[ruby/date] Deprecate lenient RFC 3339 date time separators

RFC 3339 allows only "T", and by convention a space, between the date
and the time, but Date._rfc3339 also accepts \t, \n, \v, \f and \r.
Warn on those under Warning[:deprecated] before they become an error.

The separator is now captured so rfc3339_cb can inspect it, which
shifts the remaining group indices.

https://github.com/ruby/date/commit/ffb9d45105
This commit is contained in:
youdie006 authored and git committed 2026-10-09 22:45:03 +00:00
1 parent b5d839dbca
commit a9d3eadfc8
2 files changed
+39 -9

No files matched your search

+21 -9
View File
@@ -2590,7 +2590,11 @@ date__iso8601(VALUE str)
}
#undef SNUM
#define SNUM 8
#define SNUM 9
#ifndef HAVE_RB_CATEGORY_WARN
#define rb_category_warn(category, fmt) rb_warn(fmt)
#endif
static int
rfc3339_cb(VALUE m, VALUE hash)
@@ -2604,16 +2608,24 @@ rfc3339_cb(VALUE m, VALUE hash)
s[i] = rb_reg_nth_match(i, m);
}
{
int c = RSTRING_PTR(s[4])[0];
if (c != 't' && c != 'T' && c != ' ')
rb_category_warn(RB_WARN_CATEGORY_DEPRECATED,
"Invalid RFC3339 date time separator provided, "
"this will raise an error in a future version.");
}
set_hash("year", str2num(s[1]));
set_hash("mon", str2num(s[2]));
set_hash("mday", str2num(s[3]));
set_hash("hour", str2num(s[4]));
set_hash("min", str2num(s[5]));
set_hash("sec", str2num(s[6]));
set_hash("zone", s[8]);
set_hash("offset", date_zone_to_diff(s[8]));
if (!NIL_P(s[7]))
set_hash("sec_fraction", sec_fraction(s[7]));
set_hash("hour", str2num(s[5]));
set_hash("min", str2num(s[6]));
set_hash("sec", str2num(s[7]));
set_hash("zone", s[9]);
set_hash("offset", date_zone_to_diff(s[9]));
if (!NIL_P(s[8]))
set_hash("sec_fraction", sec_fraction(s[8]));
return 1;
}
@@ -2623,7 +2635,7 @@ rfc3339(VALUE str, VALUE hash)
{
static const char pat_source[] =
"\\A\\s*(-?\\d{4})-(\\d{2})-(\\d{2})"
"(?:t|\\s)"
"(t|\\s)"
"(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?"
"(z|[-+]\\d{2}:\\d{2})\\s*\\z";
static VALUE pat = Qnil;
+18
View File
@@ -889,6 +889,24 @@ class TestDateParse < Test::Unit::TestCase
assert_raise(TypeError) {Date._rfc3339('2001-02-03T04:05:06Z'.to_sym)}
end
def test__rfc3339__deprecated_separator
pat = /Invalid RFC3339 date time separator/
["\t", "\n", "\v", "\f", "\r"].each do |sep|
h = assert_deprecated_warn(pat) do
Date._rfc3339("2001-02-03#{sep}04:05:06Z")
end
assert_equal([2001, 2, 3, 4, 5, 6, 0],
h.values_at(:year, :mon, :mday, :hour, :min, :sec, :offset))
end
["T", "t", " "].each do |sep|
assert_deprecated_warn("") do
Date._rfc3339("2001-02-03#{sep}04:05:06Z")
end
end
end
def test__xmlschema
h = Date._xmlschema('2001-02-03')
assert_equal([2001, 2, 3, nil, nil, nil, nil],