mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-24 22:22:08 +03:00
Fix a zipfile problem with extracting zero length files compressed using
deflate. FossilOrigin-Name: cf64087224aff1a2fe169d23996d9e5ed8d86459c655eb5d0bace0466a557ec6
This commit is contained in:
@ -64,7 +64,7 @@ static const char ZIPFILE_SCHEMA[] =
|
||||
"rawdata," /* 4: Raw data */
|
||||
"data," /* 5: Uncompressed data */
|
||||
"method," /* 6: Compression method (integer) */
|
||||
"file HIDDEN" /* 7: Name of zip file */
|
||||
"z HIDDEN" /* 7: Name of zip file */
|
||||
") WITHOUT ROWID;";
|
||||
|
||||
#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
|
||||
@ -235,6 +235,7 @@ struct ZipfileEntry {
|
||||
typedef struct ZipfileCsr ZipfileCsr;
|
||||
struct ZipfileCsr {
|
||||
sqlite3_vtab_cursor base; /* Base class - must be first */
|
||||
i64 iId; /* Cursor ID */
|
||||
int bEof; /* True when at EOF */
|
||||
|
||||
/* Used outside of write transactions */
|
||||
@ -264,8 +265,10 @@ struct ZipfileTab {
|
||||
char *zFile; /* Zip file this table accesses (may be NULL) */
|
||||
u8 *aBuffer; /* Temporary buffer used for various tasks */
|
||||
|
||||
/* The following are used by write transactions only */
|
||||
ZipfileCsr *pCsrList; /* List of cursors */
|
||||
i64 iNextCsrid;
|
||||
|
||||
/* The following are used by write transactions only */
|
||||
ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */
|
||||
ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */
|
||||
FILE *pWriteFd; /* File handle open on zip archive */
|
||||
@ -344,6 +347,7 @@ static int zipfileDisconnect(sqlite3_vtab *pVtab){
|
||||
** Constructor for a new ZipfileCsr object.
|
||||
*/
|
||||
static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
|
||||
ZipfileTab *pTab = (ZipfileTab*)p;
|
||||
ZipfileCsr *pCsr;
|
||||
pCsr = sqlite3_malloc(sizeof(*pCsr));
|
||||
*ppCsr = (sqlite3_vtab_cursor*)pCsr;
|
||||
@ -351,6 +355,9 @@ static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
memset(pCsr, 0, sizeof(*pCsr));
|
||||
pCsr->iId = ++pTab->iNextCsrid;
|
||||
pCsr->pCsrNext = pTab->pCsrList;
|
||||
pTab->pCsrList = pCsr;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@ -359,14 +366,6 @@ static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
|
||||
** by zipfileOpen().
|
||||
*/
|
||||
static void zipfileResetCursor(ZipfileCsr *pCsr){
|
||||
ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab);
|
||||
ZipfileCsr **pp;
|
||||
|
||||
/* Remove this cursor from the ZipfileTab.pCsrList list. */
|
||||
for(pp=&pTab->pCsrList; *pp; pp=&((*pp)->pCsrNext)){
|
||||
if( *pp==pCsr ) *pp = pCsr->pCsrNext;
|
||||
}
|
||||
|
||||
sqlite3_free(pCsr->cds.zFile);
|
||||
pCsr->cds.zFile = 0;
|
||||
pCsr->bEof = 0;
|
||||
@ -381,7 +380,18 @@ static void zipfileResetCursor(ZipfileCsr *pCsr){
|
||||
*/
|
||||
static int zipfileClose(sqlite3_vtab_cursor *cur){
|
||||
ZipfileCsr *pCsr = (ZipfileCsr*)cur;
|
||||
ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab);
|
||||
ZipfileCsr **pp;
|
||||
zipfileResetCursor(pCsr);
|
||||
|
||||
/* Remove this cursor from the ZipfileTab.pCsrList list. */
|
||||
for(pp=&pTab->pCsrList; *pp; pp=&((*pp)->pCsrNext)){
|
||||
if( *pp==pCsr ){
|
||||
*pp = pCsr->pCsrNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_free(pCsr);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@ -823,7 +833,8 @@ static int zipfileColumn(
|
||||
case 5: { /* data */
|
||||
if( i==4 || pCsr->cds.iCompression==0 || pCsr->cds.iCompression==8 ){
|
||||
int sz = pCsr->cds.szCompressed;
|
||||
if( sz>0 ){
|
||||
int szFinal = pCsr->cds.szUncompressed;
|
||||
if( szFinal>0 ){
|
||||
u8 *aBuf = sqlite3_malloc(sz);
|
||||
if( aBuf==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
@ -835,12 +846,20 @@ static int zipfileColumn(
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
if( i==5 && pCsr->cds.iCompression ){
|
||||
zipfileInflate(ctx, aBuf, sz, pCsr->cds.szUncompressed);
|
||||
zipfileInflate(ctx, aBuf, sz, szFinal);
|
||||
}else{
|
||||
sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
|
||||
}
|
||||
sqlite3_free(aBuf);
|
||||
}
|
||||
}else{
|
||||
/* Figure out if this is a directory or a zero-sized file. Consider
|
||||
** it to be a directory either if the mode suggests so, or if
|
||||
** the final character in the name is '/'. */
|
||||
u32 mode = pCsr->cds.iExternalAttr >> 16;
|
||||
if( !(mode & S_IFDIR) && pCsr->cds.zFile[pCsr->cds.nFile-1]!='/' ){
|
||||
sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -848,6 +867,9 @@ static int zipfileColumn(
|
||||
case 6: /* method */
|
||||
sqlite3_result_int(ctx, pCsr->cds.iCompression);
|
||||
break;
|
||||
case 7: /* z */
|
||||
sqlite3_result_int64(ctx, pCsr->iId);
|
||||
break;
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
@ -1553,6 +1575,84 @@ static int zipfileRollback(sqlite3_vtab *pVtab){
|
||||
return zipfileCommit(pVtab);
|
||||
}
|
||||
|
||||
static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){
|
||||
ZipfileCsr *pCsr;
|
||||
for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
|
||||
if( iId==pCsr->iId ) break;
|
||||
}
|
||||
return pCsr;
|
||||
}
|
||||
|
||||
static void zipfileFunctionCds(
|
||||
sqlite3_context *context,
|
||||
int argc,
|
||||
sqlite3_value **argv
|
||||
){
|
||||
ZipfileCsr *pCsr;
|
||||
ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
|
||||
assert( argc>0 );
|
||||
|
||||
pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
|
||||
if( pCsr ){
|
||||
ZipfileCDS *p = &pCsr->cds;
|
||||
char *zRes = sqlite3_mprintf("{"
|
||||
"\"version-made-by\" : %u, "
|
||||
"\"version-to-extract\" : %u, "
|
||||
"\"flags\" : %u, "
|
||||
"\"compression\" : %u, "
|
||||
"\"time\" : %u, "
|
||||
"\"date\" : %u, "
|
||||
"\"crc32\" : %u, "
|
||||
"\"compressed-size\" : %u, "
|
||||
"\"uncompressed-size\" : %u, "
|
||||
"\"file-name-length\" : %u, "
|
||||
"\"extra-field-length\" : %u, "
|
||||
"\"file-comment-length\" : %u, "
|
||||
"\"disk-number-start\" : %u, "
|
||||
"\"internal-attr\" : %u, "
|
||||
"\"external-attr\" : %u, "
|
||||
"\"offset\" : %u }",
|
||||
(u32)p->iVersionMadeBy, (u32)p->iVersionExtract,
|
||||
(u32)p->flags, (u32)p->iCompression,
|
||||
(u32)p->mTime, (u32)p->mDate,
|
||||
(u32)p->crc32, (u32)p->szCompressed,
|
||||
(u32)p->szUncompressed, (u32)p->nFile,
|
||||
(u32)p->nExtra, (u32)p->nComment,
|
||||
(u32)p->iDiskStart, (u32)p->iInternalAttr,
|
||||
(u32)p->iExternalAttr, (u32)p->iOffset
|
||||
);
|
||||
|
||||
if( zRes==0 ){
|
||||
sqlite3_result_error_nomem(context);
|
||||
}else{
|
||||
sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
|
||||
sqlite3_free(zRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** xFindFunction method.
|
||||
*/
|
||||
static int zipfileFindFunction(
|
||||
sqlite3_vtab *pVtab, /* Virtual table handle */
|
||||
int nArg, /* Number of SQL function arguments */
|
||||
const char *zName, /* Name of SQL function */
|
||||
void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
|
||||
void **ppArg /* OUT: User data for *pxFunc */
|
||||
){
|
||||
if( nArg>0 ){
|
||||
if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
|
||||
*pxFunc = zipfileFunctionCds;
|
||||
*ppArg = (void*)pVtab;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Register the "zipfile" virtual table.
|
||||
*/
|
||||
@ -1576,11 +1676,14 @@ static int zipfileRegister(sqlite3 *db){
|
||||
0, /* xSync */
|
||||
zipfileCommit, /* xCommit */
|
||||
zipfileRollback, /* xRollback */
|
||||
0, /* xFindMethod */
|
||||
zipfileFindFunction, /* xFindMethod */
|
||||
0, /* xRename */
|
||||
};
|
||||
|
||||
int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_overload_function(db, "zipfile_cds", -1);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#else /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\san\serror\sin\sthe\ssetDeviceCharacteristics()\sprocedure\sfor\sthe\n(unsupported)\sQNX\scode\sin\sos_unix.c.
|
||||
D 2018-01-15T14:32:37.594
|
||||
C Fix\sa\szipfile\sproblem\swith\sextracting\szero\slength\sfiles\scompressed\susing\ndeflate.
|
||||
D 2018-01-15T15:49:46.517
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 38f84f301cbef443b2d269f67a74b8cc536469831f70df7c3e912acc04932cc2
|
||||
@ -303,7 +303,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 7001d7ca733d34a8b4fbacf7f8d322f3b2bf402f41052a021b5eda8227f0f5d4
|
||||
F ext/misc/zipfile.c 46171a19439d0c76acf48770e736c281536f160d3a5a96a0511e34402e262fac
|
||||
F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
|
||||
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
|
||||
F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee
|
||||
@ -1699,7 +1699,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 a4fa0581ba7cfd45fabe0198f55b3c2c8ee3ecfd2825aeed91116f44e77d760b
|
||||
R 755347b860dbdbaa8de782672cfa2550
|
||||
U drh
|
||||
Z bf44e658c85afb034dcb761e50e86217
|
||||
P 8151913a3987f4dd2d6efee046727f5fa9b6f11d5d3867ea8f512c03a212ac2b
|
||||
R d9864f9f3d3219c31b427d2f3aa9a193
|
||||
U dan
|
||||
Z 4b1456c73d542678caf828eee79b5bff
|
||||
|
@ -1 +1 @@
|
||||
8151913a3987f4dd2d6efee046727f5fa9b6f11d5d3867ea8f512c03a212ac2b
|
||||
cf64087224aff1a2fe169d23996d9e5ed8d86459c655eb5d0bace0466a557ec6
|
Reference in New Issue
Block a user