Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb2b3d5d

Browse files
author
Thomas G. Lockhart
committed
Fix code to check legal dates *before* calling localtime() to get the
time zone.Previously, localtime() rotated a date with a day of month field which exceeded the actual range into the next months, masking the fact that a bad date had been specified.Regression tests pass.
1 parent64e74e3 commitb2b3d5d

File tree

2 files changed

+43
-123
lines changed

2 files changed

+43
-123
lines changed

‎src/backend/utils/adt/datetime.c

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.30 1999/03/14 16:40:15 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.31 1999/04/15 02:22:37 thomas Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -27,19 +27,6 @@
2727

2828
staticintdate2tm(DateADTdateVal,int*tzp,structtm*tm,double*fsec,char**tzn);
2929

30-
#defineUTIME_MINYEAR (1901)
31-
#defineUTIME_MINMONTH (12)
32-
#defineUTIME_MINDAY (14)
33-
#defineUTIME_MAXYEAR (2038)
34-
#defineUTIME_MAXMONTH (01)
35-
#defineUTIME_MAXDAY (18)
36-
37-
#defineIS_VALID_UTIME(y,m,d) (((y > UTIME_MINYEAR) \
38-
|| ((y == UTIME_MINYEAR) && ((m > UTIME_MINMONTH) \
39-
|| ((m == UTIME_MINMONTH) && (d >= UTIME_MINDAY))))) \
40-
&& ((y < UTIME_MAXYEAR) \
41-
|| ((y == UTIME_MAXYEAR) && ((m < UTIME_MAXMONTH) \
42-
|| ((m == UTIME_MAXMONTH) && (d <= UTIME_MAXDAY))))))
4330

4431
/*****************************************************************************
4532
* Date ADT
@@ -71,7 +58,7 @@ date_in(char *str)
7158
#endif
7259
if ((ParseDateTime(str,lowstr,field,ftype,MAXDATEFIELDS,&nf)!=0)
7360
|| (DecodeDateTime(field,ftype,nf,&dtype,tm,&fsec,&tzp)!=0))
74-
elog(ERROR,"Bad date external representation%s",str);
61+
elog(ERROR,"Bad date external representation'%s'",str);
7562

7663
switch (dtype)
7764
{
@@ -89,19 +76,9 @@ date_in(char *str)
8976
break;
9077

9178
default:
92-
elog(ERROR,"Unrecognized date external representation%s",str);
79+
elog(ERROR,"Unrecognized date external representation'%s'",str);
9380
}
9481

95-
#ifdefNOT_USED
96-
if (tm->tm_year<0||tm->tm_year>32767)
97-
elog(ERROR,"date_in: year must be limited to values 0 through 32767 in '%s'",str);
98-
if (tm->tm_mon<1||tm->tm_mon>12)
99-
elog(ERROR,"date_in: month must be limited to values 1 through 12 in '%s'",str);
100-
#endif
101-
if (tm->tm_mday<1||tm->tm_mday>day_tab[isleap(tm->tm_year)][tm->tm_mon-1])
102-
elog(ERROR,"date_in: day must be limited to values 1 through %d in '%s'",
103-
day_tab[isleap(tm->tm_year)][tm->tm_mon-1],str);
104-
10582
date= (date2j(tm->tm_year,tm->tm_mon,tm->tm_mday)-date2j(2000,1,1));
10683

10784
returndate;
@@ -453,13 +430,6 @@ time_in(char *str)
453430
|| (DecodeTimeOnly(field,ftype,nf,&dtype,tm,&fsec)!=0))
454431
elog(ERROR,"Bad time external representation '%s'",str);
455432

456-
if ((tm->tm_hour<0)|| (tm->tm_hour>23))
457-
elog(ERROR,"Hour must be limited to values 0 through 23 in '%s'",str);
458-
if ((tm->tm_min<0)|| (tm->tm_min>59))
459-
elog(ERROR,"Minute must be limited to values 0 through 59 in '%s'",str);
460-
if ((tm->tm_sec<0)|| ((tm->tm_sec+fsec) >=60))
461-
elog(ERROR,"Second must be limited to values 0 through < 60 in '%s'",str);
462-
463433
time=palloc(sizeof(TimeADT));
464434

465435
*time= ((((tm->tm_hour*60)+tm->tm_min)*60)+tm->tm_sec+fsec);

‎src/backend/utils/adt/dt.c

Lines changed: 40 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.67 1999/03/20 02:31:45 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/dt.c,v 1.68 1999/04/15 02:22:39 thomas Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -55,12 +55,6 @@ static inttm2timespan(struct tm * tm, double fsec, TimeSpan *span);
5555
#defineUSE_DATE_CACHE 1
5656
#defineROUND_ALL 0
5757

58-
#if0
59-
#defineisleap(y) (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
60-
61-
intmdays[]= {31,28,31,30,31,30,31,31,30,31,30,31,0};
62-
#endif
63-
6458
intday_tab[2][13]= {
6559
{31,28,31,30,31,30,31,31,30,31,30,31,0},
6660
{31,29,31,30,31,30,31,31,30,31,30,31,0}};
@@ -882,15 +876,6 @@ datetime_pl_span(DateTime *datetime, TimeSpan *span)
882876
}
883877

884878
/* adjust for end of month boundary problems... */
885-
#if0
886-
if (tm->tm_mday>mdays[tm->tm_mon-1])
887-
{
888-
if ((tm->tm_mon==2)&&isleap(tm->tm_year))
889-
tm->tm_mday= (mdays[tm->tm_mon-1]+1);
890-
else
891-
tm->tm_mday=mdays[tm->tm_mon-1];
892-
}
893-
#endif
894879
if (tm->tm_mday>day_tab[isleap(tm->tm_year)][tm->tm_mon-1])
895880
tm->tm_mday= (day_tab[isleap(tm->tm_year)][tm->tm_mon-1]);
896881

@@ -1197,21 +1182,11 @@ datetime_age(DateTime *datetime1, DateTime *datetime2)
11971182
{
11981183
if (dt1<dt2)
11991184
{
1200-
#if0
1201-
tm->tm_mday+=mdays[tm1->tm_mon-1];
1202-
if (isleap(tm1->tm_year)&& (tm1->tm_mon==2))
1203-
tm->tm_mday++;
1204-
#endif
12051185
tm->tm_mday+=day_tab[isleap(tm1->tm_year)][tm1->tm_mon-1];
12061186
tm->tm_mon--;
12071187
}
12081188
else
12091189
{
1210-
#if0
1211-
tm->tm_mday+=mdays[tm2->tm_mon-1];
1212-
if (isleap(tm2->tm_year)&& (tm2->tm_mon==2))
1213-
tm->tm_mday++;
1214-
#endif
12151190
tm->tm_mday+=day_tab[isleap(tm2->tm_year)][tm2->tm_mon-1];
12161191
tm->tm_mon--;
12171192
}
@@ -2302,21 +2277,6 @@ datetkn *deltacache[MAXDATEFIELDS] = {NULL};
23022277
* These routines will be used by other date/time packages - tgl 97/02/25
23032278
*/
23042279

2305-
#if0
2306-
XXXmovedtodt.h-thomas1999-01-15
2307-
/* Set the minimum year to one greater than the year of the first valid day
2308-
*to avoid having to check year and day both. - tgl 97/05/08
2309-
*/
2310-
2311-
#defineJULIAN_MINYEAR (-4713)
2312-
#defineJULIAN_MINMONTH (11)
2313-
#defineJULIAN_MINDAY (23)
2314-
2315-
#defineIS_VALID_JULIAN(y,m,d) ((y > JULIAN_MINYEAR) \
2316-
|| ((y == JULIAN_MINYEAR) && ((m > JULIAN_MINMONTH) \
2317-
|| ((m == JULIAN_MINMONTH) && (d >= JULIAN_MINDAY)))))
2318-
#endif
2319-
23202280
int
23212281
date2j(inty,intm,intd)
23222282
{
@@ -3063,47 +3023,55 @@ DecodeDateTime(char **field, int *ftype, int nf,
30633023
printf(" %02d:%02d:%02d\n",tm->tm_hour,tm->tm_min,tm->tm_sec);
30643024
#endif
30653025

3066-
if ((*dtype==DTK_DATE)&& ((fmask&DTK_DATE_M)!=DTK_DATE_M))
3067-
return ((fmask&DTK_TIME_M)==DTK_TIME_M) ?1 :-1;
3068-
3069-
/* timezone not specified? then find local timezone if possible */
3070-
if ((*dtype==DTK_DATE)&& ((fmask&DTK_DATE_M)==DTK_DATE_M)
3071-
&& (tzp!=NULL)&& (!(fmask&DTK_M(TZ))))
3026+
/* do additional checking for full date specs... */
3027+
if (*dtype==DTK_DATE)
30723028
{
3029+
if ((fmask&DTK_DATE_M)!=DTK_DATE_M)
3030+
return ((fmask&DTK_TIME_M)==DTK_TIME_M) ?1 :-1;
30733031

3074-
/*
3075-
* daylight savings time modifier but no standard timezone? then
3076-
* error
3077-
*/
3078-
if (fmask&DTK_M(DTZMOD))
3032+
/* check for valid day of month, now that we know for sure the month and year... */
3033+
if ((tm->tm_mday<1)
3034+
|| (tm->tm_mday>day_tab[isleap(tm->tm_year)][tm->tm_mon-1]))
30793035
return-1;
30803036

3081-
if (IS_VALID_UTIME(tm->tm_year,tm->tm_mon,tm->tm_mday))
3037+
/* timezone not specified? then find local timezone if possible */
3038+
if (((fmask&DTK_DATE_M)==DTK_DATE_M)
3039+
&& (tzp!=NULL)&& (!(fmask&DTK_M(TZ))))
30823040
{
3041+
/*
3042+
* daylight savings time modifier but no standard timezone? then
3043+
* error
3044+
*/
3045+
if (fmask&DTK_M(DTZMOD))
3046+
return-1;
3047+
3048+
if (IS_VALID_UTIME(tm->tm_year,tm->tm_mon,tm->tm_mday))
3049+
{
30833050
#ifdefUSE_POSIX_TIME
3084-
tm->tm_year-=1900;
3085-
tm->tm_mon-=1;
3086-
tm->tm_isdst=-1;
3087-
mktime(tm);
3088-
tm->tm_year+=1900;
3089-
tm->tm_mon+=1;
3051+
tm->tm_year-=1900;
3052+
tm->tm_mon-=1;
3053+
tm->tm_isdst=-1;
3054+
mktime(tm);
3055+
tm->tm_year+=1900;
3056+
tm->tm_mon+=1;
30903057

30913058
#if defined(HAVE_TM_ZONE)
3092-
*tzp=-(tm->tm_gmtoff);/* tm_gmtoff is Sun/DEC-ism */
3059+
*tzp=-(tm->tm_gmtoff);/* tm_gmtoff is Sun/DEC-ism */
30933060
#elif defined(HAVE_INT_TIMEZONE)
3094-
*tzp= ((tm->tm_isdst>0) ? (timezone-3600) :timezone);
3061+
*tzp= ((tm->tm_isdst>0) ? (timezone-3600) :timezone);
30953062
#else
30963063
#error USE_POSIX_TIME is defined but neither HAVE_TM_ZONE or HAVE_INT_TIMEZONE are defined
30973064
#endif
30983065

30993066
#else/* !USE_POSIX_TIME */
3100-
*tzp=CTimeZone;
3067+
*tzp=CTimeZone;
31013068
#endif
3102-
}
3103-
else
3104-
{
3105-
tm->tm_isdst=0;
3106-
*tzp=0;
3069+
}
3070+
else
3071+
{
3072+
tm->tm_isdst=0;
3073+
*tzp=0;
3074+
}
31073075
}
31083076
}
31093077

@@ -3231,6 +3199,11 @@ DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct tm * tm, dou
32313199
elseif ((mer==PM)&& (tm->tm_hour!=12))
32323200
tm->tm_hour+=12;
32333201

3202+
if (((tm->tm_hour<0)|| (tm->tm_hour>23))
3203+
|| ((tm->tm_min<0)|| (tm->tm_min>59))
3204+
|| ((tm->tm_sec<0)|| ((tm->tm_sec+*fsec) >=60)))
3205+
return-1;
3206+
32343207
if ((fmask&DTK_TIME_M)!=DTK_TIME_M)
32353208
return-1;
32363209

@@ -3541,15 +3514,6 @@ DecodeNumber(int flen, char *str, int fmask,
35413514
tm->tm_year=val;
35423515

35433516
/* adjust ONLY if exactly two digits... */
3544-
#if0
3545-
if (flen==2)
3546-
{
3547-
if (tm->tm_year<70)
3548-
tm->tm_year+=2000;
3549-
elseif (tm->tm_year<100)
3550-
tm->tm_year+=1900;
3551-
}
3552-
#endif
35533517
*is2digits= (flen==2);
35543518

35553519
}
@@ -3615,13 +3579,6 @@ DecodeNumberField(int len, char *str, int fmask,
36153579
tm->tm_mon=atoi(str+2);
36163580
*(str+2)='\0';
36173581
tm->tm_year=atoi(str+0);
3618-
3619-
#if0
3620-
if (tm->tm_year<70)
3621-
tm->tm_year+=2000;
3622-
elseif (tm->tm_year<100)
3623-
tm->tm_year+=1900;
3624-
#endif
36253582
*is2digits= TRUE;
36263583
}
36273584

@@ -3636,13 +3593,6 @@ DecodeNumberField(int len, char *str, int fmask,
36363593
*(str+2)='\0';
36373594
tm->tm_mon=1;
36383595
tm->tm_year=atoi(str+0);
3639-
3640-
#if0
3641-
if (tm->tm_year<70)
3642-
tm->tm_year+=2000;
3643-
elseif (tm->tm_year<100)
3644-
tm->tm_year+=1900;
3645-
#endif
36463596
*is2digits= TRUE;
36473597
}
36483598
elseif (strchr(str,'.')!=NULL)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp