@@ -42,7 +42,7 @@ static int DecodeTimezone(char *str, int *tzp);
4242static const datetkn * datebsearch (const char * key , const datetkn * base , int nel );
4343static int DecodeDate (char * str , int fmask , int * tmask , bool * is2digits ,
4444 struct pg_tm * tm );
45- static int ValidateDate (int fmask , bool is2digits , bool bc ,
45+ static int ValidateDate (int fmask , bool isjulian , bool is2digits , bool bc ,
4646 struct pg_tm * tm );
4747static void TrimTrailingZeros (char * str );
4848static void AppendSeconds (char * cp , int sec , fsec_t fsec ,
@@ -795,6 +795,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
795795 int dterr ;
796796 int mer = HR24 ;
797797 bool haveTextMonth = FALSE;
798+ bool isjulian = FALSE;
798799 bool is2digits = FALSE;
799800 bool bc = FALSE;
800801 pg_tz * namedTz = NULL ;
@@ -833,10 +834,12 @@ DecodeDateTime(char **field, int *ftype, int nf,
833834
834835 errno = 0 ;
835836 val = strtoi (field [i ], & cp , 10 );
836- if (errno == ERANGE )
837+ if (errno == ERANGE || val < 0 )
837838 return DTERR_FIELD_OVERFLOW ;
838839
839840 j2date (val , & tm -> tm_year , & tm -> tm_mon , & tm -> tm_mday );
841+ isjulian = TRUE;
842+
840843 /* Get the time zone from the end of the string */
841844 dterr = DecodeTimezone (cp , tzp );
842845 if (dterr )
@@ -1065,11 +1068,13 @@ DecodeDateTime(char **field, int *ftype, int nf,
10651068 break ;
10661069
10671070 case DTK_JULIAN :
1068- /***
1069- * previous field was a label for "julian date"?
1070- ***/
1071+ /* previous field was a label for "julian date" */
1072+ if ( val < 0 )
1073+ return DTERR_FIELD_OVERFLOW ;
10711074 tmask = DTK_DATE_M ;
10721075 j2date (val , & tm -> tm_year , & tm -> tm_mon , & tm -> tm_mday );
1076+ isjulian = TRUE;
1077+
10731078 /* fractional Julian Day? */
10741079 if (* cp == '.' )
10751080 {
@@ -1361,7 +1366,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
13611366 } /* end loop over fields */
13621367
13631368 /* do final checking/adjustment of Y/M/D fields */
1364- dterr = ValidateDate (fmask , is2digits , bc , tm );
1369+ dterr = ValidateDate (fmask , isjulian , is2digits , bc , tm );
13651370 if (dterr )
13661371 return dterr ;
13671372
@@ -1564,6 +1569,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
15641569 int i ;
15651570 int val ;
15661571 int dterr ;
1572+ bool isjulian = FALSE;
15671573 bool is2digits = FALSE;
15681574 bool bc = FALSE;
15691575 int mer = HR24 ;
@@ -1795,11 +1801,13 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
17951801 break ;
17961802
17971803 case DTK_JULIAN :
1798- /***
1799- * previous field was a label for "julian date"?
1800- ***/
1804+ /* previous field was a label for "julian date" */
1805+ if ( val < 0 )
1806+ return DTERR_FIELD_OVERFLOW ;
18011807 tmask = DTK_DATE_M ;
18021808 j2date (val , & tm -> tm_year , & tm -> tm_mon , & tm -> tm_mday );
1809+ isjulian = TRUE;
1810+
18031811 if (* cp == '.' )
18041812 {
18051813 double time ;
@@ -2045,7 +2053,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
20452053 } /* end loop over fields */
20462054
20472055 /* do final checking/adjustment of Y/M/D fields */
2048- dterr = ValidateDate (fmask , is2digits , bc , tm );
2056+ dterr = ValidateDate (fmask , isjulian , is2digits , bc , tm );
20492057 if (dterr )
20502058 return dterr ;
20512059
@@ -2247,11 +2255,16 @@ DecodeDate(char *str, int fmask, int *tmask, bool *is2digits,
22472255 * Return 0 if okay, a DTERR code if not.
22482256 */
22492257static int
2250- ValidateDate (int fmask , bool is2digits , bool bc , struct pg_tm * tm )
2258+ ValidateDate (int fmask , bool isjulian , bool is2digits , bool bc ,
2259+ struct pg_tm * tm )
22512260{
22522261 if (fmask & DTK_M (YEAR ))
22532262 {
2254- if (bc )
2263+ if (isjulian )
2264+ {
2265+ /* tm_year is correct and should not be touched */
2266+ }
2267+ else if (bc )
22552268 {
22562269 /* there is no year zero in AD/BC notation */
22572270 if (tm -> tm_year <= 0 )
0 commit comments