1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Further changes to the date/time functions to suppress harmless signed

integer overflow warnings that could have occurred when doing out-of-range
date calculations which, according to the docs, give undefined results.

FossilOrigin-Name: dc453b3403450b1d8cc53daf0721fed025b9053c
This commit is contained in:
drh
2016-11-30 00:48:28 +00:00
parent 3edb157e23
commit d76a902c87
4 changed files with 89 additions and 29 deletions

View File

@@ -65,17 +65,17 @@ struct tm *__cdecl localtime(const time_t *);
*/
typedef struct DateTime DateTime;
struct DateTime {
sqlite3_int64 iJD; /* The julian day number times 86400000 */
int Y, M, D; /* Year, month, and day */
int h, m; /* Hour and minutes */
int tz; /* Timezone offset in minutes */
double s; /* Seconds */
char validYMD; /* True (1) if Y,M,D are valid */
char validHMS; /* True (1) if h,m,s are valid */
char validJD; /* True (1) if iJD is valid */
char validTZ; /* True (1) if tz is valid */
char tzSet; /* Timezone was set explicitly */
char isError; /* An overflow has occurred */
sqlite3_uint64 iJD; /* The julian day number times 86400000 */
int Y, M, D; /* Year, month, and day */
int h, m; /* Hour and minutes */
int tz; /* Timezone offset in minutes */
double s; /* Seconds */
char validYMD; /* True (1) if Y,M,D are valid */
char validHMS; /* True (1) if h,m,s are valid */
char validJD; /* True (1) if iJD is valid */
char validTZ; /* True (1) if tz is valid */
char tzSet; /* Timezone was set explicitly */
char isError; /* An overflow has occurred */
};
@@ -232,6 +232,14 @@ static int parseHhMmSs(const char *zDate, DateTime *p){
return 0;
}
/*
** Put the DateTime object into its error state.
*/
static void datetimeError(DateTime *p){
memset(p, 0, sizeof(*p));
p->isError = 1;
}
/*
** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume
** that the YYYY-MM-DD is according to the Gregorian calendar.
@@ -251,6 +259,10 @@ static void computeJD(DateTime *p){
M = 1;
D = 1;
}
if( Y<-4713 || Y>9999 ){
datetimeError(p);
return;
}
if( M<=2 ){
Y--;
M += 12;
@@ -373,7 +385,7 @@ static int parseDateOrTime(
** The input is the JulianDay times 86400000.
*/
static int validJulianDay(sqlite3_int64 iJD){
return iJD>=148699540800000 && iJD<=464269060799999;
return iJD>=0 && iJD<=464269060799999;
}
/*
@@ -387,8 +399,7 @@ static void computeYMD(DateTime *p){
p->M = 1;
p->D = 1;
}else if( !validJulianDay(p->iJD) ){
memset(p, 0, sizeof(*p));
p->isError = 1;
datetimeError(p);
return;
}else{
Z = (int)((p->iJD + 43200000)/86400000);
@@ -713,6 +724,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
case '8':
case '9': {
double rRounder;
double rAbs;
for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
rc = 1;
@@ -749,15 +761,16 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
computeJD(p);
rc = 0;
rRounder = r<0 ? -0.5 : +0.5;
if( n==3 && strcmp(z,"day")==0 ){
rAbs = r<0 ? -r : r;
if( n==3 && strcmp(z,"day")==0 && rAbs<5373485.0 ){
p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
}else if( n==4 && strcmp(z,"hour")==0 ){
}else if( n==4 && strcmp(z,"hour")==0 && rAbs<128963628.0 ){
p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
}else if( n==6 && strcmp(z,"minute")==0 ){
}else if( n==6 && strcmp(z,"minute")==0 && rAbs<7737817680.0 ){
p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
}else if( n==6 && strcmp(z,"second")==0 ){
}else if( n==6 && strcmp(z,"second")==0 && rAbs<464269060800.0 ){
p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
}else if( n==5 && strcmp(z,"month")==0 ){
}else if( n==5 && strcmp(z,"month")==0 && rAbs<176546.0 ){
int x, y;
computeYMD_HMS(p);
p->M += (int)r;
@@ -770,7 +783,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
if( y!=r ){
p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
}
}else if( n==4 && strcmp(z,"year")==0 ){
}else if( n==4 && strcmp(z,"year")==0 && rAbs<14713.0 ){
int y = (int)r;
computeYMD_HMS(p);
p->Y += y;