Remove the time() dependency from the zipfile extension. Use SQLite VFS

methods instead.

FossilOrigin-Name: 0702fb5611c7cf0154c5490eeada66afc733731dff0fe030375bae6a72123a17
This commit is contained in:
dan 2018-02-02 16:20:41 +00:00
parent 668845bb0b
commit 1dff328119
3 changed files with 64 additions and 29 deletions

View File

@ -30,18 +30,9 @@ SQLITE_EXTENSION_INIT1
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#if !defined(_WIN32) && !defined(WIN32)
# include <unistd.h>
# include <dirent.h>
# include <utime.h>
#else
#if defined(_WIN32) || defined(WIN32)
# include <io.h>
#endif
#include <time.h>
#include <errno.h>
#include <zlib.h>
@ -68,6 +59,25 @@ typedef unsigned long u32;
#endif /* SQLITE_AMALGAMATION */
/*
** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK.
**
** In some ways it would be better to obtain these values from system
** header files. But, the dependency is undesirable and (a) these
** have been stable for decades, (b) the values are part of POSIX and
** are also made explicit in [man stat], and (c) are part of the
** file format for zip archives.
*/
#ifndef S_IFDIR
# define S_IFDIR 0040000
#endif
#ifndef S_IFREG
# define S_IFREG 0100000
#endif
#ifndef S_IFLNK
# define S_IFLNK 0120000
#endif
static const char ZIPFILE_SCHEMA[] =
"CREATE TABLE y("
"name PRIMARY KEY," /* 0: Name of file in zip archive */
@ -1447,6 +1457,39 @@ static int zipfileBegin(sqlite3_vtab *pVtab){
return rc;
}
/*
** Return the current time as a 32-bit timestamp in UNIX epoch format (like
** time(2)).
*/
static u32 zipfileTime(void){
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
u32 ret;
if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
i64 ms;
pVfs->xCurrentTimeInt64(pVfs, &ms);
ret = (u32)((ms/1000) - ((i64)24405875 * 8640));
}else{
double day;
pVfs->xCurrentTime(pVfs, &day);
ret = (u32)((day - 2440587.5) * 86400);
}
return ret;
}
/*
** Return a 32-bit timestamp in UNIX epoch format.
**
** If the value passed as the only argument is either NULL or an SQL NULL,
** return the current time. Otherwise, return the value stored in (*pVal)
** cast to a 32-bit unsigned integer.
*/
static u32 zipfileGetTime(sqlite3_value *pVal){
if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
return zipfileTime();
}
return (u32)sqlite3_value_int64(pVal);
}
/*
** xUpdate method.
*/
@ -1461,7 +1504,7 @@ static int zipfileUpdate(
ZipfileEntry *pNew = 0; /* New in-memory CDS entry */
u32 mode = 0; /* Mode for new entry */
i64 mTime = 0; /* Modification time for new entry */
u32 mTime = 0; /* Modification time for new entry */
i64 sz = 0; /* Uncompressed size */
const char *zPath = 0; /* Path for new entry */
int nPath = 0; /* strlen(zPath) */
@ -1540,11 +1583,7 @@ static int zipfileUpdate(
if( rc==SQLITE_OK ){
zPath = (const char*)sqlite3_value_text(apVal[2]);
nPath = (int)strlen(zPath);
if( sqlite3_value_type(apVal[4])==SQLITE_NULL ){
mTime = (sqlite3_int64)time(0);
}else{
mTime = sqlite3_value_int64(apVal[4]);
}
mTime = zipfileGetTime(apVal[4]);
}
if( rc==SQLITE_OK && bIsDir ){
@ -1581,7 +1620,7 @@ static int zipfileUpdate(
pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS;
pNew->cds.iCompression = (u16)iMethod;
zipfileMtimeToDos(&pNew->cds, (u32)mTime);
zipfileMtimeToDos(&pNew->cds, mTime);
pNew->cds.crc32 = iCrc32;
pNew->cds.szCompressed = nData;
pNew->cds.szUncompressed = (u32)sz;
@ -1929,11 +1968,7 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
if( rc ) goto zipfile_step_out;
/* Decode the "mtime" argument. */
if( pMtime==0 || sqlite3_value_type(pMtime)==SQLITE_NULL ){
e.mUnixTime = (u32)time(0);
}else{
e.mUnixTime = (u32)sqlite3_value_int64(pMtime);
}
e.mUnixTime = zipfileGetTime(pMtime);
/* If this is a directory entry, ensure that there is exactly one '/'
** at the end of the path. Or, if this is not a directory and the path

View File

@ -1,5 +1,5 @@
C Add\sa\sfew\smore\szipfile\stests.\sNo\schanges\sto\scode.
D 2018-02-01T20:42:23.543
C Remove\sthe\stime()\sdependency\sfrom\sthe\szipfile\sextension.\sUse\sSQLite\sVFS\nmethods\sinstead.
D 2018-02-02T16:20:41.841
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 7a3f714b4fcf793108042b7b0a5c720b0b310ec84314d61ba7f3f49f27e550ea
@ -304,7 +304,7 @@ F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178
F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
F ext/misc/zipfile.c 2856e99ce4b45669edbdc070649a7c6ea0348979d9297ab682f3c552078d47c7
F ext/misc/zipfile.c 8043b5efef0da4abba31ac021a9ea9aaf216c72547fb7f64eed9e08fd96107ff
F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee
@ -1704,7 +1704,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 48f1c556994d7f8f359c649a1da81eec02306106b68946a9a20b276742c4610d
R cdbed97cc578ccd9e756b9f206f65092
P 3f621545879ea39502cfaf2b61883f92c077070274b4fdf45524ded81cac3e63
R 0244469f34b504c4ae85aff5c78a3c61
U dan
Z 07c3c59583bca5bfb67bba61fc8753c1
Z ce324d9598828c350892743fba0ec306

View File

@ -1 +1 @@
3f621545879ea39502cfaf2b61883f92c077070274b4fdf45524ded81cac3e63
0702fb5611c7cf0154c5490eeada66afc733731dff0fe030375bae6a72123a17