ruby-changes:69895
From: usa <ko1@a...>
Date: Wed, 24 Nov 2021 18:08:01 +0900 (JST)
Subject: [ruby-changes:69895] 1fbf663b00 (ruby_2_6): Merge date-2.0.2
https://git.ruby-lang.org/ruby.git/commit/?id=1fbf663b00 From 1fbf663b00bf1bdde4ebbbf0875dd7d37b0d90c6 Mon Sep 17 00:00:00 2001 From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> Date: Wed, 24 Nov 2021 09:07:47 +0000 Subject: Merge date-2.0.2 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67952 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/date/date.gemspec | 7 +- ext/date/date_core.c | 411 ++++++++++++++++++++++++++++++---------- ext/date/date_parse.c | 51 ++--- ext/date/date_strptime.c | 6 +- ext/date/lib/date.rb | 1 + test/date/test_date_parse.rb | 164 +++++++--------- test/date/test_date_strftime.rb | 7 +- version.h | 10 +- 8 files changed, 426 insertions(+), 231 deletions(-) diff --git a/ext/date/date.gemspec b/ext/date/date.gemspec index ddb9608f4e4..b30a0557460 100644 --- a/ext/date/date.gemspec +++ b/ext/date/date.gemspec @@ -1,7 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ext/date/date.gemspec#L1 # 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 67ed6171a78..918e61234c6 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -3692,7 +3692,7 @@ rt_rewrite_frags(VALUE hash) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L3692 { 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L3717 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4292 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4335 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4361 * 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4374 /* * 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4386 * 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4409 } { - 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); https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4428 /* * 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4457 * 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) https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L4478 } { - 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, (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/