diff --git a/newlib/libc/time/tzset_r.c b/newlib/libc/time/tzset_r.c index 9e0cf834bd6b..5bf463ed3dd7 100644 --- a/newlib/libc/time/tzset_r.c +++ b/newlib/libc/time/tzset_r.c @@ -45,8 +45,30 @@ _tzset_unlocked_r (struct _reent *reent_ptr) if (*tzenv == ':') ++tzenv; - if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_std, &n) <= 0) - return; + /* allow POSIX angle bracket < > quoted tz abbr e.g. <+03> */ + if (*tzenv == '<') + { + ++tzenv; + + /* scan while dest space left, not EoS, not close quote */ + for (n = 0; + n < sizeof (__tzname_std) && tzenv[n] && '>' != tzenv[n]; + ++n) + { + __tzname_std[n] = tzenv[n]; + } + + /* quit if no chars scanned, not close quote, or too many chars */ + if (!n || '>' != tzenv[n] || sizeof (__tzname_std) <= n) + return; + + __tzname_std[n] = '\0'; + } + else + { + if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_std, &n) <= 0) + return; + } tzenv += n; @@ -68,17 +90,43 @@ _tzset_unlocked_r (struct _reent *reent_ptr) tz->__tzrule[0].offset = sign * (ss + SECSPERMIN * mm + SECSPERHOUR * hh); _tzname[0] = __tzname_std; tzenv += n; - - if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_dst, &n) <= 0) - { /* No dst */ - _tzname[1] = _tzname[0]; - _timezone = tz->__tzrule[0].offset; - _daylight = 0; - return; + + /* allow POSIX angle bracket < > quoted tz abbr e.g. <+03> */ + if (*tzenv == '<') + { + ++tzenv; + + /* scan while dest space left, not EoS, not close quote */ + for (n = 0; + n < sizeof (__tzname_dst) && tzenv[n] && '>' != tzenv[n]; + ++n) + { + __tzname_dst[n] = tzenv[n]; + } + + /* quit if no chars scanned, not close quote, or too many chars */ + if (!n || '>' != tzenv[n] || sizeof (__tzname_dst) <= n) + { /* No dst */ + _tzname[1] = _tzname[0]; + _timezone = tz->__tzrule[0].offset; + _daylight = 0; + return; + } + + __tzname_dst[n] = '\0'; } else - _tzname[1] = __tzname_dst; + { + if (sscanf (tzenv, "%10[^0-9,+-]%n", __tzname_dst, &n) <= 0) + { /* No dst */ + _tzname[1] = _tzname[0]; + _timezone = tz->__tzrule[0].offset; + _daylight = 0; + return; + } + } + _tzname[1] = __tzname_dst; tzenv += n; /* otherwise we have a dst name, look for the offset */