@@ -42,7 +42,7 @@ static int DecodeTimezone(char *str, int *tzp);
42
42
static const datetkn * datebsearch (const char * key , const datetkn * base , int nel );
43
43
static int DecodeDate (char * str , int fmask , int * tmask , bool * is2digits ,
44
44
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 ,
46
46
struct pg_tm * tm );
47
47
static void TrimTrailingZeros (char * str );
48
48
static void AppendSeconds (char * cp , int sec , fsec_t fsec ,
@@ -795,6 +795,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
795
795
int dterr ;
796
796
int mer = HR24 ;
797
797
bool haveTextMonth = FALSE;
798
+ bool isjulian = FALSE;
798
799
bool is2digits = FALSE;
799
800
bool bc = FALSE;
800
801
pg_tz * namedTz = NULL ;
@@ -833,10 +834,12 @@ DecodeDateTime(char **field, int *ftype, int nf,
833
834
834
835
errno = 0 ;
835
836
val = strtoi (field [i ], & cp , 10 );
836
- if (errno == ERANGE )
837
+ if (errno == ERANGE || val < 0 )
837
838
return DTERR_FIELD_OVERFLOW ;
838
839
839
840
j2date (val , & tm -> tm_year , & tm -> tm_mon , & tm -> tm_mday );
841
+ isjulian = TRUE;
842
+
840
843
/* Get the time zone from the end of the string */
841
844
dterr = DecodeTimezone (cp , tzp );
842
845
if (dterr )
@@ -1065,11 +1068,13 @@ DecodeDateTime(char **field, int *ftype, int nf,
1065
1068
break ;
1066
1069
1067
1070
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 ;
1071
1074
tmask = DTK_DATE_M ;
1072
1075
j2date (val , & tm -> tm_year , & tm -> tm_mon , & tm -> tm_mday );
1076
+ isjulian = TRUE;
1077
+
1073
1078
/* fractional Julian Day? */
1074
1079
if (* cp == '.' )
1075
1080
{
@@ -1361,7 +1366,7 @@ DecodeDateTime(char **field, int *ftype, int nf,
1361
1366
} /* end loop over fields */
1362
1367
1363
1368
/* do final checking/adjustment of Y/M/D fields */
1364
- dterr = ValidateDate (fmask , is2digits , bc , tm );
1369
+ dterr = ValidateDate (fmask , isjulian , is2digits , bc , tm );
1365
1370
if (dterr )
1366
1371
return dterr ;
1367
1372
@@ -1564,6 +1569,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
1564
1569
int i ;
1565
1570
int val ;
1566
1571
int dterr ;
1572
+ bool isjulian = FALSE;
1567
1573
bool is2digits = FALSE;
1568
1574
bool bc = FALSE;
1569
1575
int mer = HR24 ;
@@ -1795,11 +1801,13 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
1795
1801
break ;
1796
1802
1797
1803
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 ;
1801
1807
tmask = DTK_DATE_M ;
1802
1808
j2date (val , & tm -> tm_year , & tm -> tm_mon , & tm -> tm_mday );
1809
+ isjulian = TRUE;
1810
+
1803
1811
if (* cp == '.' )
1804
1812
{
1805
1813
double time ;
@@ -2045,7 +2053,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf,
2045
2053
} /* end loop over fields */
2046
2054
2047
2055
/* do final checking/adjustment of Y/M/D fields */
2048
- dterr = ValidateDate (fmask , is2digits , bc , tm );
2056
+ dterr = ValidateDate (fmask , isjulian , is2digits , bc , tm );
2049
2057
if (dterr )
2050
2058
return dterr ;
2051
2059
@@ -2247,11 +2255,16 @@ DecodeDate(char *str, int fmask, int *tmask, bool *is2digits,
2247
2255
* Return 0 if okay, a DTERR code if not.
2248
2256
*/
2249
2257
static 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 )
2251
2260
{
2252
2261
if (fmask & DTK_M (YEAR ))
2253
2262
{
2254
- if (bc )
2263
+ if (isjulian )
2264
+ {
2265
+ /* tm_year is correct and should not be touched */
2266
+ }
2267
+ else if (bc )
2255
2268
{
2256
2269
/* there is no year zero in AD/BC notation */
2257
2270
if (tm -> tm_year <= 0 )
0 commit comments