mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Prevent digit-gobbling for all but %l and %e, which can't be fixed.
Discuss in the BUGS section of the manpage, problems involved with the use of %C, %e, %l, %p, %U and %W. PR: 13901 Reported by: scott@chronis.pobox.com
This commit is contained in:
parent
7313447c12
commit
398592ffe1
2 changed files with 85 additions and 12 deletions
|
|
@ -95,6 +95,45 @@ function appeared in
|
|||
.Pp
|
||||
.Sh BUGS
|
||||
The
|
||||
.Fa %C
|
||||
format specifier only accepts centuries within the range 19 to 99.
|
||||
.Pp
|
||||
Both the
|
||||
.Fa %e
|
||||
and
|
||||
.Fa %l
|
||||
format specifiers may incorrectly scan one too many digits
|
||||
if the intended values comprise only a single digit
|
||||
and that digit is followed immediately by another digit.
|
||||
Both specifiers accept zero-padded values,
|
||||
even though they are both defined as taking unpadded values.
|
||||
.Pp
|
||||
The
|
||||
.Fa %p
|
||||
format specifier has no effect unless it is parsed
|
||||
.Em after
|
||||
hour-related specifiers.
|
||||
Specifying
|
||||
.Fa %l
|
||||
without
|
||||
.Fa %p
|
||||
will produce undefined results.
|
||||
Note that 12AM
|
||||
.Pq ante meridiem
|
||||
is taken as midnight
|
||||
and 12PM
|
||||
.Pq post meridiem
|
||||
is taken as noon.
|
||||
.Pp
|
||||
The
|
||||
.Fa %U
|
||||
and
|
||||
.Fa %W
|
||||
format specifiers accept any value within the range 00 to 53
|
||||
without validating against other values supplied (like month
|
||||
or day of the year, for example).
|
||||
.Pp
|
||||
The
|
||||
.Fa %Z
|
||||
format specifier only accepts time zone abbreviations of the local time zone,
|
||||
or the value "GMT".
|
||||
|
|
|
|||
|
|
@ -129,9 +129,12 @@ label:
|
|||
if (!isdigit((unsigned char)*buf))
|
||||
return 0;
|
||||
|
||||
for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
/* XXX This will break for 3-digit centuries. */
|
||||
len = 2;
|
||||
for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
i *= 10;
|
||||
i += *buf - '0';
|
||||
len--;
|
||||
}
|
||||
if (i < 19)
|
||||
return 0;
|
||||
|
|
@ -206,9 +209,11 @@ label:
|
|||
if (!isdigit((unsigned char)*buf))
|
||||
return 0;
|
||||
|
||||
for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
len = 3;
|
||||
for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
i *= 10;
|
||||
i += *buf - '0';
|
||||
len--;
|
||||
}
|
||||
if (i < 1 || i > 366)
|
||||
return 0;
|
||||
|
|
@ -224,9 +229,11 @@ label:
|
|||
if (!isdigit((unsigned char)*buf))
|
||||
return 0;
|
||||
|
||||
for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
len = 2;
|
||||
for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
i *= 10;
|
||||
i += *buf - '0';
|
||||
len--;
|
||||
}
|
||||
|
||||
if (c == 'M') {
|
||||
|
|
@ -248,12 +255,22 @@ label:
|
|||
case 'I':
|
||||
case 'k':
|
||||
case 'l':
|
||||
/*
|
||||
* Of these, %l is the only specifier explicitly
|
||||
* documented as not being zero-padded. However,
|
||||
* there is no harm in allowing zero-padding.
|
||||
*
|
||||
* XXX The %l specifier may gobble one too many
|
||||
* digits if used incorrectly.
|
||||
*/
|
||||
if (!isdigit((unsigned char)*buf))
|
||||
return 0;
|
||||
|
||||
for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
len = 2;
|
||||
for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
i *= 10;
|
||||
i += *buf - '0';
|
||||
len--;
|
||||
}
|
||||
if (c == 'H' || c == 'k') {
|
||||
if (i > 23)
|
||||
|
|
@ -269,6 +286,10 @@ label:
|
|||
break;
|
||||
|
||||
case 'p':
|
||||
/*
|
||||
* XXX This is bogus if parsed before hour-related
|
||||
* specifiers.
|
||||
*/
|
||||
len = strlen(Locale->am);
|
||||
if (strncasecmp(buf, Locale->am, len) == 0) {
|
||||
if (tm->tm_hour > 12)
|
||||
|
|
@ -326,9 +347,11 @@ label:
|
|||
if (!isdigit((unsigned char)*buf))
|
||||
return 0;
|
||||
|
||||
for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
len = 2;
|
||||
for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
i *= 10;
|
||||
i += *buf - '0';
|
||||
len--;
|
||||
}
|
||||
if (i > 53)
|
||||
return 0;
|
||||
|
|
@ -342,10 +365,7 @@ label:
|
|||
if (!isdigit((unsigned char)*buf))
|
||||
return 0;
|
||||
|
||||
for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
i *= 10;
|
||||
i += *buf - '0';
|
||||
}
|
||||
i = *buf - '0';
|
||||
if (i > 6)
|
||||
return 0;
|
||||
|
||||
|
|
@ -358,12 +378,22 @@ label:
|
|||
|
||||
case 'd':
|
||||
case 'e':
|
||||
/*
|
||||
* The %e specifier is explicitly documented as not
|
||||
* being zero-padded but there is no harm in allowing
|
||||
* such padding.
|
||||
*
|
||||
* XXX The %e specifier may gobble one too many
|
||||
* digits if used incorrectly.
|
||||
*/
|
||||
if (!isdigit((unsigned char)*buf))
|
||||
return 0;
|
||||
|
||||
for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
len = 2;
|
||||
for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
i *= 10;
|
||||
i += *buf - '0';
|
||||
len--;
|
||||
}
|
||||
if (i > 31)
|
||||
return 0;
|
||||
|
|
@ -414,9 +444,11 @@ label:
|
|||
if (!isdigit((unsigned char)*buf))
|
||||
return 0;
|
||||
|
||||
for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
len = 2;
|
||||
for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
i *= 10;
|
||||
i += *buf - '0';
|
||||
len--;
|
||||
}
|
||||
if (i < 1 || i > 12)
|
||||
return 0;
|
||||
|
|
@ -436,9 +468,11 @@ label:
|
|||
if (!isdigit((unsigned char)*buf))
|
||||
return 0;
|
||||
|
||||
for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
len = (c == 'Y') ? 4 : 2;
|
||||
for (i = 0; len && *buf != 0 && isdigit((unsigned char)*buf); buf++) {
|
||||
i *= 10;
|
||||
i += *buf - '0';
|
||||
len--;
|
||||
}
|
||||
if (c == 'Y')
|
||||
i -= 1900;
|
||||
|
|
|
|||
Loading…
Reference in a new issue