1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Allow UTC offset without colons per ISO-8601 [Bug #17504]

This commit is contained in:
Nobuyoshi Nakada 2021-01-04 00:07:10 +09:00
parent 30a35420e6
commit 9441f3f970
Notes: git 2021-01-13 16:38:30 +09:00
2 changed files with 35 additions and 15 deletions

View file

@ -1223,6 +1223,12 @@ class TestTime < Test::Unit::TestCase
assert_equal [00, 00, 9, 1, 1, 2000], t.getlocal("+09:00").to_a[0, 6] assert_equal [00, 00, 9, 1, 1, 2000], t.getlocal("+09:00").to_a[0, 6]
assert_equal [20, 29, 21, 31, 12, 1999], t.getlocal("-02:30:40").to_a[0, 6] assert_equal [20, 29, 21, 31, 12, 1999], t.getlocal("-02:30:40").to_a[0, 6]
assert_equal [35, 10, 9, 1, 1, 2000], t.getlocal("+09:10:35").to_a[0, 6] assert_equal [35, 10, 9, 1, 1, 2000], t.getlocal("+09:10:35").to_a[0, 6]
assert_equal [00, 30, 21, 31, 12, 1999], t.getlocal("-0230").to_a[0, 6]
assert_equal [00, 00, 9, 1, 1, 2000], t.getlocal("+0900").to_a[0, 6]
assert_equal [20, 29, 21, 31, 12, 1999], t.getlocal("-023040").to_a[0, 6]
assert_equal [35, 10, 9, 1, 1, 2000], t.getlocal("+091035").to_a[0, 6]
assert_raise(ArgumentError) {t.getlocal("-02:3040")}
assert_raise(ArgumentError) {t.getlocal("+0910:35")}
end end
def test_getlocal_nil def test_getlocal_nil

44
time.c
View file

@ -2087,7 +2087,7 @@ utc_offset_arg(VALUE arg)
VALUE tmp; VALUE tmp;
if (!NIL_P(tmp = rb_check_string_type(arg))) { if (!NIL_P(tmp = rb_check_string_type(arg))) {
int n = 0; int n = 0;
char *s = RSTRING_PTR(tmp); const char *s = RSTRING_PTR(tmp), *min = NULL, *sec = NULL;
if (!rb_enc_str_asciicompat_p(tmp)) { if (!rb_enc_str_asciicompat_p(tmp)) {
goto invalid_utc_offset; goto invalid_utc_offset;
} }
@ -2115,24 +2115,38 @@ utc_offset_arg(VALUE arg)
if (STRNCASECMP("UTC", s, 3) == 0) { if (STRNCASECMP("UTC", s, 3) == 0) {
return UTC_ZONE; return UTC_ZONE;
} }
goto invalid_utc_offset; break; /* +HH */
case 9: case 5: /* +HHMM */
if (s[6] != ':') goto invalid_utc_offset; min = s+3;
if (!ISDIGIT(s[7]) || !ISDIGIT(s[8])) goto invalid_utc_offset; break;
n += (s[7] * 10 + s[8] - '0' * 11); case 6: /* +HH:MM */
/* fall through */ min = s+4;
case 6: break;
if (s[0] != '+' && s[0] != '-') goto invalid_utc_offset; case 7: /* +HHMMSS */
if (!ISDIGIT(s[1]) || !ISDIGIT(s[2])) goto invalid_utc_offset; sec = s+5;
if (s[3] != ':') goto invalid_utc_offset; min = s+3;
if (!ISDIGIT(s[4]) || !ISDIGIT(s[5])) goto invalid_utc_offset; break;
if (s[4] > '5') goto invalid_utc_offset; case 9: /* +HH:MM:SS */
break; sec = s+7;
min = s+4;
break;
default: default:
goto invalid_utc_offset; goto invalid_utc_offset;
} }
if (sec) {
if (sec == s+7 && *(sec-1) != ':') goto invalid_utc_offset;
if (!ISDIGIT(sec[0]) || !ISDIGIT(sec[1])) goto invalid_utc_offset;
n += (sec[0] * 10 + sec[1] - '0' * 11);
}
if (min) {
if (min == s+4 && *(min-1) != ':') goto invalid_utc_offset;
if (!ISDIGIT(min[0]) || !ISDIGIT(min[1])) goto invalid_utc_offset;
if (min[0] > '5') goto invalid_utc_offset;
n += (min[0] * 10 + min[1] - '0' * 11) * 60;
}
if (s[0] != '+' && s[0] != '-') goto invalid_utc_offset;
if (!ISDIGIT(s[1]) || !ISDIGIT(s[2])) goto invalid_utc_offset;
n += (s[1] * 10 + s[2] - '0' * 11) * 3600; n += (s[1] * 10 + s[2] - '0' * 11) * 3600;
n += (s[4] * 10 + s[5] - '0' * 11) * 60;
if (s[0] == '-') if (s[0] == '-')
n = -n; n = -n;
return INT2FIX(n); return INT2FIX(n);