Compare commits
10 Commits
21c99c7ebb
...
306ae88e6c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
306ae88e6c | ||
|
|
5cf8152653 | ||
|
|
003690f1a9 | ||
|
|
0bbee328ec | ||
|
|
198ccb365e | ||
|
|
6bad86a0b4 | ||
|
|
7fbb4c1d7c | ||
|
|
92299a72a1 | ||
|
|
34cc0f9669 | ||
|
|
86a915ec19 |
911
backport-0001-CVE-2021-41817.patch
Normal file
911
backport-0001-CVE-2021-41817.patch
Normal file
@ -0,0 +1,911 @@
|
|||||||
|
From 489c8cebf575741d62effd0d212f1319beff3c40 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yusuke Endoh <mame@ruby-lang.org>
|
||||||
|
Date: Fri, 12 Nov 2021 12:15:25 +0900
|
||||||
|
Subject: [PATCH] [ruby/date] Add length limit option for methods that parses
|
||||||
|
date strings
|
||||||
|
|
||||||
|
`Date.parse` now raises an ArgumentError when a given date string is
|
||||||
|
longer than 128. You can configure the limit by giving `limit` keyword
|
||||||
|
arguments like `Date.parse(str, limit:1000)`. If you pass `limit:nil`,
|
||||||
|
the limit is disabled.
|
||||||
|
|
||||||
|
Not only `Date.parse` but also the following methods are changed.
|
||||||
|
|
||||||
|
* Date._parse
|
||||||
|
* Date.parse
|
||||||
|
* DateTime.parse
|
||||||
|
* Date._iso8601
|
||||||
|
* Date.iso8601
|
||||||
|
* DateTime.iso8601
|
||||||
|
* Date._rfc3339
|
||||||
|
* Date.rfc3339
|
||||||
|
* DateTime.rfc3339
|
||||||
|
* Date._xmlschema
|
||||||
|
* Date.xmlschema
|
||||||
|
* DateTime.xmlschema
|
||||||
|
* Date._rfc2822
|
||||||
|
* Date.rfc2822
|
||||||
|
* DateTime.rfc2822
|
||||||
|
* Date._rfc822
|
||||||
|
* Date.rfc822
|
||||||
|
* DateTime.rfc822
|
||||||
|
* Date._jisx0301
|
||||||
|
* Date.jisx0301
|
||||||
|
* DateTime.jisx0301
|
||||||
|
|
||||||
|
https://github.com/ruby/date/commit/3959accef8
|
||||||
|
---
|
||||||
|
ext/date/date_core.c | 384 +++++++++++++++++++++++++++--------
|
||||||
|
test/date/test_date_parse.rb | 29 +++
|
||||||
|
2 files changed, 325 insertions(+), 88 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
|
||||||
|
index c250633..177ea0f 100644
|
||||||
|
--- a/ext/date/date_core.c
|
||||||
|
+++ b/ext/date/date_core.c
|
||||||
|
@@ -4290,12 +4290,37 @@ 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)
|
||||||
|
+{
|
||||||
|
+ 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,
|
||||||
|
@@ -4320,7 +4345,7 @@ date_s__parse_internal(int argc, VALUE *argv, VALUE klass)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
@@ -4331,6 +4356,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 , but note that
|
||||||
|
+ * it may take a long time to parse.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
date_s__parse(int argc, VALUE *argv, VALUE klass)
|
||||||
|
@@ -4340,7 +4369,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.
|
||||||
|
@@ -4352,13 +4381,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 , 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:
|
||||||
|
@@ -4370,11 +4404,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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -4388,19 +4423,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 , 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.
|
||||||
|
@@ -4408,13 +4452,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 , 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:
|
||||||
|
@@ -4424,38 +4473,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 , 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 , 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:
|
||||||
|
@@ -4465,38 +4532,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 , 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 , 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:
|
||||||
|
@@ -4506,41 +4591,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 , 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 , 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:
|
||||||
|
@@ -4550,39 +4652,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 , 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 , 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:
|
||||||
|
@@ -4592,38 +4711,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 , 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 ...>
|
||||||
|
+ *
|
||||||
|
+ * Raise an ArgumentError when the string length is longer than _limit_.
|
||||||
|
+ * You can stop this check by passing , 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:
|
||||||
|
@@ -4633,7 +4770,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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -7925,7 +8066,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.
|
||||||
|
@@ -7939,13 +8080,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 , 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:
|
||||||
|
@@ -7957,18 +8103,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.
|
||||||
|
@@ -7979,13 +8127,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 , 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:
|
||||||
|
@@ -7995,27 +8148,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 , 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:
|
||||||
|
@@ -8025,27 +8188,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 , 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:
|
||||||
|
@@ -8055,28 +8228,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 , 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:
|
||||||
|
@@ -8086,7 +8269,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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -8100,13 +8288,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 , 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:
|
||||||
|
@@ -8116,27 +8309,37 @@ 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.
|
||||||
|
*
|
||||||
|
* DateTime.jisx0301('H13.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 , 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:
|
||||||
|
@@ -8146,7 +8349,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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -9297,19 +9505,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);
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
diff --git a/test/date/test_date_parse.rb b/test/date/test_date_parse.rb
|
||||||
|
index ac0eb85..f9b160e 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
|
||||||
|
|
||||||
|
@@ -1122,4 +1123,32 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
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
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
101
backport-0002-CVE-2021-41817.patch
Normal file
101
backport-0002-CVE-2021-41817.patch
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
From fa674cf7230e40bc96625ee97a6057e48bb20f0f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jean Boussier <jean.boussier@gmail.com>
|
||||||
|
Date: Mon, 15 Nov 2021 11:37:40 +0100
|
||||||
|
Subject: [PATCH] [ruby/date] `Date._<format>(nil)` should return an empty Hash
|
||||||
|
|
||||||
|
Fix: https://github.com/ruby/date/issues/39
|
||||||
|
|
||||||
|
This is how versions previous to 3.2.1 behaved and Active Support
|
||||||
|
currently rely on this behavior.
|
||||||
|
|
||||||
|
https://github.com/rails/rails/blob/90357af08048ef5076730505f6e7b14a81f33d0c/activesupport/lib/active_support/values/time_zone.rb#L383-L384
|
||||||
|
|
||||||
|
Any Rails application upgrading to date `3.2.1` might run into unexpected errors.
|
||||||
|
|
||||||
|
https://github.com/ruby/date/commit/8f2d7a0c7e
|
||||||
|
---
|
||||||
|
ext/date/date_core.c | 2 ++
|
||||||
|
test/date/test_date_parse.rb | 18 ++++++++++++++++++
|
||||||
|
2 files changed, 20 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
|
||||||
|
index 177ea0f..516640b 100644
|
||||||
|
--- a/ext/date/date_core.c
|
||||||
|
+++ b/ext/date/date_core.c
|
||||||
|
@@ -4304,6 +4304,8 @@ get_limit(VALUE opt)
|
||||||
|
static void
|
||||||
|
check_limit(VALUE str, VALUE opt)
|
||||||
|
{
|
||||||
|
+ if (NIL_P(str)) return;
|
||||||
|
+
|
||||||
|
StringValue(str);
|
||||||
|
size_t slen = RSTRING_LEN(str);
|
||||||
|
size_t limit = get_limit(opt);
|
||||||
|
diff --git a/test/date/test_date_parse.rb b/test/date/test_date_parse.rb
|
||||||
|
index f9b160e..dfc018b 100644
|
||||||
|
--- a/test/date/test_date_parse.rb
|
||||||
|
+++ b/test/date/test_date_parse.rb
|
||||||
|
@@ -824,6 +824,9 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
h = Date._iso8601('')
|
||||||
|
assert_equal({}, h)
|
||||||
|
+
|
||||||
|
+ h = Date._iso8601(nil)
|
||||||
|
+ assert_equal({}, h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test__rfc3339
|
||||||
|
@@ -839,6 +842,9 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
h = Date._rfc3339('')
|
||||||
|
assert_equal({}, h)
|
||||||
|
+
|
||||||
|
+ h = Date._rfc3339(nil)
|
||||||
|
+ assert_equal({}, h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test__xmlschema
|
||||||
|
@@ -921,6 +927,9 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
h = Date._xmlschema('')
|
||||||
|
assert_equal({}, h)
|
||||||
|
+
|
||||||
|
+ h = Date._xmlschema(nil)
|
||||||
|
+ assert_equal({}, h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test__rfc2822
|
||||||
|
@@ -953,6 +962,9 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
h = Date._rfc2822('')
|
||||||
|
assert_equal({}, h)
|
||||||
|
+
|
||||||
|
+ h = Date._rfc2822(nil)
|
||||||
|
+ assert_equal({}, h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test__httpdate
|
||||||
|
@@ -973,6 +985,9 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
h = Date._httpdate('')
|
||||||
|
assert_equal({}, h)
|
||||||
|
+
|
||||||
|
+ h = Date._httpdate(nil)
|
||||||
|
+ assert_equal({}, h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test__jisx0301
|
||||||
|
@@ -1001,6 +1016,9 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
h = Date._jisx0301('')
|
||||||
|
assert_equal({}, h)
|
||||||
|
+
|
||||||
|
+ h = Date._jisx0301(nil)
|
||||||
|
+ assert_equal({}, h)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
97
backport-0003-CVE-2021-41817.patch
Normal file
97
backport-0003-CVE-2021-41817.patch
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
From a87c56f820dac90d50544ad33cc546daa9f29a9a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jean Boussier <jean.boussier@gmail.com>
|
||||||
|
Date: Tue, 16 Nov 2021 14:03:42 +0100
|
||||||
|
Subject: [PATCH] [ruby/date] check_limit: also handle symbols
|
||||||
|
|
||||||
|
https://github.com/ruby/date/commit/376c65942b
|
||||||
|
---
|
||||||
|
ext/date/date_core.c | 1 +
|
||||||
|
test/date/test_date_parse.rb | 24 ++++++++++++++++++++++++
|
||||||
|
2 files changed, 25 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
|
||||||
|
index 516640b..0a9468a 100644
|
||||||
|
--- a/ext/date/date_core.c
|
||||||
|
+++ b/ext/date/date_core.c
|
||||||
|
@@ -4305,6 +4305,7 @@ 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);
|
||||||
|
diff --git a/test/date/test_date_parse.rb b/test/date/test_date_parse.rb
|
||||||
|
index dfc018b..5bc2ceb 100644
|
||||||
|
--- a/test/date/test_date_parse.rb
|
||||||
|
+++ b/test/date/test_date_parse.rb
|
||||||
|
@@ -827,6 +827,10 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -845,6 +849,10 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -930,6 +938,10 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -965,6 +977,10 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -988,6 +1004,10 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
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
|
||||||
|
@@ -1019,6 +1039,10 @@ class TestDateParse < Test::Unit::TestCase
|
||||||
|
|
||||||
|
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
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,372 @@
|
|||||||
|
From e4a067e11235a2ec7a00616d41350485e384ec05 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sutou Kouhei <kou@clear-code.com>
|
||||||
|
Date: Thu, 1 Aug 2024 11:51:33 +0900
|
||||||
|
Subject: [PATCH] Add 3.3.3 entry
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/rexml/formatters/pretty.rb | 2 +-
|
||||||
|
lib/rexml/parsers/baseparser.rb | 67 ++++++++++++++-----
|
||||||
|
lib/rexml/parsers/sax2parser.rb | 21 +-----
|
||||||
|
lib/rexml/parsers/streamparser.rb | 4 +-
|
||||||
|
lib/rexml/rexml.rb | 2 +-
|
||||||
|
lib/rexml/source.rb | 22 ++++--
|
||||||
|
lib/rexml/text.rb | 48 +++++++++----
|
||||||
|
7 files changed, 105 insertions(+), 61 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rexml/formatters/pretty.rb b/lib/rexml/formatters/pretty.rb
|
||||||
|
index a1198b7..a838d83 100644
|
||||||
|
--- a/lib/rexml/formatters/pretty.rb
|
||||||
|
+++ b/lib/rexml/formatters/pretty.rb
|
||||||
|
@@ -111,7 +111,7 @@ module REXML
|
||||||
|
# itself, then we don't need a carriage return... which makes this
|
||||||
|
# logic more complex.
|
||||||
|
node.children.each { |child|
|
||||||
|
- next if child == node.children[-1] and child.instance_of?(Text)
|
||||||
|
+ next if child.instance_of?(Text)
|
||||||
|
unless child == node.children[0] or child.instance_of?(Text) or
|
||||||
|
(child == node.children[1] and !node.children[0].writethis)
|
||||||
|
output << "\n"
|
||||||
|
diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
|
||||||
|
index 617a3d5..44dc658 100644
|
||||||
|
--- a/lib/rexml/parsers/baseparser.rb
|
||||||
|
+++ b/lib/rexml/parsers/baseparser.rb
|
||||||
|
@@ -124,11 +124,10 @@ module REXML
|
||||||
|
}
|
||||||
|
|
||||||
|
module Private
|
||||||
|
- INSTRUCTION_END = /#{NAME}(\s+.*?)?\?>/um
|
||||||
|
TAG_PATTERN = /((?>#{QNAME_STR}))\s*/um
|
||||||
|
CLOSE_PATTERN = /(#{QNAME_STR})\s*>/um
|
||||||
|
ATTLISTDECL_END = /\s+#{NAME}(?:#{ATTDEF})*\s*>/um
|
||||||
|
- NAME_PATTERN = /\s*#{NAME}/um
|
||||||
|
+ NAME_PATTERN = /#{NAME}/um
|
||||||
|
GEDECL_PATTERN = "\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
|
||||||
|
PEDECL_PATTERN = "\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
|
||||||
|
ENTITYDECL_PATTERN = /(?:#{GEDECL_PATTERN})|(?:#{PEDECL_PATTERN})/um
|
||||||
|
@@ -159,6 +158,7 @@ module REXML
|
||||||
|
def stream=( source )
|
||||||
|
@source = SourceFactory.create_from( source )
|
||||||
|
@closed = nil
|
||||||
|
+ @have_root = false
|
||||||
|
@document_status = nil
|
||||||
|
@tags = []
|
||||||
|
@stack = []
|
||||||
|
@@ -241,7 +241,7 @@ module REXML
|
||||||
|
if @document_status == nil
|
||||||
|
start_position = @source.position
|
||||||
|
if @source.match("<?", true)
|
||||||
|
- return process_instruction(start_position)
|
||||||
|
+ return process_instruction
|
||||||
|
elsif @source.match("<!", true)
|
||||||
|
if @source.match("--", true)
|
||||||
|
md = @source.match(/(.*?)-->/um, true)
|
||||||
|
@@ -311,7 +311,11 @@ module REXML
|
||||||
|
raise REXML::ParseException.new( "Bad ELEMENT declaration!", @source ) if md.nil?
|
||||||
|
return [ :elementdecl, "<!ELEMENT" + md[1] ]
|
||||||
|
elsif @source.match("ENTITY", true)
|
||||||
|
- match = [:entitydecl, *@source.match(Private::ENTITYDECL_PATTERN, true).captures.compact]
|
||||||
|
+ match_data = @source.match(Private::ENTITYDECL_PATTERN, true)
|
||||||
|
+ unless match_data
|
||||||
|
+ raise REXML::ParseException.new("Malformed entity declaration", @source)
|
||||||
|
+ end
|
||||||
|
+ match = [:entitydecl, *match_data.captures.compact]
|
||||||
|
ref = false
|
||||||
|
if match[1] == '%'
|
||||||
|
ref = true
|
||||||
|
@@ -343,7 +347,7 @@ module REXML
|
||||||
|
contents = md[0]
|
||||||
|
|
||||||
|
pairs = {}
|
||||||
|
- values = md[0].scan( ATTDEF_RE )
|
||||||
|
+ values = md[0].strip.scan( ATTDEF_RE )
|
||||||
|
values.each do |attdef|
|
||||||
|
unless attdef[3] == "#IMPLIED"
|
||||||
|
attdef.compact!
|
||||||
|
@@ -437,7 +441,7 @@ module REXML
|
||||||
|
raise REXML::ParseException.new( "Declarations can only occur "+
|
||||||
|
"in the doctype declaration.", @source)
|
||||||
|
elsif @source.match("?", true)
|
||||||
|
- return process_instruction(start_position)
|
||||||
|
+ return process_instruction
|
||||||
|
else
|
||||||
|
# Get the next tag
|
||||||
|
md = @source.match(Private::TAG_PATTERN, true)
|
||||||
|
@@ -462,8 +466,12 @@ module REXML
|
||||||
|
@closed = tag
|
||||||
|
@nsstack.shift
|
||||||
|
else
|
||||||
|
+ if @tags.empty? and @have_root
|
||||||
|
+ raise ParseException.new("Malformed XML: Extra tag at the end of the document (got '<#{tag}')", @source)
|
||||||
|
+ end
|
||||||
|
@tags.push( tag )
|
||||||
|
end
|
||||||
|
+ @have_root = true
|
||||||
|
return [ :start_element, tag, attributes ]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
@@ -471,6 +479,16 @@ module REXML
|
||||||
|
if text.chomp!("<")
|
||||||
|
@source.position -= "<".bytesize
|
||||||
|
end
|
||||||
|
+ if @tags.empty?
|
||||||
|
+ unless /\A\s*\z/.match?(text)
|
||||||
|
+ if @have_root
|
||||||
|
+ raise ParseException.new("Malformed XML: Extra content at the end of the document (got '#{text}')", @source)
|
||||||
|
+ else
|
||||||
|
+ raise ParseException.new("Malformed XML: Content at the start of the document (got '#{text}')", @source)
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ return pull_event if @have_root
|
||||||
|
+ end
|
||||||
|
return [ :text, text ]
|
||||||
|
end
|
||||||
|
rescue REXML::UndefinedNamespaceException
|
||||||
|
@@ -515,7 +533,11 @@ module REXML
|
||||||
|
|
||||||
|
# Unescapes all possible entities
|
||||||
|
def unnormalize( string, entities=nil, filter=nil )
|
||||||
|
- rv = string.gsub( Private::CARRIAGE_RETURN_NEWLINE_PATTERN, "\n" )
|
||||||
|
+ if string.include?("\r")
|
||||||
|
+ rv = string.gsub( Private::CARRIAGE_RETURN_NEWLINE_PATTERN, "\n" )
|
||||||
|
+ else
|
||||||
|
+ rv = string.dup
|
||||||
|
+ end
|
||||||
|
matches = rv.scan( REFERENCE_RE )
|
||||||
|
return rv if matches.size == 0
|
||||||
|
rv.gsub!( Private::CHARACTER_REFERENCES ) {
|
||||||
|
@@ -565,14 +587,14 @@ module REXML
|
||||||
|
def parse_name(base_error_message)
|
||||||
|
md = @source.match(Private::NAME_PATTERN, true)
|
||||||
|
unless md
|
||||||
|
- if @source.match(/\s*\S/um)
|
||||||
|
+ if @source.match(/\S/um)
|
||||||
|
message = "#{base_error_message}: invalid name"
|
||||||
|
else
|
||||||
|
message = "#{base_error_message}: name is missing"
|
||||||
|
end
|
||||||
|
raise REXML::ParseException.new(message, @source)
|
||||||
|
end
|
||||||
|
- md[1]
|
||||||
|
+ md[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_id(base_error_message,
|
||||||
|
@@ -641,15 +663,24 @@ module REXML
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
- def process_instruction(start_position)
|
||||||
|
- match_data = @source.match(Private::INSTRUCTION_END, true)
|
||||||
|
- unless match_data
|
||||||
|
- message = "Invalid processing instruction node"
|
||||||
|
- @source.position = start_position
|
||||||
|
- raise REXML::ParseException.new(message, @source)
|
||||||
|
+ def process_instruction
|
||||||
|
+ name = parse_name("Malformed XML: Invalid processing instruction node")
|
||||||
|
+ if @source.match(/\s+/um, true)
|
||||||
|
+ match_data = @source.match(/(.*?)\?>/um, true)
|
||||||
|
+ unless match_data
|
||||||
|
+ raise ParseException.new("Malformed XML: Unclosed processing instruction", @source)
|
||||||
|
+ end
|
||||||
|
+ content = match_data[1]
|
||||||
|
+ else
|
||||||
|
+ content = nil
|
||||||
|
+ unless @source.match("?>", true)
|
||||||
|
+ raise ParseException.new("Malformed XML: Unclosed processing instruction", @source)
|
||||||
|
+ end
|
||||||
|
end
|
||||||
|
- if @document_status.nil? and match_data[1] == "xml"
|
||||||
|
- content = match_data[2]
|
||||||
|
+ if name == "xml"
|
||||||
|
+ if @document_status
|
||||||
|
+ raise ParseException.new("Malformed XML: XML declaration is not at the start", @source)
|
||||||
|
+ end
|
||||||
|
version = VERSION.match(content)
|
||||||
|
version = version[1] unless version.nil?
|
||||||
|
encoding = ENCODING.match(content)
|
||||||
|
@@ -664,7 +695,7 @@ module REXML
|
||||||
|
standalone = standalone[1] unless standalone.nil?
|
||||||
|
return [ :xmldecl, version, encoding, standalone ]
|
||||||
|
end
|
||||||
|
- [:processing_instruction, match_data[1], match_data[2]]
|
||||||
|
+ [:processing_instruction, name, content]
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_attributes(prefixes, curr_ns)
|
||||||
|
diff --git a/lib/rexml/parsers/sax2parser.rb b/lib/rexml/parsers/sax2parser.rb
|
||||||
|
index 01cb469..cec9d2f 100644
|
||||||
|
--- a/lib/rexml/parsers/sax2parser.rb
|
||||||
|
+++ b/lib/rexml/parsers/sax2parser.rb
|
||||||
|
@@ -161,25 +161,8 @@ module REXML
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when :text
|
||||||
|
- #normalized = @parser.normalize( event[1] )
|
||||||
|
- #handle( :characters, normalized )
|
||||||
|
- copy = event[1].clone
|
||||||
|
-
|
||||||
|
- esub = proc { |match|
|
||||||
|
- if @entities.has_key?($1)
|
||||||
|
- @entities[$1].gsub(Text::REFERENCE, &esub)
|
||||||
|
- else
|
||||||
|
- match
|
||||||
|
- end
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- copy.gsub!( Text::REFERENCE, &esub )
|
||||||
|
- copy.gsub!( Text::NUMERICENTITY ) {|m|
|
||||||
|
- m=$1
|
||||||
|
- m = "0#{m}" if m[0] == ?x
|
||||||
|
- [Integer(m)].pack('U*')
|
||||||
|
- }
|
||||||
|
- handle( :characters, copy )
|
||||||
|
+ unnormalized = @parser.unnormalize( event[1], @entities )
|
||||||
|
+ handle( :characters, unnormalized )
|
||||||
|
when :entitydecl
|
||||||
|
handle_entitydecl( event )
|
||||||
|
when :processing_instruction, :comment, :attlistdecl,
|
||||||
|
diff --git a/lib/rexml/parsers/streamparser.rb b/lib/rexml/parsers/streamparser.rb
|
||||||
|
index 9e0eb0b..fa3ac49 100644
|
||||||
|
--- a/lib/rexml/parsers/streamparser.rb
|
||||||
|
+++ b/lib/rexml/parsers/streamparser.rb
|
||||||
|
@@ -36,8 +36,8 @@ module REXML
|
||||||
|
@listener.tag_end( event[1] )
|
||||||
|
@tag_stack.pop
|
||||||
|
when :text
|
||||||
|
- normalized = @parser.unnormalize( event[1] )
|
||||||
|
- @listener.text( normalized )
|
||||||
|
+ unnormalized = @parser.unnormalize( event[1] )
|
||||||
|
+ @listener.text( unnormalized )
|
||||||
|
when :processing_instruction
|
||||||
|
@listener.instruction( *event[1,2] )
|
||||||
|
when :start_doctype
|
||||||
|
diff --git a/lib/rexml/rexml.rb b/lib/rexml/rexml.rb
|
||||||
|
index 3af03ec..39e92a5 100644
|
||||||
|
--- a/lib/rexml/rexml.rb
|
||||||
|
+++ b/lib/rexml/rexml.rb
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
module REXML
|
||||||
|
COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
|
||||||
|
DATE = "2008/019"
|
||||||
|
- VERSION = "3.3.1"
|
||||||
|
+ VERSION = "3.3.3"
|
||||||
|
REVISION = ""
|
||||||
|
|
||||||
|
Copyright = COPYRIGHT
|
||||||
|
diff --git a/lib/rexml/source.rb b/lib/rexml/source.rb
|
||||||
|
index 5715c35..ff887fc 100644
|
||||||
|
--- a/lib/rexml/source.rb
|
||||||
|
+++ b/lib/rexml/source.rb
|
||||||
|
@@ -204,10 +204,20 @@ module REXML
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
- def read(term = nil)
|
||||||
|
+ def read(term = nil, min_bytes = 1)
|
||||||
|
term = encode(term) if term
|
||||||
|
begin
|
||||||
|
- @scanner << readline(term)
|
||||||
|
+ str = readline(term)
|
||||||
|
+ @scanner << str
|
||||||
|
+ read_bytes = str.bytesize
|
||||||
|
+ begin
|
||||||
|
+ while read_bytes < min_bytes
|
||||||
|
+ str = readline(term)
|
||||||
|
+ @scanner << str
|
||||||
|
+ read_bytes += str.bytesize
|
||||||
|
+ end
|
||||||
|
+ rescue IOError
|
||||||
|
+ end
|
||||||
|
true
|
||||||
|
rescue Exception, NameError
|
||||||
|
@source = nil
|
||||||
|
@@ -237,10 +247,9 @@ module REXML
|
||||||
|
read if @scanner.eos? && @source
|
||||||
|
end
|
||||||
|
|
||||||
|
- # Note: When specifying a string for 'pattern', it must not include '>' except in the following formats:
|
||||||
|
- # - ">"
|
||||||
|
- # - "XXX>" (X is any string excluding '>')
|
||||||
|
def match( pattern, cons=false )
|
||||||
|
+ # To avoid performance issue, we need to increase bytes to read per scan
|
||||||
|
+ min_bytes = 1
|
||||||
|
while true
|
||||||
|
if cons
|
||||||
|
md = @scanner.scan(pattern)
|
||||||
|
@@ -250,7 +259,8 @@ module REXML
|
||||||
|
break if md
|
||||||
|
return nil if pattern.is_a?(String)
|
||||||
|
return nil if @source.nil?
|
||||||
|
- return nil unless read
|
||||||
|
+ return nil unless read(nil, min_bytes)
|
||||||
|
+ min_bytes *= 2
|
||||||
|
end
|
||||||
|
|
||||||
|
md.nil? ? nil : @scanner
|
||||||
|
diff --git a/lib/rexml/text.rb b/lib/rexml/text.rb
|
||||||
|
index b47bad3..7e0befe 100644
|
||||||
|
--- a/lib/rexml/text.rb
|
||||||
|
+++ b/lib/rexml/text.rb
|
||||||
|
@@ -151,25 +151,45 @@ module REXML
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
- # context sensitive
|
||||||
|
- string.scan(pattern) do
|
||||||
|
- if $1[-1] != ?;
|
||||||
|
- raise "Illegal character #{$1.inspect} in raw string #{string.inspect}"
|
||||||
|
- elsif $1[0] == ?&
|
||||||
|
- if $5 and $5[0] == ?#
|
||||||
|
- case ($5[1] == ?x ? $5[2..-1].to_i(16) : $5[1..-1].to_i)
|
||||||
|
- when *VALID_CHAR
|
||||||
|
+ pos = 0
|
||||||
|
+ while (index = string.index(/<|&/, pos))
|
||||||
|
+ if string[index] == "<"
|
||||||
|
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ unless (end_index = string.index(/[^\s];/, index + 1))
|
||||||
|
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ value = string[(index + 1)..end_index]
|
||||||
|
+ if /\s/.match?(value)
|
||||||
|
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ if value[0] == "#"
|
||||||
|
+ character_reference = value[1..-1]
|
||||||
|
+
|
||||||
|
+ unless (/\A(\d+|x[0-9a-fA-F]+)\z/.match?(character_reference))
|
||||||
|
+ if character_reference[0] == "x" || character_reference[-1] == "x"
|
||||||
|
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
||||||
|
else
|
||||||
|
- raise "Illegal character #{$1.inspect} in raw string #{string.inspect}"
|
||||||
|
+ raise "Illegal character #{string.inspect} in raw string #{string.inspect}"
|
||||||
|
end
|
||||||
|
- # FIXME: below can't work but this needs API change.
|
||||||
|
- # elsif @parent and $3 and !SUBSTITUTES.include?($1)
|
||||||
|
- # if !doctype or !doctype.entities.has_key?($3)
|
||||||
|
- # raise "Undeclared entity '#{$1}' in raw string \"#{string}\""
|
||||||
|
- # end
|
||||||
|
end
|
||||||
|
+
|
||||||
|
+ case (character_reference[0] == "x" ? character_reference[1..-1].to_i(16) : character_reference[0..-1].to_i)
|
||||||
|
+ when *VALID_CHAR
|
||||||
|
+ else
|
||||||
|
+ raise "Illegal character #{string.inspect} in raw string #{string.inspect}"
|
||||||
|
+ end
|
||||||
|
+ elsif !(/\A#{Entity::NAME}\z/um.match?(value))
|
||||||
|
+ raise "Illegal character \"#{string[index]}\" in raw string #{string.inspect}"
|
||||||
|
end
|
||||||
|
+
|
||||||
|
+ pos = end_index + 1
|
||||||
|
end
|
||||||
|
+
|
||||||
|
+ string
|
||||||
|
end
|
||||||
|
|
||||||
|
def node_type
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
524
backport-CVE-2024-43398-upgrade-lib-rexml-to-3.3.6.patch
Normal file
524
backport-CVE-2024-43398-upgrade-lib-rexml-to-3.3.6.patch
Normal file
@ -0,0 +1,524 @@
|
|||||||
|
From 95871f399eda642a022b03550479b7994895c742 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sutou Kouhei <kou@clear-code.com>
|
||||||
|
Date: Thu, 22 Aug 2024 09:54:49 +0900
|
||||||
|
Subject: [PATCH] Add 3.3.6 entry
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/rexml/element.rb | 30 ++--
|
||||||
|
lib/rexml/entity.rb | 52 +------
|
||||||
|
lib/rexml/parsers/baseparser.rb | 139 +++++++++++++-----
|
||||||
|
lib/rexml/parsers/streamparser.rb | 16 +-
|
||||||
|
lib/rexml/parsers/treeparser.rb | 7 -
|
||||||
|
lib/rexml/rexml.rb | 2 +-
|
||||||
|
6 files changed, 131 insertions(+), 115 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/rexml/element.rb b/lib/rexml/element.rb
|
||||||
|
index a5808d7..4e3a60b 100644
|
||||||
|
--- a/lib/rexml/element.rb
|
||||||
|
+++ b/lib/rexml/element.rb
|
||||||
|
@@ -441,9 +441,14 @@ module REXML
|
||||||
|
# Related: #root_node, #document.
|
||||||
|
#
|
||||||
|
def root
|
||||||
|
- return elements[1] if self.kind_of? Document
|
||||||
|
- return self if parent.kind_of? Document or parent.nil?
|
||||||
|
- return parent.root
|
||||||
|
+ target = self
|
||||||
|
+ while target
|
||||||
|
+ return target.elements[1] if target.kind_of? Document
|
||||||
|
+ parent = target.parent
|
||||||
|
+ return target if parent.kind_of? Document or parent.nil?
|
||||||
|
+ target = parent
|
||||||
|
+ end
|
||||||
|
+ nil
|
||||||
|
end
|
||||||
|
|
||||||
|
# :call-seq:
|
||||||
|
@@ -619,8 +624,12 @@ module REXML
|
||||||
|
else
|
||||||
|
prefix = "xmlns:#{prefix}" unless prefix[0,5] == 'xmlns'
|
||||||
|
end
|
||||||
|
- ns = attributes[ prefix ]
|
||||||
|
- ns = parent.namespace(prefix) if ns.nil? and parent
|
||||||
|
+ ns = nil
|
||||||
|
+ target = self
|
||||||
|
+ while ns.nil? and target
|
||||||
|
+ ns = target.attributes[prefix]
|
||||||
|
+ target = target.parent
|
||||||
|
+ end
|
||||||
|
ns = '' if ns.nil? and prefix == 'xmlns'
|
||||||
|
return ns
|
||||||
|
end
|
||||||
|
@@ -2375,17 +2384,6 @@ module REXML
|
||||||
|
elsif old_attr.kind_of? Hash
|
||||||
|
old_attr[value.prefix] = value
|
||||||
|
elsif old_attr.prefix != value.prefix
|
||||||
|
- # Check for conflicting namespaces
|
||||||
|
- if value.prefix != "xmlns" and old_attr.prefix != "xmlns"
|
||||||
|
- old_namespace = old_attr.namespace
|
||||||
|
- new_namespace = value.namespace
|
||||||
|
- if old_namespace == new_namespace
|
||||||
|
- raise ParseException.new(
|
||||||
|
- "Namespace conflict in adding attribute \"#{value.name}\": "+
|
||||||
|
- "Prefix \"#{old_attr.prefix}\" = \"#{old_namespace}\" and "+
|
||||||
|
- "prefix \"#{value.prefix}\" = \"#{new_namespace}\"")
|
||||||
|
- end
|
||||||
|
- end
|
||||||
|
store value.name, {old_attr.prefix => old_attr,
|
||||||
|
value.prefix => value}
|
||||||
|
else
|
||||||
|
diff --git a/lib/rexml/entity.rb b/lib/rexml/entity.rb
|
||||||
|
index 573db69..12bbad3 100644
|
||||||
|
--- a/lib/rexml/entity.rb
|
||||||
|
+++ b/lib/rexml/entity.rb
|
||||||
|
@@ -12,6 +12,7 @@ module REXML
|
||||||
|
EXTERNALID = "(?:(?:(SYSTEM)\\s+#{SYSTEMLITERAL})|(?:(PUBLIC)\\s+#{PUBIDLITERAL}\\s+#{SYSTEMLITERAL}))"
|
||||||
|
NDATADECL = "\\s+NDATA\\s+#{NAME}"
|
||||||
|
PEREFERENCE = "%#{NAME};"
|
||||||
|
+ PEREFERENCE_RE = /#{PEREFERENCE}/um
|
||||||
|
ENTITYVALUE = %Q{((?:"(?:[^%&"]|#{PEREFERENCE}|#{REFERENCE})*")|(?:'([^%&']|#{PEREFERENCE}|#{REFERENCE})*'))}
|
||||||
|
PEDEF = "(?:#{ENTITYVALUE}|#{EXTERNALID})"
|
||||||
|
ENTITYDEF = "(?:#{ENTITYVALUE}|(?:#{EXTERNALID}(#{NDATADECL})?))"
|
||||||
|
@@ -19,7 +20,7 @@ module REXML
|
||||||
|
GEDECL = "<!ENTITY\\s+#{NAME}\\s+#{ENTITYDEF}\\s*>"
|
||||||
|
ENTITYDECL = /\s*(?:#{GEDECL})|(?:#{PEDECL})/um
|
||||||
|
|
||||||
|
- attr_reader :name, :external, :ref, :ndata, :pubid
|
||||||
|
+ attr_reader :name, :external, :ref, :ndata, :pubid, :value
|
||||||
|
|
||||||
|
# Create a new entity. Simple entities can be constructed by passing a
|
||||||
|
# name, value to the constructor; this creates a generic, plain entity
|
||||||
|
@@ -68,14 +69,11 @@ module REXML
|
||||||
|
end
|
||||||
|
|
||||||
|
# Evaluates to the unnormalized value of this entity; that is, replacing
|
||||||
|
- # all entities -- both %ent; and &ent; entities. This differs from
|
||||||
|
- # +value()+ in that +value+ only replaces %ent; entities.
|
||||||
|
+ # &ent; entities.
|
||||||
|
def unnormalized
|
||||||
|
document.record_entity_expansion unless document.nil?
|
||||||
|
- v = value()
|
||||||
|
- return nil if v.nil?
|
||||||
|
- @unnormalized = Text::unnormalize(v, parent)
|
||||||
|
- @unnormalized
|
||||||
|
+ return nil if @value.nil?
|
||||||
|
+ @unnormalized = Text::unnormalize(@value, parent)
|
||||||
|
end
|
||||||
|
|
||||||
|
#once :unnormalized
|
||||||
|
@@ -121,46 +119,6 @@ module REXML
|
||||||
|
write rv
|
||||||
|
rv
|
||||||
|
end
|
||||||
|
-
|
||||||
|
- PEREFERENCE_RE = /#{PEREFERENCE}/um
|
||||||
|
- # Returns the value of this entity. At the moment, only internal entities
|
||||||
|
- # are processed. If the value contains internal references (IE,
|
||||||
|
- # %blah;), those are replaced with their values. IE, if the doctype
|
||||||
|
- # contains:
|
||||||
|
- # <!ENTITY % foo "bar">
|
||||||
|
- # <!ENTITY yada "nanoo %foo; nanoo>
|
||||||
|
- # then:
|
||||||
|
- # doctype.entity('yada').value #-> "nanoo bar nanoo"
|
||||||
|
- def value
|
||||||
|
- @resolved_value ||= resolve_value
|
||||||
|
- end
|
||||||
|
-
|
||||||
|
- def parent=(other)
|
||||||
|
- @resolved_value = nil
|
||||||
|
- super
|
||||||
|
- end
|
||||||
|
-
|
||||||
|
- private
|
||||||
|
- def resolve_value
|
||||||
|
- return nil if @value.nil?
|
||||||
|
- return @value unless @value.match?(PEREFERENCE_RE)
|
||||||
|
-
|
||||||
|
- matches = @value.scan(PEREFERENCE_RE)
|
||||||
|
- rv = @value.clone
|
||||||
|
- if @parent
|
||||||
|
- sum = 0
|
||||||
|
- matches.each do |entity_reference|
|
||||||
|
- entity_value = @parent.entity( entity_reference[0] )
|
||||||
|
- if sum + entity_value.bytesize > Security.entity_expansion_text_limit
|
||||||
|
- raise "entity expansion has grown too large"
|
||||||
|
- else
|
||||||
|
- sum += entity_value.bytesize
|
||||||
|
- end
|
||||||
|
- rv.gsub!( /%#{entity_reference.join};/um, entity_value )
|
||||||
|
- end
|
||||||
|
- end
|
||||||
|
- rv
|
||||||
|
- end
|
||||||
|
end
|
||||||
|
|
||||||
|
# This is a set of entity constants -- the ones defined in the XML
|
||||||
|
diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
|
||||||
|
index 44dc658..d11c276 100644
|
||||||
|
--- a/lib/rexml/parsers/baseparser.rb
|
||||||
|
+++ b/lib/rexml/parsers/baseparser.rb
|
||||||
|
@@ -1,12 +1,29 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
require_relative '../parseexception'
|
||||||
|
require_relative '../undefinednamespaceexception'
|
||||||
|
+require_relative '../security'
|
||||||
|
require_relative '../source'
|
||||||
|
require 'set'
|
||||||
|
require "strscan"
|
||||||
|
|
||||||
|
module REXML
|
||||||
|
module Parsers
|
||||||
|
+ unless [].respond_to?(:tally)
|
||||||
|
+ module EnumerableTally
|
||||||
|
+ refine Enumerable do
|
||||||
|
+ def tally
|
||||||
|
+ counts = {}
|
||||||
|
+ each do |item|
|
||||||
|
+ counts[item] ||= 0
|
||||||
|
+ counts[item] += 1
|
||||||
|
+ end
|
||||||
|
+ counts
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ using EnumerableTally
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
if StringScanner::Version < "3.0.8"
|
||||||
|
module StringScannerCaptures
|
||||||
|
refine StringScanner do
|
||||||
|
@@ -124,6 +141,7 @@ module REXML
|
||||||
|
}
|
||||||
|
|
||||||
|
module Private
|
||||||
|
+ PEREFERENCE_PATTERN = /#{PEREFERENCE}/um
|
||||||
|
TAG_PATTERN = /((?>#{QNAME_STR}))\s*/um
|
||||||
|
CLOSE_PATTERN = /(#{QNAME_STR})\s*>/um
|
||||||
|
ATTLISTDECL_END = /\s+#{NAME}(?:#{ATTDEF})*\s*>/um
|
||||||
|
@@ -163,7 +181,8 @@ module REXML
|
||||||
|
@tags = []
|
||||||
|
@stack = []
|
||||||
|
@entities = []
|
||||||
|
- @nsstack = []
|
||||||
|
+ @namespaces = {}
|
||||||
|
+ @namespaces_restore_stack = []
|
||||||
|
end
|
||||||
|
|
||||||
|
def position
|
||||||
|
@@ -231,6 +250,10 @@ module REXML
|
||||||
|
if @document_status == :in_doctype
|
||||||
|
raise ParseException.new("Malformed DOCTYPE: unclosed", @source)
|
||||||
|
end
|
||||||
|
+ unless @tags.empty?
|
||||||
|
+ path = "/" + @tags.join("/")
|
||||||
|
+ raise ParseException.new("Missing end tag for '#{path}'", @source)
|
||||||
|
+ end
|
||||||
|
return [ :end_document ]
|
||||||
|
end
|
||||||
|
return @stack.shift if @stack.size > 0
|
||||||
|
@@ -263,7 +286,6 @@ module REXML
|
||||||
|
@source.position = start_position
|
||||||
|
raise REXML::ParseException.new(message, @source)
|
||||||
|
end
|
||||||
|
- @nsstack.unshift(Set.new)
|
||||||
|
name = parse_name(base_error_message)
|
||||||
|
if @source.match(/\s*\[/um, true)
|
||||||
|
id = [nil, nil, nil]
|
||||||
|
@@ -333,6 +355,8 @@ module REXML
|
||||||
|
match[4] = match[4][1..-2] # HREF
|
||||||
|
match.delete_at(5) if match.size > 5 # Chop out NDATA decl
|
||||||
|
# match is [ :entity, name, PUBLIC, pubid, href(, ndata)? ]
|
||||||
|
+ elsif Private::PEREFERENCE_PATTERN.match?(match[2])
|
||||||
|
+ raise REXML::ParseException.new("Parameter entity references forbidden in internal subset: #{match[2]}", @source)
|
||||||
|
else
|
||||||
|
match[2] = match[2][1..-2]
|
||||||
|
match.pop if match.size == 4
|
||||||
|
@@ -355,7 +379,7 @@ module REXML
|
||||||
|
val = attdef[4] if val == "#FIXED "
|
||||||
|
pairs[attdef[0]] = val
|
||||||
|
if attdef[0] =~ /^xmlns:(.*)/
|
||||||
|
- @nsstack[0] << $1
|
||||||
|
+ @namespaces[$1] = val
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@@ -408,7 +432,7 @@ module REXML
|
||||||
|
# here explicitly.
|
||||||
|
@source.ensure_buffer
|
||||||
|
if @source.match("/", true)
|
||||||
|
- @nsstack.shift
|
||||||
|
+ @namespaces_restore_stack.pop
|
||||||
|
last_tag = @tags.pop
|
||||||
|
md = @source.match(Private::CLOSE_PATTERN, true)
|
||||||
|
if md and !last_tag
|
||||||
|
@@ -453,18 +477,18 @@ module REXML
|
||||||
|
@document_status = :in_element
|
||||||
|
@prefixes.clear
|
||||||
|
@prefixes << md[2] if md[2]
|
||||||
|
- @nsstack.unshift(curr_ns=Set.new)
|
||||||
|
- attributes, closed = parse_attributes(@prefixes, curr_ns)
|
||||||
|
+ push_namespaces_restore
|
||||||
|
+ attributes, closed = parse_attributes(@prefixes)
|
||||||
|
# Verify that all of the prefixes have been defined
|
||||||
|
for prefix in @prefixes
|
||||||
|
- unless @nsstack.find{|k| k.member?(prefix)}
|
||||||
|
+ unless @namespaces.key?(prefix)
|
||||||
|
raise UndefinedNamespaceException.new(prefix,@source,self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if closed
|
||||||
|
@closed = tag
|
||||||
|
- @nsstack.shift
|
||||||
|
+ pop_namespaces_restore
|
||||||
|
else
|
||||||
|
if @tags.empty? and @have_root
|
||||||
|
raise ParseException.new("Malformed XML: Extra tag at the end of the document (got '<#{tag}')", @source)
|
||||||
|
@@ -504,15 +528,13 @@ module REXML
|
||||||
|
private :pull_event
|
||||||
|
|
||||||
|
def entity( reference, entities )
|
||||||
|
- value = nil
|
||||||
|
- value = entities[ reference ] if entities
|
||||||
|
- if value
|
||||||
|
- record_entity_expansion
|
||||||
|
- else
|
||||||
|
- value = DEFAULT_ENTITIES[ reference ]
|
||||||
|
- value = value[2] if value
|
||||||
|
- end
|
||||||
|
- unnormalize( value, entities ) if value
|
||||||
|
+ return unless entities
|
||||||
|
+
|
||||||
|
+ value = entities[ reference ]
|
||||||
|
+ return if value.nil?
|
||||||
|
+
|
||||||
|
+ record_entity_expansion
|
||||||
|
+ unnormalize( value, entities )
|
||||||
|
end
|
||||||
|
|
||||||
|
# Escapes all possible entities
|
||||||
|
@@ -546,22 +568,29 @@ module REXML
|
||||||
|
[Integer(m)].pack('U*')
|
||||||
|
}
|
||||||
|
matches.collect!{|x|x[0]}.compact!
|
||||||
|
+ if filter
|
||||||
|
+ matches.reject! do |entity_reference|
|
||||||
|
+ filter.include?(entity_reference)
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
if matches.size > 0
|
||||||
|
- sum = 0
|
||||||
|
- matches.each do |entity_reference|
|
||||||
|
- unless filter and filter.include?(entity_reference)
|
||||||
|
- entity_value = entity( entity_reference, entities )
|
||||||
|
- if entity_value
|
||||||
|
- re = Private::DEFAULT_ENTITIES_PATTERNS[entity_reference] || /&#{entity_reference};/
|
||||||
|
- rv.gsub!( re, entity_value )
|
||||||
|
- sum += rv.bytesize
|
||||||
|
- if sum > Security.entity_expansion_text_limit
|
||||||
|
- raise "entity expansion has grown too large"
|
||||||
|
- end
|
||||||
|
- else
|
||||||
|
- er = DEFAULT_ENTITIES[entity_reference]
|
||||||
|
- rv.gsub!( er[0], er[2] ) if er
|
||||||
|
+ matches.tally.each do |entity_reference, n|
|
||||||
|
+ entity_expansion_count_before = @entity_expansion_count
|
||||||
|
+ entity_value = entity( entity_reference, entities )
|
||||||
|
+ if entity_value
|
||||||
|
+ if n > 1
|
||||||
|
+ entity_expansion_count_delta =
|
||||||
|
+ @entity_expansion_count - entity_expansion_count_before
|
||||||
|
+ record_entity_expansion(entity_expansion_count_delta * (n - 1))
|
||||||
|
end
|
||||||
|
+ re = Private::DEFAULT_ENTITIES_PATTERNS[entity_reference] || /&#{entity_reference};/
|
||||||
|
+ rv.gsub!( re, entity_value )
|
||||||
|
+ if rv.bytesize > Security.entity_expansion_text_limit
|
||||||
|
+ raise "entity expansion has grown too large"
|
||||||
|
+ end
|
||||||
|
+ else
|
||||||
|
+ er = DEFAULT_ENTITIES[entity_reference]
|
||||||
|
+ rv.gsub!( er[0], er[2] ) if er
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rv.gsub!( Private::DEFAULT_ENTITIES_PATTERNS['amp'], '&' )
|
||||||
|
@@ -570,9 +599,34 @@ module REXML
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
+ def add_namespace(prefix, uri)
|
||||||
|
+ @namespaces_restore_stack.last[prefix] = @namespaces[prefix]
|
||||||
|
+ if uri.nil?
|
||||||
|
+ @namespaces.delete(prefix)
|
||||||
|
+ else
|
||||||
|
+ @namespaces[prefix] = uri
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ def push_namespaces_restore
|
||||||
|
+ namespaces_restore = {}
|
||||||
|
+ @namespaces_restore_stack.push(namespaces_restore)
|
||||||
|
+ namespaces_restore
|
||||||
|
+ end
|
||||||
|
|
||||||
|
- def record_entity_expansion
|
||||||
|
- @entity_expansion_count += 1
|
||||||
|
+ def pop_namespaces_restore
|
||||||
|
+ namespaces_restore = @namespaces_restore_stack.pop
|
||||||
|
+ namespaces_restore.each do |prefix, uri|
|
||||||
|
+ if uri.nil?
|
||||||
|
+ @namespaces.delete(prefix)
|
||||||
|
+ else
|
||||||
|
+ @namespaces[prefix] = uri
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
+ def record_entity_expansion(delta=1)
|
||||||
|
+ @entity_expansion_count += delta
|
||||||
|
if @entity_expansion_count > Security.entity_expansion_limit
|
||||||
|
raise "number of entity expansions exceeded, processing aborted."
|
||||||
|
end
|
||||||
|
@@ -698,8 +752,9 @@ module REXML
|
||||||
|
[:processing_instruction, name, content]
|
||||||
|
end
|
||||||
|
|
||||||
|
- def parse_attributes(prefixes, curr_ns)
|
||||||
|
+ def parse_attributes(prefixes)
|
||||||
|
attributes = {}
|
||||||
|
+ expanded_names = {}
|
||||||
|
closed = false
|
||||||
|
while true
|
||||||
|
if @source.match(">", true)
|
||||||
|
@@ -741,7 +796,7 @@ module REXML
|
||||||
|
"(http://www.w3.org/TR/REC-xml-names/#ns-decl)"
|
||||||
|
raise REXML::ParseException.new( msg, @source, self)
|
||||||
|
end
|
||||||
|
- curr_ns << local_part
|
||||||
|
+ add_namespace(local_part, value)
|
||||||
|
elsif prefix
|
||||||
|
prefixes << prefix unless prefix == "xml"
|
||||||
|
end
|
||||||
|
@@ -751,6 +806,20 @@ module REXML
|
||||||
|
raise REXML::ParseException.new(msg, @source, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
+ unless prefix == "xmlns"
|
||||||
|
+ uri = @namespaces[prefix]
|
||||||
|
+ expanded_name = [uri, local_part]
|
||||||
|
+ existing_prefix = expanded_names[expanded_name]
|
||||||
|
+ if existing_prefix
|
||||||
|
+ message = "Namespace conflict in adding attribute " +
|
||||||
|
+ "\"#{local_part}\": " +
|
||||||
|
+ "Prefix \"#{existing_prefix}\" = \"#{uri}\" and " +
|
||||||
|
+ "prefix \"#{prefix}\" = \"#{uri}\""
|
||||||
|
+ raise REXML::ParseException.new(message, @source, self)
|
||||||
|
+ end
|
||||||
|
+ expanded_names[expanded_name] = prefix
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
attributes[name] = value
|
||||||
|
else
|
||||||
|
message = "Invalid attribute name: <#{@source.buffer.split(%r{[/>\s]}).first}>"
|
||||||
|
diff --git a/lib/rexml/parsers/streamparser.rb b/lib/rexml/parsers/streamparser.rb
|
||||||
|
index fa3ac49..7781fe4 100644
|
||||||
|
--- a/lib/rexml/parsers/streamparser.rb
|
||||||
|
+++ b/lib/rexml/parsers/streamparser.rb
|
||||||
|
@@ -7,36 +7,33 @@ module REXML
|
||||||
|
def initialize source, listener
|
||||||
|
@listener = listener
|
||||||
|
@parser = BaseParser.new( source )
|
||||||
|
- @tag_stack = []
|
||||||
|
+ @entities = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_listener( listener )
|
||||||
|
@parser.add_listener( listener )
|
||||||
|
end
|
||||||
|
|
||||||
|
+ def entity_expansion_count
|
||||||
|
+ @parser.entity_expansion_count
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
def parse
|
||||||
|
# entity string
|
||||||
|
while true
|
||||||
|
event = @parser.pull
|
||||||
|
case event[0]
|
||||||
|
when :end_document
|
||||||
|
- unless @tag_stack.empty?
|
||||||
|
- tag_path = "/" + @tag_stack.join("/")
|
||||||
|
- raise ParseException.new("Missing end tag for '#{tag_path}'",
|
||||||
|
- @parser.source)
|
||||||
|
- end
|
||||||
|
return
|
||||||
|
when :start_element
|
||||||
|
- @tag_stack << event[1]
|
||||||
|
attrs = event[2].each do |n, v|
|
||||||
|
event[2][n] = @parser.unnormalize( v )
|
||||||
|
end
|
||||||
|
@listener.tag_start( event[1], attrs )
|
||||||
|
when :end_element
|
||||||
|
@listener.tag_end( event[1] )
|
||||||
|
- @tag_stack.pop
|
||||||
|
when :text
|
||||||
|
- unnormalized = @parser.unnormalize( event[1] )
|
||||||
|
+ unnormalized = @parser.unnormalize( event[1], @entities )
|
||||||
|
@listener.text( unnormalized )
|
||||||
|
when :processing_instruction
|
||||||
|
@listener.instruction( *event[1,2] )
|
||||||
|
@@ -48,6 +45,7 @@ module REXML
|
||||||
|
when :comment, :attlistdecl, :cdata, :xmldecl, :elementdecl
|
||||||
|
@listener.send( event[0].to_s, *event[1..-1] )
|
||||||
|
when :entitydecl, :notationdecl
|
||||||
|
+ @entities[ event[1] ] = event[2] if event.size == 3
|
||||||
|
@listener.send( event[0].to_s, event[1..-1] )
|
||||||
|
when :externalentity
|
||||||
|
entity_reference = event[1]
|
||||||
|
diff --git a/lib/rexml/parsers/treeparser.rb b/lib/rexml/parsers/treeparser.rb
|
||||||
|
index 0cb6f7c..4565a40 100644
|
||||||
|
--- a/lib/rexml/parsers/treeparser.rb
|
||||||
|
+++ b/lib/rexml/parsers/treeparser.rb
|
||||||
|
@@ -15,7 +15,6 @@ module REXML
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse
|
||||||
|
- tag_stack = []
|
||||||
|
entities = nil
|
||||||
|
begin
|
||||||
|
while true
|
||||||
|
@@ -23,19 +22,13 @@ module REXML
|
||||||
|
#STDERR.puts "TREEPARSER GOT #{event.inspect}"
|
||||||
|
case event[0]
|
||||||
|
when :end_document
|
||||||
|
- unless tag_stack.empty?
|
||||||
|
- raise ParseException.new("No close tag for #{@build_context.xpath}",
|
||||||
|
- @parser.source, @parser)
|
||||||
|
- end
|
||||||
|
return
|
||||||
|
when :start_element
|
||||||
|
- tag_stack.push(event[1])
|
||||||
|
el = @build_context = @build_context.add_element( event[1] )
|
||||||
|
event[2].each do |key, value|
|
||||||
|
el.attributes[key]=Attribute.new(key,value,self)
|
||||||
|
end
|
||||||
|
when :end_element
|
||||||
|
- tag_stack.pop
|
||||||
|
@build_context = @build_context.parent
|
||||||
|
when :text
|
||||||
|
if @build_context[-1].instance_of? Text
|
||||||
|
diff --git a/lib/rexml/rexml.rb b/lib/rexml/rexml.rb
|
||||||
|
index 39e92a5..99d574b 100644
|
||||||
|
--- a/lib/rexml/rexml.rb
|
||||||
|
+++ b/lib/rexml/rexml.rb
|
||||||
|
@@ -31,7 +31,7 @@
|
||||||
|
module REXML
|
||||||
|
COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
|
||||||
|
DATE = "2008/019"
|
||||||
|
- VERSION = "3.3.3"
|
||||||
|
+ VERSION = "3.3.6"
|
||||||
|
REVISION = ""
|
||||||
|
|
||||||
|
Copyright = COPYRIGHT
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
62
backport-CVE-2024-47220.patch
Normal file
62
backport-CVE-2024-47220.patch
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
From f5faca9222541591e1a7c3c97552ebb0c92733c7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jeremy Evans <code@jeremyevans.net>
|
||||||
|
Date: Wed, 18 Sep 2024 14:11:49 -0700
|
||||||
|
Subject: [PATCH] Prevent request smuggling
|
||||||
|
|
||||||
|
If a request has both a content-length and transfer-encoding
|
||||||
|
headers, return a 400 response. This is allowed by RFC 7230
|
||||||
|
section 3.3.3.3.
|
||||||
|
|
||||||
|
Fixes #145
|
||||||
|
---
|
||||||
|
lib/webrick/httprequest.rb | 4 ++++
|
||||||
|
test/webrick/test_httprequest.rb | 18 ++++++++++++++++++
|
||||||
|
2 files changed, 22 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/webrick/httprequest.rb b/lib/webrick/httprequest.rb
|
||||||
|
index 5cf5844..820acb2 100644
|
||||||
|
--- a/lib/webrick/httprequest.rb
|
||||||
|
+++ b/lib/webrick/httprequest.rb
|
||||||
|
@@ -474,6 +474,10 @@ module WEBrick
|
||||||
|
def read_body(socket, block)
|
||||||
|
return unless socket
|
||||||
|
if tc = self['transfer-encoding']
|
||||||
|
+ if self['content-length']
|
||||||
|
+ raise HTTPStatus::BadRequest, "request with both transfer-encoding and content-length, possible request smuggling"
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
case tc
|
||||||
|
when /\Achunked\z/io then read_chunked(socket, block)
|
||||||
|
else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."
|
||||||
|
diff --git a/test/webrick/test_httprequest.rb b/test/webrick/test_httprequest.rb
|
||||||
|
index 855ff9d..cce9b91 100644
|
||||||
|
--- a/test/webrick/test_httprequest.rb
|
||||||
|
+++ b/test/webrick/test_httprequest.rb
|
||||||
|
@@ -81,6 +81,24 @@ GET /
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
+ def test_content_length_and_transfer_encoding_headers_smuggling
|
||||||
|
+ msg = <<~HTTP.gsub("\n", "\r\n")
|
||||||
|
+ POST /user HTTP/1.1
|
||||||
|
+ Content-Length: 28
|
||||||
|
+ Transfer-Encoding: chunked
|
||||||
|
+
|
||||||
|
+ 0
|
||||||
|
+
|
||||||
|
+ GET /admin HTTP/1.1
|
||||||
|
+
|
||||||
|
+ HTTP
|
||||||
|
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
|
||||||
|
+ req.parse(StringIO.new(msg))
|
||||||
|
+ assert_raise(WEBrick::HTTPStatus::BadRequest){
|
||||||
|
+ req.body
|
||||||
|
+ }
|
||||||
|
+ end
|
||||||
|
+
|
||||||
|
def test_parse_headers
|
||||||
|
msg = <<-_end_of_message_
|
||||||
|
GET /path HTTP/1.1
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
38
backport-CVE-2024-49761.patch
Normal file
38
backport-CVE-2024-49761.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From ce59f2eb1aeb371fe1643414f06618dbe031979f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sutou Kouhei <kou@clear-code.com>
|
||||||
|
Date: Thu, 24 Oct 2024 14:45:31 +0900
|
||||||
|
Subject: [PATCH] parser: fix a bug that �x...; is accepted as a character
|
||||||
|
reference
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
|
||||||
|
index 7bd8adf..b4547ba 100644
|
||||||
|
--- a/lib/rexml/parsers/baseparser.rb
|
||||||
|
+++ b/lib/rexml/parsers/baseparser.rb
|
||||||
|
@@ -150,7 +150,7 @@ module REXML
|
||||||
|
PEDECL_PATTERN = "\\s+(%)\\s+#{NAME}\\s+#{PEDEF}\\s*>"
|
||||||
|
ENTITYDECL_PATTERN = /(?:#{GEDECL_PATTERN})|(?:#{PEDECL_PATTERN})/um
|
||||||
|
CARRIAGE_RETURN_NEWLINE_PATTERN = /\r\n?/
|
||||||
|
- CHARACTER_REFERENCES = /�*((?:\d+)|(?:x[a-fA-F0-9]+));/
|
||||||
|
+ CHARACTER_REFERENCES = /&#((?:\d+)|(?:x[a-fA-F0-9]+));/
|
||||||
|
DEFAULT_ENTITIES_PATTERNS = {}
|
||||||
|
default_entities = ['gt', 'lt', 'quot', 'apos', 'amp']
|
||||||
|
default_entities.each do |term|
|
||||||
|
@@ -570,8 +570,12 @@ module REXML
|
||||||
|
return rv if matches.size == 0
|
||||||
|
rv.gsub!( Private::CHARACTER_REFERENCES ) {
|
||||||
|
m=$1
|
||||||
|
- m = "0#{m}" if m[0] == ?x
|
||||||
|
- [Integer(m)].pack('U*')
|
||||||
|
+ if m.start_with?("x")
|
||||||
|
+ code_point = Integer(m[1..-1], 16)
|
||||||
|
+ else
|
||||||
|
+ code_point = Integer(m, 10)
|
||||||
|
+ end
|
||||||
|
+ [code_point].pack('U*')
|
||||||
|
}
|
||||||
|
matches.collect!{|x|x[0]}.compact!
|
||||||
|
if filter
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
26
ruby.spec
26
ruby.spec
@ -1,6 +1,6 @@
|
|||||||
Name: ruby
|
Name: ruby
|
||||||
Version: 2.5.8
|
Version: 2.5.8
|
||||||
Release: 127
|
Release: 132
|
||||||
Summary: Object-oriented scripting language interpreter
|
Summary: Object-oriented scripting language interpreter
|
||||||
License: (Ruby or BSD) and Public Domain and MIT and CC0 and zlib and UCD
|
License: (Ruby or BSD) and Public Domain and MIT and CC0 and zlib and UCD
|
||||||
URL: https://www.ruby-lang.org/
|
URL: https://www.ruby-lang.org/
|
||||||
@ -70,6 +70,13 @@ Patch6026: backport-0005-CVE-2024-35221.patch
|
|||||||
Patch6027: upgrade-lib-rexml-to-3.3.1.patch
|
Patch6027: upgrade-lib-rexml-to-3.3.1.patch
|
||||||
Patch6028: upgrade-lib-rexml-test-to-3.3.1.patch
|
Patch6028: upgrade-lib-rexml-test-to-3.3.1.patch
|
||||||
Patch6029: backport-CVE-2024-41946.patch
|
Patch6029: backport-CVE-2024-41946.patch
|
||||||
|
Patch6030: backport-CVE-2024-39908-CVE-2024-41123-upgrade-lib-rexml-to-3.3.3.patch
|
||||||
|
Patch6031: backport-CVE-2024-43398-upgrade-lib-rexml-to-3.3.6.patch
|
||||||
|
Patch6032: backport-CVE-2024-47220.patch
|
||||||
|
Patch6033: backport-CVE-2024-49761.patch
|
||||||
|
Patch6034: backport-0001-CVE-2021-41817.patch
|
||||||
|
Patch6035: backport-0002-CVE-2021-41817.patch
|
||||||
|
Patch6036: backport-0003-CVE-2021-41817.patch
|
||||||
|
|
||||||
Patch9000: add-require_relative-helper-to-uninitialized-constan.patch
|
Patch9000: add-require_relative-helper-to-uninitialized-constan.patch
|
||||||
|
|
||||||
@ -145,7 +152,7 @@ The irb is acronym for Interactive Ruby,It evaluates ruby expression from the te
|
|||||||
%package -n rubygem-rdoc
|
%package -n rubygem-rdoc
|
||||||
Summary: Generate HTML and command-line documentation for Ruby projects
|
Summary: Generate HTML and command-line documentation for Ruby projects
|
||||||
Version: 6.0.1.1
|
Version: 6.0.1.1
|
||||||
License: GPLv2 and Ruby and MIT and OFL
|
License: GPLv2 and Ruby and MIT and OFL-1.1-RFN
|
||||||
Requires: ruby(release) ruby(rubygems) >= 2.7.6 ruby(irb) = 2.5.8 rubygem(io-console) >= 0.4.6 rubygem(json) >= 2.1.0
|
Requires: ruby(release) ruby(rubygems) >= 2.7.6 ruby(irb) = 2.5.8 rubygem(io-console) >= 0.4.6 rubygem(json) >= 2.1.0
|
||||||
Provides: rdoc = %{version}-%{release} ri = %{version}-%{release} rubygem(rdoc) = %{version}-%{release}
|
Provides: rdoc = %{version}-%{release} ri = %{version}-%{release} rubygem(rdoc) = %{version}-%{release}
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
@ -609,6 +616,21 @@ make runruby TESTRUN_SCRIPT=%{SOURCE13}
|
|||||||
%exclude %{gem_dir}/gems/xmlrpc-0.3.0/.*
|
%exclude %{gem_dir}/gems/xmlrpc-0.3.0/.*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Dec 19 2024 shixuantong <shixuantong1@huawei.com> - 2.5.8-132
|
||||||
|
- fix CVE-2021-41817
|
||||||
|
|
||||||
|
* Tue Oct 29 2024 shixuantong <shixuantong1@huawei.com> - 2.5.8-131
|
||||||
|
- fix CVE-2024-49761
|
||||||
|
|
||||||
|
* Tue Oct 08 2024 shixuantong <shixuantong1@huawei.com> - 2.5.8-130
|
||||||
|
- fix CVE-2024-47220
|
||||||
|
|
||||||
|
* Mon Sep 02 2024 shixuantong <shixuantong1@huawei.com> - 2.5.8-129
|
||||||
|
- upgrade rexml to fix CVE-2024-39908 CVE-2024-41123 CVE-2024-43398
|
||||||
|
|
||||||
|
* Fri Aug 30 2024 shixuantong <shixuantong1@huawei.com> - 2.5.8-128
|
||||||
|
- license compliance rectification
|
||||||
|
|
||||||
* Fri Aug 09 2024 zhangxianting <zhangxianting@uniontech.com> - 2.5.8-127
|
* Fri Aug 09 2024 zhangxianting <zhangxianting@uniontech.com> - 2.5.8-127
|
||||||
- fix CVE-2024-41946
|
- fix CVE-2024-41946
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user