-C Version\s3.7.6.3\srelease\scandidate\s1.
-D 2011-05-19T13:26:54.226
+C Backport\sthe\slocaltime()\sfailure\sfix\sof\sticket\s[bd484a090c8077]\sto\sthe\n3.7.6\sbranch.
+D 2011-06-21T15:15:16.412
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4
-F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b
+F src/date.c 8eb16dd5c0fea761f65f1ed98b2c2e8fbaea800c
F src/delete.c 7a24fcc9a31664d145acb97ce56b6d9f249a25e4
F src/expr.c e3cf0957c6b8faaaf7386a3bc69e53c0dc9705be
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85
-F src/main.c a8571665d43ff18f89a49d47a281605ce5ea825e
+F src/main.c a3a968b6b0405a849c855451eb825f597cc2a43f
F src/malloc.c 788f2ed928786dfe305b6783d551d6b1a9080976
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
F src/select.c 649a6f10f7eb7b52a5a28847773cb9968a828ae8
F src/shell.c 72e7e176bf46d5c6518d15ac4ad6847c4bb5df79
-F src/sqlite.h.in 4d28db70c37a1b17942820308eb59f211140da43
+F src/sqlite.h.in 91e79bcf895101ac55520f708840df7f36b4528a
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
-F src/sqliteInt.h ac8f3f5846275c634f6649969304a9e97f6f9854
+F src/sqliteInt.h 6d605800a055f613ec43a02b4d35894b4c9ee291
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 501c9a200fd998a268be475be5858febc90b725b
-F src/test1.c 9ca440e80e16e53920904a0a5ac7feffb9b2c9a1
+F src/test1.c 48465fd0a179d05beb2f6e073d683c03d171c051
F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc
F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
F test/tkt-b72787b1.test e6b62b2b2785c04d0d698d6a603507e384165049
+F test/tkt-bd484a090c.test ef8b7ad7529258b6b8a5b16d4c186f88aa412af8
F test/tkt-cbd054fa6b.test f14f97ea43662e6f70c9e63287081e8be5d9d589
F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7
F test/tkt-d82e3f3721.test 731359dfdcdb36fea0559cd33fec39dd0ceae8e6
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P e4d0f7ace83370e9c878cb0be30dcc28ab97ebae
-R 36390cb0be4272b8ed5078298b604298
+P ed1da510a239ea767a01dc332b667119fa3c908e
+R 54fab978eaa2d7be584363d967fab2fc
U drh
-Z 402f39aea0221f326527a31afee1a690
+Z ba01364c8e95bf423f27b3ad121cc8c9
-ed1da510a239ea767a01dc332b667119fa3c908e
\ No newline at end of file
+5d4b0c5bfc5be1b16b05d43f943cd8f755d23d0e
\ No newline at end of file
#ifndef SQLITE_OMIT_DATETIME_FUNCS
-/*
-** On recent Windows platforms, the localtime_s() function is available
-** as part of the "Secure CRT". It is essentially equivalent to
-** localtime_r() available under most POSIX platforms, except that the
-** order of the parameters is reversed.
-**
-** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
-**
-** If the user has not indicated to use localtime_r() or localtime_s()
-** already, check for an MSVC build environment that provides
-** localtime_s().
-*/
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
- defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
-#define HAVE_LOCALTIME_S 1
-#endif
/*
** A structure for holding a single date and time.
p->validTZ = 0;
}
+/*
+** On recent Windows platforms, the localtime_s() function is available
+** as part of the "Secure CRT". It is essentially equivalent to
+** localtime_r() available under most POSIX platforms, except that the
+** order of the parameters is reversed.
+**
+** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
+**
+** If the user has not indicated to use localtime_r() or localtime_s()
+** already, check for an MSVC build environment that provides
+** localtime_s().
+*/
+#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
+ defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
+#define HAVE_LOCALTIME_S 1
+#endif
+
+#ifndef SQLITE_OMIT_LOCALTIME
+/*
+** The following routine implements the rough equivalent of localtime_r()
+** using whatever operating-system specific localtime facility that
+** is available. This routine returns 0 on success and
+** non-zero on any kind of error.
+**
+** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
+** routine will always fail.
+*/
+int osLocaltime(time_t *t, struct tm *pTm){
+ int rc;
+#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \
+ && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S)
+ struct tm *pX;
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+ sqlite3_mutex_enter(mutex);
+ pX = localtime(t);
+#ifndef SQLITE_OMIT_BUILTIN_TEST
+ if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
+#endif
+ if( pX ) *pTm = *pX;
+ sqlite3_mutex_leave(mutex);
+ rc = pX==0;
+#else
+#ifndef SQLITE_OMIT_BUILTIN_TEST
+ if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
+#endif
+#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R
+ rc = localtime_r(t, pTm)==0;
+#else
+ rc = localtime_s(pTm, t);
+#endif /* HAVE_LOCALTIME_R */
+#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */
+ return rc;
+}
+#endif /* SQLITE_OMIT_LOCALTIME */
+
+
#ifndef SQLITE_OMIT_LOCALTIME
/*
-** Compute the difference (in milliseconds)
-** between localtime and UTC (a.k.a. GMT)
-** for the time value p where p is in UTC.
+** Compute the difference (in milliseconds) between localtime and UTC
+** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
+** return this value and set *pRc to SQLITE_OK.
+**
+** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
+** is undefined in this case.
*/
-static sqlite3_int64 localtimeOffset(DateTime *p){
+static sqlite3_int64 localtimeOffset(
+ DateTime *p, /* Date at which to calculate offset */
+ sqlite3_context *pCtx, /* Write error here if one occurs */
+ int *pRc /* OUT: Error code. SQLITE_OK or ERROR */
+){
DateTime x, y;
time_t t;
+ struct tm sLocal;
+
x = *p;
computeYMD_HMS(&x);
if( x.Y<1971 || x.Y>=2038 ){
x.validJD = 0;
computeJD(&x);
t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
-#ifdef HAVE_LOCALTIME_R
- {
- struct tm sLocal;
- localtime_r(&t, &sLocal);
- y.Y = sLocal.tm_year + 1900;
- y.M = sLocal.tm_mon + 1;
- y.D = sLocal.tm_mday;
- y.h = sLocal.tm_hour;
- y.m = sLocal.tm_min;
- y.s = sLocal.tm_sec;
- }
-#elif defined(HAVE_LOCALTIME_S) && HAVE_LOCALTIME_S
- {
- struct tm sLocal;
- localtime_s(&sLocal, &t);
- y.Y = sLocal.tm_year + 1900;
- y.M = sLocal.tm_mon + 1;
- y.D = sLocal.tm_mday;
- y.h = sLocal.tm_hour;
- y.m = sLocal.tm_min;
- y.s = sLocal.tm_sec;
- }
-#else
- {
- struct tm *pTm;
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
- pTm = localtime(&t);
- y.Y = pTm->tm_year + 1900;
- y.M = pTm->tm_mon + 1;
- y.D = pTm->tm_mday;
- y.h = pTm->tm_hour;
- y.m = pTm->tm_min;
- y.s = pTm->tm_sec;
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+ if( osLocaltime(&t, &sLocal) ){
+ sqlite3_result_error(pCtx, "local time unavailable", -1);
+ *pRc = SQLITE_ERROR;
+ return 0;
}
-#endif
+ y.Y = sLocal.tm_year + 1900;
+ y.M = sLocal.tm_mon + 1;
+ y.D = sLocal.tm_mday;
+ y.h = sLocal.tm_hour;
+ y.m = sLocal.tm_min;
+ y.s = sLocal.tm_sec;
y.validYMD = 1;
y.validHMS = 1;
y.validJD = 0;
y.validTZ = 0;
computeJD(&y);
+ *pRc = SQLITE_OK;
return y.iJD - x.iJD;
}
#endif /* SQLITE_OMIT_LOCALTIME */
** localtime
** utc
**
-** Return 0 on success and 1 if there is any kind of error.
+** Return 0 on success and 1 if there is any kind of error. If the error
+** is in a system call (i.e. localtime()), then an error message is written
+** to context pCtx. If the error is an unrecognized modifier, no error is
+** written to pCtx.
*/
-static int parseModifier(const char *zMod, DateTime *p){
+static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
int rc = 1;
int n;
double r;
*/
if( strcmp(z, "localtime")==0 ){
computeJD(p);
- p->iJD += localtimeOffset(p);
+ p->iJD += localtimeOffset(p, pCtx, &rc);
clearYMD_HMS_TZ(p);
- rc = 0;
}
break;
}
else if( strcmp(z, "utc")==0 ){
sqlite3_int64 c1;
computeJD(p);
- c1 = localtimeOffset(p);
- p->iJD -= c1;
- clearYMD_HMS_TZ(p);
- p->iJD += c1 - localtimeOffset(p);
- rc = 0;
+ c1 = localtimeOffset(p, pCtx, &rc);
+ if( rc==SQLITE_OK ){
+ p->iJD -= c1;
+ clearYMD_HMS_TZ(p);
+ p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
+ }
}
#endif
break;
}
}
for(i=1; i<argc; i++){
- if( (z = sqlite3_value_text(argv[i]))==0 || parseModifier((char*)z, p) ){
- return 1;
- }
+ z = sqlite3_value_text(argv[i]);
+ if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
}
return 0;
}
break;
}
+ /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
+ **
+ ** If parameter onoff is non-zero, configure the wrappers so that all
+ ** subsequent calls to localtime() and variants fail. If onoff is zero,
+ ** undo this setting.
+ */
+ case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
+ sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
+ break;
+ }
+
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
#define SQLITE_TESTCTRL_ISKEYWORD 16
#define SQLITE_TESTCTRL_PGHDRSZ 17
#define SQLITE_TESTCTRL_SCRATCHMALLOC 18
-#define SQLITE_TESTCTRL_LAST 18
+#define SQLITE_TESTCTRL_LOCALTIME_FAULT 19
+#define SQLITE_TESTCTRL_LAST 19
/*
** CAPI3REF: SQLite Runtime Status
int nRefInitMutex; /* Number of users of pInitMutex */
void (*xLog)(void*,int,const char*); /* Function for logging */
void *pLogArg; /* First argument to xLog() */
+ int bLocaltimeFault; /* True to fail localtime() calls */
};
/*
}
#endif /* SQLITE_OMIT_EXPLAIN */
+/*
+** sqlite3_test_control VERB ARGS...
+*/
+static int test_test_control(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ struct Verb {
+ const char *zName;
+ int i;
+ } aVerb[] = {
+ { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
+ };
+ int iVerb;
+ int iFlag;
+ int rc;
+
+ if( objc<2 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "VERB ARGS...");
+ return TCL_ERROR;
+ }
+
+ rc = Tcl_GetIndexFromObjStruct(
+ interp, objv[1], aVerb, sizeof(aVerb[0]), "VERB", 0, &iVerb
+ );
+ if( rc!=TCL_OK ) return rc;
+
+ iFlag = aVerb[iVerb].i;
+ switch( iFlag ){
+ case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
+ int val;
+ if( objc!=3 ){
+ Tcl_WrongNumArgs(interp, 2, objv, "ONOFF");
+ return TCL_ERROR;
+ }
+ if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
+ sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, val);
+ break;
+ }
+ }
+
+ Tcl_ResetResult(interp);
+ return TCL_OK;
+}
+
+
/*
** optimization_control DB OPT BOOLEAN
**
#ifndef SQLITE_OMIT_EXPLAIN
{ "print_explain_query_plan", test_print_eqp, 0 },
#endif
+ { "sqlite3_test_control", test_test_control },
};
static int bitmask_size = sizeof(Bitmask)*8;
int i;
--- /dev/null
+# 2011 June 21
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# This file contains tests for SQLite. Specifically, it tests that SQLite
+# does not crash and an error is returned if localhost() fails. This
+# is the problem reported by ticket bd484a090c.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+set testprefix tkt-bd484a090c
+
+
+do_test 1.1 {
+ lindex [catchsql { SELECT datetime('now', 'localtime') }] 0
+} {0}
+do_test 1.2 {
+ lindex [catchsql { SELECT datetime('now', 'utc') }] 0
+} {0}
+
+sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 1
+
+do_test 2.1 {
+ foreach {rc msg} [catchsql { SELECT datetime('now', 'localtime') }] {}
+ set res [string match {local time unavailable} $msg]
+ list $rc $res
+} {1 1}
+do_test 2.2 {
+ foreach {rc msg} [catchsql { SELECT datetime('now', 'utc') }] {}
+ set res [string match {local time unavailable} $msg]
+ list $rc $res
+} {1 1}
+
+sqlite3_test_control SQLITE_TESTCTRL_LOCALTIME_FAULT 0
+
+finish_test