Jim Meyering wrote: > Documenting in getdate.texi will be enough, because that file is > included by coreutils.texi. Thanks!
Ok, here is amended version of the patch, first two (or less) digits are
considered as hours, TZ correction limit set to +/-24:00, both changes
in behaviour documented in getdate.texi.
Greetings,
Ondrej
From cf9655b40b3850e0d848490674949997f5b9402f Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ond=C5=99ej=20Va=C5=A1=C3=ADk?= <[EMAIL PROTECTED]>
Date: Fri, 25 Jul 2008 15:29:40 +0200
Subject: [PATCH] getdate.y: add limits for TZ, handle TZ +HH format correctly
* doc/getdate.texi: Document new behaviour and limits of time zone
correction
* lib/getdate.y (time_zone_hh_mm): Allow only TZ in the range
UTC-24 to UTC+24 hours, consider first two digits of TZ as hours
when no minutes specified. Invalid TZ will cause invalid date format
error.
* tests/test-getdate.c: Tests for that change
---
ChangeLog | 8 ++++++
doc/getdate.texi | 10 ++++---
lib/getdate.y | 34 ++++++++++++++++++++------
tests/test-getdate.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 103 insertions(+), 12 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 6c48308..b19680f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-07-25 Ondřej Vašík <[EMAIL PROTECTED]>
+
+ getdate.y: Allow only timezone range specified by POSIX
+ * lib/getdate.y (time_zone_hhmm): Allow only TZ in the range
+ -24 to +24 hours, consider first two digits as hours. Invalid TZ
+ should cause invalid format error.
+ * tests/test-getdate.c: Tests for the fix
+
2008-07-23 Ulrich Drepper <[EMAIL PROTECTED]>
mktime.c: normalize tp->tm_isdst value to -1/0/1.
diff --git a/doc/getdate.texi b/doc/getdate.texi
index eae4526..687d187 100644
--- a/doc/getdate.texi
+++ b/doc/getdate.texi
@@ -271,10 +271,12 @@ forces interpretation of the time relative to
Coordinated Universal Time (@sc{utc}), overriding any previous
specification for the time zone or the local time zone. For example,
@samp{+0530} and @samp{+05:30} both stand for the time zone 5.5 hours
-ahead of @sc{utc} (e.g., India). The @var{minute}
-part of the time of day may not be elided when a time zone correction
-is used. This is the best way to specify a time zone correction by
-fractional parts of an hour.
+ahead of @sc{utc} (e.g., India). Only time zone correction between -24:00
+and +24:00 from basic UTC0 time zone is accepted. Time zones outside of this
+range are considered as invalid. If you specify only two or less digits, they
+are interpreted as hours. The @var{minute} part of the time of day may not
+be elided when a time zone correction is used. This is the best way to
+specify a time zone correction by fractional parts of an hour.
Either @samp{am}/@samp{pm} or a time zone correction may be specified,
but not both.
diff --git a/lib/getdate.y b/lib/getdate.y
index 695fd59..9fe2181 100644
--- a/lib/getdate.y
+++ b/lib/getdate.y
@@ -205,7 +205,7 @@ typedef struct
union YYSTYPE;
static int yylex (union YYSTYPE *, parser_control *);
static int yyerror (parser_control const *, char const *);
-static long int time_zone_hhmm (textint, long int);
+static long int time_zone_hhmm (parser_control *, textint, long int);
/* Extract into *PC any date and time info from a string of digits
of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY,
@@ -358,7 +358,7 @@ time:
set_hhmmss (pc, $1.value, $3.value, 0, 0);
pc->meridian = MER24;
pc->zones_seen++;
- pc->time_zone = time_zone_hhmm ($4, $5);
+ pc->time_zone = time_zone_hhmm (pc, $4, $5);
}
| tUNUMBER ':' tUNUMBER ':' unsigned_seconds o_merid
{
@@ -370,7 +370,7 @@ time:
set_hhmmss (pc, $1.value, $3.value, $5.tv_sec, $5.tv_nsec);
pc->meridian = MER24;
pc->zones_seen++;
- pc->time_zone = time_zone_hhmm ($6, $7);
+ pc->time_zone = time_zone_hhmm (pc, $6, $7);
}
;
@@ -394,7 +394,7 @@ zone:
{ pc->time_zone = $1;
apply_relative_time (pc, $2, 1); }
| tZONE tSNUMBER o_colon_minutes
- { pc->time_zone = $1 + time_zone_hhmm ($2, $3); }
+ { pc->time_zone = $1 + time_zone_hhmm (pc, $2, $3); }
| tDAYZONE
{ pc->time_zone = $1 + 60; }
| tZONE tDST
@@ -795,15 +795,33 @@ static table const military_table[] =
/* Convert a time zone expressed as HH:MM into an integer count of
minutes. If MM is negative, then S is of the form HHMM and needs
- to be picked apart; otherwise, S is of the form HH. */
+ to be picked apart; otherwise, S is of the form HH. As specified at
+ http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html
+ allow only valid TZ range, consider first two digits as hours, if no
+ minutes specified */
static long int
-time_zone_hhmm (textint s, long int mm)
+time_zone_hhmm (parser_control *pc, textint s, long int mm)
{
+ long int returnvalue;
+
+ /* if 's' length is two or less, consider it as hours when no
+ minutes specified */
+ if ((s.digits <= 2) && (mm < 0))
+ s.value *= 100;
+
if (mm < 0)
- return (s.value / 100) * 60 + s.value % 100;
+ returnvalue = (s.value / 100) * 60 + s.value % 100;
else
- return s.value * 60 + (s.negative ? -mm : mm);
+ returnvalue = s.value * 60 + (s.negative ? -mm : mm);
+
+ /* check if the return value is in real timezone range,
+ otherwise increment pc->zones_seen to cause time format
+ error, allow UTC-24:00 to UTC+24:00 */
+ if (abs (returnvalue) > 1440)
+ pc->zones_seen++;
+
+ return returnvalue;
}
static int
diff --git a/tests/test-getdate.c b/tests/test-getdate.c
index 901adf9..80cf573 100644
--- a/tests/test-getdate.c
+++ b/tests/test-getdate.c
@@ -53,6 +53,7 @@ main (int argc, char **argv)
struct timespec result;
struct timespec result2;
struct timespec now;
+ int i;
const char *p;
now.tv_sec = 4711;
@@ -98,5 +99,67 @@ main (int argc, char **argv)
ASSERT (result.tv_sec == result2.tv_sec
&& result.tv_nsec == result2.tv_nsec);
+ /* test if several time zones formats are handled same way */
+ now.tv_sec = 4711;
+ now.tv_nsec = 1267;
+ p = "UTC+14:00";
+ ASSERT (get_date (&result, p, &now));
+ LOG (p, now, result);
+ p = "UTC+14";
+ ASSERT (get_date (&result2, p, &now));
+ LOG (p, now, result2);
+ ASSERT (result.tv_sec == result2.tv_sec
+ && result.tv_nsec == result2.tv_nsec);
+ p = "UTC+1400";
+ ASSERT (get_date (&result2, p, &now));
+ LOG (p, now, result2);
+ ASSERT (result.tv_sec == result2.tv_sec
+ && result.tv_nsec == result2.tv_nsec);
+
+ now.tv_sec = 4711;
+ now.tv_nsec = 1267;
+ p = "UTC-14:00";
+ ASSERT (get_date (&result, p, &now));
+ LOG (p, now, result);
+ p = "UTC-14";
+ ASSERT (get_date (&result2, p, &now));
+ LOG (p, now, result2);
+ ASSERT (result.tv_sec == result2.tv_sec
+ && result.tv_nsec == result2.tv_nsec);
+ p = "UTC-1400";
+ ASSERT (get_date (&result2, p, &now));
+ LOG (p, now, result2);
+ ASSERT (result.tv_sec == result2.tv_sec
+ && result.tv_nsec == result2.tv_nsec);
+
+ now.tv_sec = 4711;
+ now.tv_nsec = 1267;
+ p = "UTC+0:15";
+ ASSERT (get_date (&result, p, &now));
+ LOG (p, now, result);
+ p = "UTC+0015";
+ ASSERT (get_date (&result2, p, &now));
+ LOG (p, now, result2);
+ ASSERT (result.tv_sec == result2.tv_sec
+ && result.tv_nsec == result2.tv_nsec);
+
+ now.tv_sec = 4711;
+ now.tv_nsec = 1267;
+ p = "UTC-1:30";
+ ASSERT (get_date (&result, p, &now));
+ LOG (p, now, result);
+ p = "UTC-130";
+ ASSERT (get_date (&result2, p, &now));
+ LOG (p, now, result2);
+ ASSERT (result.tv_sec == result2.tv_sec
+ && result.tv_nsec == result2.tv_nsec);
+
+
+ /* TZ out of range should cause get_date failure */
+ now.tv_sec = 4711;
+ now.tv_nsec = 1267;
+ p = "UTC+25:00";
+ ASSERT (!get_date (&result, p, &now));
+
return 0;
}
--
1.5.6.1.156.ge903b
signature.asc
Description: Toto je digitálně podepsaná část zprávy
_______________________________________________ Bug-coreutils mailing list [email protected] http://lists.gnu.org/mailman/listinfo/bug-coreutils
