| Summary: | Y2k bug in at(1) | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Crist J. Clark <cjc> |
| Component: | bin | Assignee: | Sheldon Hearn <sheldonh> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 3.4-STABLE | ||
| Hardware: | Any | ||
| OS: | Any | ||
On Mon, 03 Jan 2000 21:54:28 EST, "Crist J. Clark" wrote:
> if (year > 99) {
> if (year > 1899)
> year -= 1900;
> else
> panic("garbled time");
> } ...
What odd code. :-)
I'd fix this by making proper tm_year adjustments before those calls to
assign_date() which pass it a tm_year value.
Have you chatted to the authors? Are they unreachable?
Ciao,
Sheldon.
Index: parsetime.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/at/parsetime.c,v
retrieving revision 1.19
diff -u -d -r1.19 parsetime.c
--- parsetime.c 1999/12/05 19:57:14 1.19
+++ parsetime.c 2000/01/04 10:54:54
@@ -495,7 +495,7 @@
tm->tm_wday = wday;
- assign_date(tm, mday, tm->tm_mon, tm->tm_year);
+ assign_date(tm, mday, tm->tm_mon, 1900 + tm->tm_year);
break;
case NUMBER:
@@ -527,7 +527,7 @@
}
else if (tlen == 6 || tlen == 8) {
if (tlen == 8) {
- year = (mon % 10000) - 1900;
+ year = mon % 10000;
mon /= 10000;
}
else {
> > if (year > 99) {
> > if (year > 1899)
> > year -= 1900;
> > else
> > panic("garbled time");
> > } ...
>
> What odd code. :-)
>
> I'd fix this by making proper tm_year adjustments before those calls to
> assign_date() which pass it a tm_year value.
>
> Have you chatted to the authors? Are they unreachable?
>
> Ciao,
> Sheldon.
>
> Index: parsetime.c
> ===================================================================
> RCS file: /home/ncvs/src/usr.bin/at/parsetime.c,v
> retrieving revision 1.19
[...]
It's another way to do this right. I'v adapted OpenBSD Team patch
.
And, Mr. Sheldon, can you, please, make one of two changes in STABLE branch ?
Best Regards,
Sergey N. Voronkov.
--- /usr/src/usr.bin/at/parsetime.c Sun Aug 29 21:25:26 1999
+++ parsetime.c Fri Jan 21 10:21:56 2000
@@ -417,27 +417,30 @@
static void
assign_date(struct tm *tm, long mday, long mon, long year)
{
- if (year > 99) {
- if (year > 1899)
- year -= 1900;
- else
- panic("garbled time");
- } else if (year != -1) {
+
+ /*
+ * Convert year into tm_year format (year - 1900).
+ * We may be given the year in 2 digit, 4 digit, or tm_year format.
+ */
+#define TM_YEAR_BASE 1900
+ if (year != -1) {
struct tm *lt;
time_t now;
time(&now);
lt = localtime(&now);
- /*
- * check if the specified year is in the next century.
- * allow for one year of user error as many people will
- * enter n - 1 at the start of year n.
- */
- if (year < (lt->tm_year % 100) - 1)
- year += 100;
- /* adjust for the year 2000 and beyond */
- year += lt->tm_year - (lt->tm_year % 100);
+ if (year >= TM_YEAR_BASE)
+ year -= TM_YEAR_BASE; /* convert from 4 digit year */
+ else if (year < 100) {
+ /* Convert to tm_year assuming current century */
+ year += (lt->tm_year / 100) * 100;
+
+ if (year == lt->tm_year - 1)
+ year++; /* Common off by one error */
+ else if (year < lt->tm_year)
+ year += 100; /* must be in next century */
+ }
}
if (year < 0 &&
Hello Nick!
As a last person deeply touched /usr/src/usr.bin/at/parsetime.c,
could you, please, review and apply this patch to at (PR/15872).
Patch is based on OpenBSD code.
Sorry, I test it only on my 3.4-STABLE system. In CURRENT may be
need to make some changes in patch header. assign_date() has some bug
in both versions.
Serg N. Voronkov
--- parsetime.c.orig Mon Aug 30 00:42:00 1999
+++ parsetime.c Thu Jan 27 18:50:48 2000
@@ -417,27 +417,28 @@
static void
assign_date(struct tm *tm, long mday, long mon, long year)
{
- if (year > 99) {
- if (year > 1899)
- year -= 1900;
- else
- panic("garbled time");
- } else if (year != -1) {
- struct tm *lt;
- time_t now;
- time(&now);
- lt = localtime(&now);
+ /*
+ * Convert year into tm_year format (year - 1900).
+ */
+ if (year != -1) {
+ if (year >= 1900)
+ year -= 1900; /* convert from 4 digit year */
+ else if (year < 100) {
+ /* convert from 2 digit year */
+ struct tm *lt;
+ time_t now;
- /*
- * check if the specified year is in the next century.
- * allow for one year of user error as many people will
- * enter n - 1 at the start of year n.
- */
- if (year < (lt->tm_year % 100) - 1)
- year += 100;
- /* adjust for the year 2000 and beyond */
- year += lt->tm_year - (lt->tm_year % 100);
+ time(&now);
+ lt = localtime(&now);
+
+ /* Convert to tm_year assuming current century */
+ year += (lt->tm_year / 100) * 100;
+
+ if (year == lt->tm_year - 1) year++;
+ else if (year < lt->tm_year)
+ year += 100; /* must be in next century */
+ }
}
if (year < 0 &&
On Fri, 21 Jan 2000 10:28:10 +0500, "Sergey N. Voronkov" wrote:
> It's another way to do this right. I'v adapted OpenBSD Team patch.
> And, Mr. Sheldon, can you, please, make one of two changes in STABLE
> branch ?
Hi Sergey,
I'm sorry I've taken so long to get back to you on this one. Work
pressure picked up unexpectedly.
It looks like this one will have to wait 'til after 4.0-RELEASE.
Apologies,
Sheldon.
Responsible Changed From-To: freebsd-bugs->sheldonh Reminder for me to tackle this after 4.0-RELEASE if nobody else has done so by then. State Changed From-To: open->analyzed Committed in rev 1.20 of src/usr.bin/at/parsetime.c . We'll give it some time in HEAD before merging onto RELENG_4 and RELENG_3 branches. Thanks! State Changed From-To: analyzed->closed Merged onto RELENG_4 branch in rev 1.19.2.1 of parsetime.c and onto RELENG_3 branch in rev 1.16.2.2, both on Fri Apr 14 2000. |
There is a Y2k bug in at(1). The following portion of code can cause valid time specifications to return 'garbled time' errors, /* * assign_date() assigns a date, wrapping to next year if needed */ static void assign_date(struct tm *tm, long mday, long mon, long year) { if (year > 99) { if (year > 1899) year -= 1900; else panic("garbled time"); } ... When this function is passed the current year in tm_year format, 100, it will complain it is a garbled time. However, it is a legal value. Fix: The parsetime.c code, which is excerpted above, is a _very_ complex piece of work. I hesitate to write a patch to fix this small problem since it might create greater ones. I leave it to someone with more familiarity with the code. (However, I am not sure why the 'year > 99' check is needed at all.) In the mean time, the previous command line can will work if you phrase it, % at 10:30 + 2 days You may need to try other convoluted constructions to work around other formats that might trigger the bug. How-To-Repeat: Try to queue an atjob in the following manner, % at 10:30am wed at: garbled time However, that is a legal command line.