6a79cc
From d5753ec513fa5a4bdcf59fa298642fd0d3a3c364 Mon Sep 17 00:00:00 2001
6a79cc
From: Yusuke Endoh <mame@ruby-lang.org>
6a79cc
Date: Fri, 12 Nov 2021 12:11:13 +0900
6a79cc
Subject: [PATCH 1/2] Add length limit option for methods that parses date
6a79cc
 strings
6a79cc
6a79cc
This patch fixes CVE-2021-41817 and created from the commit
6a79cc
<https://github.com/ruby/date/commit/4f9b8e946ba98f0a1774f8e677baa4a45637ebb3>.
6a79cc
We didn't merge the files included in the original commit below, as those are
6a79cc
for rebasing date gem version.
6a79cc
6a79cc
* ext/date/date.gemspec
6a79cc
* ext/date/lib/date.rb
6a79cc
6a79cc
== Original commit message ==
6a79cc
6a79cc
`Date.parse` now raises an ArgumentError when a given date string is
6a79cc
longer than 128. You can configure the limit by giving `limit` keyword
6a79cc
arguments like `Date.parse(str, limit: 1000)`. If you pass `limit: nil`,
6a79cc
the limit is disabled.
6a79cc
6a79cc
Not only `Date.parse` but also the following methods are changed.
6a79cc
6a79cc
* Date._parse
6a79cc
* Date.parse
6a79cc
* DateTime.parse
6a79cc
* Date._iso8601
6a79cc
* Date.iso8601
6a79cc
* DateTime.iso8601
6a79cc
* Date._rfc3339
6a79cc
* Date.rfc3339
6a79cc
* DateTime.rfc3339
6a79cc
* Date._xmlschema
6a79cc
* Date.xmlschema
6a79cc
* DateTime.xmlschema
6a79cc
* Date._rfc2822
6a79cc
* Date.rfc2822
6a79cc
* DateTime.rfc2822
6a79cc
* Date._rfc822
6a79cc
* Date.rfc822
6a79cc
* DateTime.rfc822
6a79cc
* Date._jisx0301
6a79cc
* Date.jisx0301
6a79cc
* DateTime.jisx0301
6a79cc
---
6a79cc
 ext/date/date_core.c         | 384 +++++++++++++++++++++++++++--------
6a79cc
 test/date/test_date_parse.rb |  29 +++
6a79cc
 2 files changed, 325 insertions(+), 88 deletions(-)
6a79cc
6a79cc
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
6a79cc
index c250633426..177ea0f6c5 100644
6a79cc
--- a/ext/date/date_core.c
6a79cc
+++ b/ext/date/date_core.c
6a79cc
@@ -4290,12 +4290,37 @@ date_s_strptime(int argc, VALUE *argv, VALUE klass)
6a79cc
 
6a79cc
 VALUE date__parse(VALUE str, VALUE comp);
6a79cc
 
6a79cc
+static size_t
6a79cc
+get_limit(VALUE opt)
6a79cc
+{
6a79cc
+    if (!NIL_P(opt)) {
6a79cc
+        VALUE limit = rb_hash_aref(opt, ID2SYM(rb_intern("limit")));
6a79cc
+        if (NIL_P(limit)) return SIZE_MAX;
6a79cc
+        return NUM2SIZET(limit);
6a79cc
+    }
6a79cc
+    return 128;
6a79cc
+}
6a79cc
+
6a79cc
+static void
6a79cc
+check_limit(VALUE str, VALUE opt)
6a79cc
+{
6a79cc
+    StringValue(str);
6a79cc
+    size_t slen = RSTRING_LEN(str);
6a79cc
+    size_t limit = get_limit(opt);
6a79cc
+    if (slen > limit) {
6a79cc
+	rb_raise(rb_eArgError,
6a79cc
+		 "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit);
6a79cc
+    }
6a79cc
+}
6a79cc
+
6a79cc
 static VALUE
6a79cc
 date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE vstr, vcomp, hash;
6a79cc
+    VALUE vstr, vcomp, hash, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "11", &vstr, &vcomp);
6a79cc
+    rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
+    check_limit(vstr, opt);
6a79cc
     StringValue(vstr);
6a79cc
     if (!rb_enc_str_asciicompat_p(vstr))
6a79cc
 	rb_raise(rb_eArgError,
6a79cc
@@ -4320,7 +4345,7 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date._parse(string[, comp=true])  ->  hash
6a79cc
+ *    Date._parse(string[, comp=true], limit: 128)  ->  hash
6a79cc
  *
6a79cc
  * Parses the given representation of date and time, and returns a
6a79cc
  * hash of parsed elements.  This method does not function as a
6a79cc
@@ -4331,6 +4356,10 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
6a79cc
  * it full.
6a79cc
  *
6a79cc
  *    Date._parse('2001-02-03')	#=> {:year=>2001, :mon=>2, :mday=>3}
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 date_s__parse(int argc, VALUE *argv, VALUE klass)
6a79cc
@@ -4340,7 +4369,7 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]])  ->  date
6a79cc
+ *    Date.parse(string='-4712-01-01'[, comp=true[, start=Date::ITALY]], limit: 128)  ->  date
6a79cc
  *
6a79cc
  * Parses the given representation of date and time, and creates a
6a79cc
  * date object.  This method does not function as a validator.
6a79cc
@@ -4352,13 +4381,18 @@ date_s__parse(int argc, VALUE *argv, VALUE klass)
6a79cc
  *    Date.parse('2001-02-03')		#=> #<Date: 2001-02-03 ...>
6a79cc
  *    Date.parse('20010203')		#=> #<Date: 2001-02-03 ...>
6a79cc
  *    Date.parse('3rd Feb 2001')	#=> #<Date: 2001-02-03 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 date_s_parse(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, comp, sg;
6a79cc
+    VALUE str, comp, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "03", &str, &comp, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -4370,11 +4404,12 @@ date_s_parse(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE argv2[2], hash;
6a79cc
-
6a79cc
-	argv2[0] = str;
6a79cc
-	argv2[1] = comp;
6a79cc
-	hash = date_s__parse(2, argv2, klass);
6a79cc
+        int argc2 = 2;
6a79cc
+	VALUE argv2[3];
6a79cc
+        argv2[0] = str;
6a79cc
+        argv2[1] = comp;
6a79cc
+        if (!NIL_P(opt)) argv2[argc2++] = opt;
6a79cc
+	VALUE hash = date_s__parse(argc2, argv2, klass);
6a79cc
 	return d_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
@@ -4388,19 +4423,28 @@ VALUE date__jisx0301(VALUE);
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date._iso8601(string)  ->  hash
6a79cc
+ *    Date._iso8601(string, limit: 128)  ->  hash
6a79cc
  *
6a79cc
  * Returns a hash of parsed elements.
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
-date_s__iso8601(VALUE klass, VALUE str)
6a79cc
+date_s__iso8601(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
+    VALUE str, opt;
6a79cc
+
6a79cc
+    rb_scan_args(argc, argv, "1:", &str, &opt;;
6a79cc
+    check_limit(str, opt);
6a79cc
+
6a79cc
     return date__iso8601(str);
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date.iso8601(string='-4712-01-01'[, start=Date::ITALY])  ->  date
6a79cc
+ *    Date.iso8601(string='-4712-01-01'[, start=Date::ITALY], limit: 128)  ->  date
6a79cc
  *
6a79cc
  * Creates a new Date object by parsing from a string according to
6a79cc
  * some typical ISO 8601 formats.
6a79cc
@@ -4408,13 +4452,18 @@ date_s__iso8601(VALUE klass, VALUE str)
6a79cc
  *    Date.iso8601('2001-02-03')	#=> #<Date: 2001-02-03 ...>
6a79cc
  *    Date.iso8601('20010203')		#=> #<Date: 2001-02-03 ...>
6a79cc
  *    Date.iso8601('2001-W05-6')	#=> #<Date: 2001-02-03 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 date_s_iso8601(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -4424,38 +4473,56 @@ date_s_iso8601(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__iso8601(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        if (!NIL_P(opt)) argv2[argc2++] = opt;
6a79cc
+	VALUE hash = date_s__iso8601(argc2, argv2, klass);
6a79cc
 	return d_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date._rfc3339(string)  ->  hash
6a79cc
+ *    Date._rfc3339(string, limit: 128)  ->  hash
6a79cc
  *
6a79cc
  * Returns a hash of parsed elements.
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
-date_s__rfc3339(VALUE klass, VALUE str)
6a79cc
+date_s__rfc3339(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
+    VALUE str, opt;
6a79cc
+
6a79cc
+    rb_scan_args(argc, argv, "1:", &str, &opt;;
6a79cc
+    check_limit(str, opt);
6a79cc
+
6a79cc
     return date__rfc3339(str);
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  date
6a79cc
+ *    Date.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  date
6a79cc
  *
6a79cc
  * Creates a new Date object by parsing from a string according to
6a79cc
  * some typical RFC 3339 formats.
6a79cc
  *
6a79cc
  *    Date.rfc3339('2001-02-03T04:05:06+07:00')	#=> #<Date: 2001-02-03 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -4465,38 +4532,56 @@ date_s_rfc3339(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__rfc3339(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        if (!NIL_P(opt)) argv2[argc2++] = opt;
6a79cc
+	VALUE hash = date_s__rfc3339(argc2, argv2, klass);
6a79cc
 	return d_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date._xmlschema(string)  ->  hash
6a79cc
+ *    Date._xmlschema(string, limit: 128)  ->  hash
6a79cc
  *
6a79cc
  * Returns a hash of parsed elements.
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
-date_s__xmlschema(VALUE klass, VALUE str)
6a79cc
+date_s__xmlschema(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
+    VALUE str, opt;
6a79cc
+
6a79cc
+    rb_scan_args(argc, argv, "1:", &str, &opt;;
6a79cc
+    check_limit(str, opt);
6a79cc
+
6a79cc
     return date__xmlschema(str);
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY])  ->  date
6a79cc
+ *    Date.xmlschema(string='-4712-01-01'[, start=Date::ITALY], limit: 128)  ->  date
6a79cc
  *
6a79cc
  * Creates a new Date object by parsing from a string according to
6a79cc
  * some typical XML Schema formats.
6a79cc
  *
6a79cc
  *    Date.xmlschema('2001-02-03')	#=> #<Date: 2001-02-03 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -4506,41 +4591,58 @@ date_s_xmlschema(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__xmlschema(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        if (!NIL_P(opt)) argv2[argc2++] = opt;
6a79cc
+	VALUE hash = date_s__xmlschema(argc2, argv2, klass);
6a79cc
 	return d_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date._rfc2822(string)  ->  hash
6a79cc
- *    Date._rfc822(string)   ->  hash
6a79cc
+ *    Date._rfc2822(string, limit: 128)  ->  hash
6a79cc
+ *    Date._rfc822(string, limit: 128)   ->  hash
6a79cc
  *
6a79cc
  * Returns a hash of parsed elements.
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
-date_s__rfc2822(VALUE klass, VALUE str)
6a79cc
+date_s__rfc2822(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
+    VALUE str, opt;
6a79cc
+
6a79cc
+    rb_scan_args(argc, argv, "1:", &str, &opt;;
6a79cc
+    check_limit(str, opt);
6a79cc
+
6a79cc
     return date__rfc2822(str);
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY])  ->  date
6a79cc
- *    Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY])   ->  date
6a79cc
+ *    Date.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128)  ->  date
6a79cc
+ *    Date.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128)   ->  date
6a79cc
  *
6a79cc
  * Creates a new Date object by parsing from a string according to
6a79cc
  * some typical RFC 2822 formats.
6a79cc
  *
6a79cc
  *    Date.rfc2822('Sat, 3 Feb 2001 00:00:00 +0000')
6a79cc
  *						#=> #<Date: 2001-02-03 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -4550,39 +4652,56 @@ date_s_rfc2822(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__rfc2822(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        if (!NIL_P(opt)) argv2[argc2++] = opt;
6a79cc
+	VALUE hash = date_s__rfc2822(argc2, argv2, klass);
6a79cc
 	return d_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date._httpdate(string)  ->  hash
6a79cc
+ *    Date._httpdate(string, limit: 128)  ->  hash
6a79cc
  *
6a79cc
  * Returns a hash of parsed elements.
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
-date_s__httpdate(VALUE klass, VALUE str)
6a79cc
+date_s__httpdate(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
+    VALUE str, opt;
6a79cc
+
6a79cc
+    rb_scan_args(argc, argv, "1:", &str, &opt;;
6a79cc
+    check_limit(str, opt);
6a79cc
+
6a79cc
     return date__httpdate(str);
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY])  ->  date
6a79cc
+ *    Date.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY], limit: 128)  ->  date
6a79cc
  *
6a79cc
  * Creates a new Date object by parsing from a string according to
6a79cc
  * some RFC 2616 format.
6a79cc
  *
6a79cc
  *    Date.httpdate('Sat, 03 Feb 2001 00:00:00 GMT')
6a79cc
  *						#=> #<Date: 2001-02-03 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 date_s_httpdate(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -4592,38 +4711,56 @@ date_s_httpdate(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__httpdate(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        if (!NIL_P(opt)) argv2[argc2++] = opt;
6a79cc
+	VALUE hash = date_s__httpdate(argc2, argv2, klass);
6a79cc
 	return d_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date._jisx0301(string)  ->  hash
6a79cc
+ *    Date._jisx0301(string, limit: 128)  ->  hash
6a79cc
  *
6a79cc
  * Returns a hash of parsed elements.
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
-date_s__jisx0301(VALUE klass, VALUE str)
6a79cc
+date_s__jisx0301(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
+    VALUE str, opt;
6a79cc
+
6a79cc
+    rb_scan_args(argc, argv, "1:", &str, &opt;;
6a79cc
+    check_limit(str, opt);
6a79cc
+
6a79cc
     return date__jisx0301(str);
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY])  ->  date
6a79cc
+ *    Date.jisx0301(string='-4712-01-01'[, start=Date::ITALY], limit: 128)  ->  date
6a79cc
  *
6a79cc
  * Creates a new Date object by parsing from a string according to
6a79cc
  * some typical JIS X 0301 formats.
6a79cc
  *
6a79cc
  *    Date.jisx0301('H13.02.03')		#=> #<Date: 2001-02-03 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -4633,7 +4770,11 @@ date_s_jisx0301(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__jisx0301(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        if (!NIL_P(opt)) argv2[argc2++] = opt;
6a79cc
+	VALUE hash = date_s__jisx0301(argc2, argv2, klass);
6a79cc
 	return d_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
@@ -7925,7 +8066,7 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]])  ->  datetime
6a79cc
+ *    DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128)  ->  datetime
6a79cc
  *
6a79cc
  * Parses the given representation of date and time, and creates a
6a79cc
  * DateTime object.  This method does not function as a validator.
6a79cc
@@ -7939,13 +8080,18 @@ datetime_s_strptime(int argc, VALUE *argv, VALUE klass)
6a79cc
  *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
6a79cc
  *    DateTime.parse('3rd Feb 2001 04:05:06 PM')
6a79cc
  *				#=> #<DateTime: 2001-02-03T16:05:06+00:00 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 datetime_s_parse(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, comp, sg;
6a79cc
+    VALUE str, comp, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "03", &str, &comp, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -7957,18 +8103,20 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE argv2[2], hash;
6a79cc
-
6a79cc
-	argv2[0] = str;
6a79cc
-	argv2[1] = comp;
6a79cc
-	hash = date_s__parse(2, argv2, klass);
6a79cc
+        int argc2 = 2;
6a79cc
+        VALUE argv2[3];
6a79cc
+        argv2[0] = str;
6a79cc
+        argv2[1] = comp;
6a79cc
+        argv2[2] = opt;
6a79cc
+        if (!NIL_P(opt)) argc2++;
6a79cc
+	VALUE hash = date_s__parse(argc2, argv2, klass);
6a79cc
 	return dt_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  datetime
6a79cc
+ *    DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  datetime
6a79cc
  *
6a79cc
  * Creates a new DateTime object by parsing from a string according to
6a79cc
  * some typical ISO 8601 formats.
6a79cc
@@ -7979,13 +8127,18 @@ datetime_s_parse(int argc, VALUE *argv, VALUE klass)
6a79cc
  *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
6a79cc
  *    DateTime.iso8601('2001-W05-6T04:05:06+07:00')
6a79cc
  *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -7995,27 +8148,37 @@ datetime_s_iso8601(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__iso8601(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        argv2[1] = opt;
6a79cc
+        if (!NIL_P(opt)) argc2--;
6a79cc
+	VALUE hash = date_s__iso8601(argc2, argv2, klass);
6a79cc
 	return dt_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  datetime
6a79cc
+ *    DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  datetime
6a79cc
  *
6a79cc
  * Creates a new DateTime object by parsing from a string according to
6a79cc
  * some typical RFC 3339 formats.
6a79cc
  *
6a79cc
  *    DateTime.rfc3339('2001-02-03T04:05:06+07:00')
6a79cc
  *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -8025,27 +8188,37 @@ datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__rfc3339(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        argv2[1] = opt;
6a79cc
+        if (!NIL_P(opt)) argc2++;
6a79cc
+	VALUE hash = date_s__rfc3339(argc2, argv2, klass);
6a79cc
 	return dt_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  datetime
6a79cc
+ *    DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  datetime
6a79cc
  *
6a79cc
  * Creates a new DateTime object by parsing from a string according to
6a79cc
  * some typical XML Schema formats.
6a79cc
  *
6a79cc
  *    DateTime.xmlschema('2001-02-03T04:05:06+07:00')
6a79cc
  *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -8055,28 +8228,38 @@ datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__xmlschema(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        argv2[1] = opt;
6a79cc
+        if (!NIL_P(opt)) argc2++;
6a79cc
+	VALUE hash = date_s__xmlschema(argc2, argv2, klass);
6a79cc
 	return dt_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY])  ->  datetime
6a79cc
- *    DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY])   ->  datetime
6a79cc
+ *    DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128)  ->  datetime
6a79cc
+ *    DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128)   ->  datetime
6a79cc
  *
6a79cc
  * Creates a new DateTime object by parsing from a string according to
6a79cc
  * some typical RFC 2822 formats.
6a79cc
  *
6a79cc
  *     DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700')
6a79cc
  *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -8086,7 +8269,12 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__rfc2822(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        argv2[1] = opt;
6a79cc
+        if (!NIL_P(opt)) argc2++;
6a79cc
+	VALUE hash = date_s__rfc2822(argc2, argv2, klass);
6a79cc
 	return dt_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
@@ -8100,13 +8288,18 @@ datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass)
6a79cc
  *
6a79cc
  *    DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT')
6a79cc
  *				#=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -8116,27 +8309,37 @@ datetime_s_httpdate(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__httpdate(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        argv2[1] = opt;
6a79cc
+        if (!NIL_P(opt)) argc2++;
6a79cc
+	VALUE hash = date_s__httpdate(argc2, argv2, klass);
6a79cc
 	return dt_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
 
6a79cc
 /*
6a79cc
  * call-seq:
6a79cc
- *    DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY])  ->  datetime
6a79cc
+ *    DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128)  ->  datetime
6a79cc
  *
6a79cc
  * Creates a new DateTime object by parsing from a string according to
6a79cc
  * some typical JIS X 0301 formats.
6a79cc
  *
6a79cc
  *    DateTime.jisx0301('H13.02.03T04:05:06+07:00')
6a79cc
  *				#=> #<DateTime: 2001-02-03T04:05:06+07:00 ...>
6a79cc
+ *
6a79cc
+ * Raise an ArgumentError when the string length is longer than _limit_.
6a79cc
+ * You can stop this check by passing `limit: nil`, but note that
6a79cc
+ * it may take a long time to parse.
6a79cc
  */
6a79cc
 static VALUE
6a79cc
 datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
6a79cc
 {
6a79cc
-    VALUE str, sg;
6a79cc
+    VALUE str, sg, opt;
6a79cc
 
6a79cc
-    rb_scan_args(argc, argv, "02", &str, &sg;;
6a79cc
+    rb_scan_args(argc, argv, "02:", &str, &sg, &opt;;
6a79cc
+    if (!NIL_P(opt)) argc--;
6a79cc
 
6a79cc
     switch (argc) {
6a79cc
       case 0:
6a79cc
@@ -8146,7 +8349,12 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
6a79cc
     }
6a79cc
 
6a79cc
     {
6a79cc
-	VALUE hash = date_s__jisx0301(klass, str);
6a79cc
+        int argc2 = 1;
6a79cc
+        VALUE argv2[2];
6a79cc
+        argv2[0] = str;
6a79cc
+        argv2[1] = opt;
6a79cc
+        if (!NIL_P(opt)) argc2++;
6a79cc
+	VALUE hash = date_s__jisx0301(argc2, argv2, klass);
6a79cc
 	return dt_new_by_frags(klass, hash, sg);
6a79cc
     }
6a79cc
 }
6a79cc
@@ -9297,19 +9505,19 @@ Init_date_core(void)
6a79cc
     rb_define_singleton_method(cDate, "strptime", date_s_strptime, -1);
6a79cc
     rb_define_singleton_method(cDate, "_parse", date_s__parse, -1);
6a79cc
     rb_define_singleton_method(cDate, "parse", date_s_parse, -1);
6a79cc
-    rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, 1);
6a79cc
+    rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, -1);
6a79cc
     rb_define_singleton_method(cDate, "iso8601", date_s_iso8601, -1);
6a79cc
-    rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, 1);
6a79cc
+    rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, -1);
6a79cc
     rb_define_singleton_method(cDate, "rfc3339", date_s_rfc3339, -1);
6a79cc
-    rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, 1);
6a79cc
+    rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, -1);
6a79cc
     rb_define_singleton_method(cDate, "xmlschema", date_s_xmlschema, -1);
6a79cc
-    rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, 1);
6a79cc
-    rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, 1);
6a79cc
+    rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, -1);
6a79cc
+    rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, -1);
6a79cc
     rb_define_singleton_method(cDate, "rfc2822", date_s_rfc2822, -1);
6a79cc
     rb_define_singleton_method(cDate, "rfc822", date_s_rfc2822, -1);
6a79cc
-    rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, 1);
6a79cc
+    rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, -1);
6a79cc
     rb_define_singleton_method(cDate, "httpdate", date_s_httpdate, -1);
6a79cc
-    rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, 1);
6a79cc
+    rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, -1);
6a79cc
     rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1);
6a79cc
 
6a79cc
 #ifndef NDEBUG
6a79cc
diff --git a/test/date/test_date_parse.rb b/test/date/test_date_parse.rb
6a79cc
index ac0eb85ca7..f9b160ee8c 100644
6a79cc
--- a/test/date/test_date_parse.rb
6a79cc
+++ b/test/date/test_date_parse.rb
6a79cc
@@ -1,6 +1,7 @@
6a79cc
 # frozen_string_literal: true
6a79cc
 require 'test/unit'
6a79cc
 require 'date'
6a79cc
+require 'timeout'
6a79cc
 
6a79cc
 class TestDateParse < Test::Unit::TestCase
6a79cc
 
6a79cc
@@ -1122,4 +1123,32 @@ def test_given_string
6a79cc
     assert_equal(s0, s)
6a79cc
   end
6a79cc
 
6a79cc
+  def test_length_limit
6a79cc
+    assert_raise(ArgumentError) { Date._parse("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date._iso8601("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date._rfc3339("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date._xmlschema("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date._rfc2822("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date._rfc822("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date._jisx0301("1" * 1000) }
6a79cc
+
6a79cc
+    assert_raise(ArgumentError) { Date.parse("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date.iso8601("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date.rfc3339("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date.xmlschema("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date.rfc2822("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date.rfc822("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { Date.jisx0301("1" * 1000) }
6a79cc
+
6a79cc
+    assert_raise(ArgumentError) { DateTime.parse("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { DateTime.iso8601("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { DateTime.rfc3339("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { DateTime.xmlschema("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { DateTime.rfc2822("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { DateTime.rfc822("1" * 1000) }
6a79cc
+    assert_raise(ArgumentError) { DateTime.jisx0301("1" * 1000) }
6a79cc
+
6a79cc
+    assert_raise(ArgumentError) { Date._parse("Jan " + "9" * 1000000) }
6a79cc
+    assert_raise(Timeout::Error) { Timeout.timeout(1) { Date._parse("Jan " + "9" * 1000000, limit: nil) } }
6a79cc
+  end
6a79cc
 end
6a79cc
-- 
6a79cc
2.36.1
6a79cc