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 */
|
"rawdata," /* 4: Raw data */
|
||||||
"data," /* 5: Uncompressed data */
|
"data," /* 5: Uncompressed data */
|
||||||
"method," /* 6: Compression method (integer) */
|
"method," /* 6: Compression method (integer) */
|
||||||
"file HIDDEN" /* 7: Name of zip file */
|
"z HIDDEN" /* 7: Name of zip file */
|
||||||
") WITHOUT ROWID;";
|
") WITHOUT ROWID;";
|
||||||
|
|
||||||
#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
|
#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */
|
||||||
@ -235,6 +235,7 @@ struct ZipfileEntry {
|
|||||||
typedef struct ZipfileCsr ZipfileCsr;
|
typedef struct ZipfileCsr ZipfileCsr;
|
||||||
struct ZipfileCsr {
|
struct ZipfileCsr {
|
||||||
sqlite3_vtab_cursor base; /* Base class - must be first */
|
sqlite3_vtab_cursor base; /* Base class - must be first */
|
||||||
|
i64 iId; /* Cursor ID */
|
||||||
int bEof; /* True when at EOF */
|
int bEof; /* True when at EOF */
|
||||||
|
|
||||||
/* Used outside of write transactions */
|
/* Used outside of write transactions */
|
||||||
@ -264,8 +265,10 @@ struct ZipfileTab {
|
|||||||
char *zFile; /* Zip file this table accesses (may be NULL) */
|
char *zFile; /* Zip file this table accesses (may be NULL) */
|
||||||
u8 *aBuffer; /* Temporary buffer used for various tasks */
|
u8 *aBuffer; /* Temporary buffer used for various tasks */
|
||||||
|
|
||||||
/* The following are used by write transactions only */
|
|
||||||
ZipfileCsr *pCsrList; /* List of cursors */
|
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 *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */
|
||||||
ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */
|
ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */
|
||||||
FILE *pWriteFd; /* File handle open on zip archive */
|
FILE *pWriteFd; /* File handle open on zip archive */
|
||||||
@ -344,6 +347,7 @@ static int zipfileDisconnect(sqlite3_vtab *pVtab){
|
|||||||
** Constructor for a new ZipfileCsr object.
|
** Constructor for a new ZipfileCsr object.
|
||||||
*/
|
*/
|
||||||
static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
|
static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
|
||||||
|
ZipfileTab *pTab = (ZipfileTab*)p;
|
||||||
ZipfileCsr *pCsr;
|
ZipfileCsr *pCsr;
|
||||||
pCsr = sqlite3_malloc(sizeof(*pCsr));
|
pCsr = sqlite3_malloc(sizeof(*pCsr));
|
||||||
*ppCsr = (sqlite3_vtab_cursor*)pCsr;
|
*ppCsr = (sqlite3_vtab_cursor*)pCsr;
|
||||||
@ -351,6 +355,9 @@ static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
|
|||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
memset(pCsr, 0, sizeof(*pCsr));
|
memset(pCsr, 0, sizeof(*pCsr));
|
||||||
|
pCsr->iId = ++pTab->iNextCsrid;
|
||||||
|
pCsr->pCsrNext = pTab->pCsrList;
|
||||||
|
pTab->pCsrList = pCsr;
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,14 +366,6 @@ static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
|
|||||||
** by zipfileOpen().
|
** by zipfileOpen().
|
||||||
*/
|
*/
|
||||||
static void zipfileResetCursor(ZipfileCsr *pCsr){
|
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);
|
sqlite3_free(pCsr->cds.zFile);
|
||||||
pCsr->cds.zFile = 0;
|
pCsr->cds.zFile = 0;
|
||||||
pCsr->bEof = 0;
|
pCsr->bEof = 0;
|
||||||
@ -381,7 +380,18 @@ static void zipfileResetCursor(ZipfileCsr *pCsr){
|
|||||||
*/
|
*/
|
||||||
static int zipfileClose(sqlite3_vtab_cursor *cur){
|
static int zipfileClose(sqlite3_vtab_cursor *cur){
|
||||||
ZipfileCsr *pCsr = (ZipfileCsr*)cur;
|
ZipfileCsr *pCsr = (ZipfileCsr*)cur;
|
||||||
|
ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab);
|
||||||
|
ZipfileCsr **pp;
|
||||||
zipfileResetCursor(pCsr);
|
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);
|
sqlite3_free(pCsr);
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
@ -823,7 +833,8 @@ static int zipfileColumn(
|
|||||||
case 5: { /* data */
|
case 5: { /* data */
|
||||||
if( i==4 || pCsr->cds.iCompression==0 || pCsr->cds.iCompression==8 ){
|
if( i==4 || pCsr->cds.iCompression==0 || pCsr->cds.iCompression==8 ){
|
||||||
int sz = pCsr->cds.szCompressed;
|
int sz = pCsr->cds.szCompressed;
|
||||||
if( sz>0 ){
|
int szFinal = pCsr->cds.szUncompressed;
|
||||||
|
if( szFinal>0 ){
|
||||||
u8 *aBuf = sqlite3_malloc(sz);
|
u8 *aBuf = sqlite3_malloc(sz);
|
||||||
if( aBuf==0 ){
|
if( aBuf==0 ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
@ -835,12 +846,20 @@ static int zipfileColumn(
|
|||||||
}
|
}
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
if( i==5 && pCsr->cds.iCompression ){
|
if( i==5 && pCsr->cds.iCompression ){
|
||||||
zipfileInflate(ctx, aBuf, sz, pCsr->cds.szUncompressed);
|
zipfileInflate(ctx, aBuf, sz, szFinal);
|
||||||
}else{
|
}else{
|
||||||
sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
|
sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
|
||||||
}
|
}
|
||||||
sqlite3_free(aBuf);
|
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;
|
break;
|
||||||
@ -848,6 +867,9 @@ static int zipfileColumn(
|
|||||||
case 6: /* method */
|
case 6: /* method */
|
||||||
sqlite3_result_int(ctx, pCsr->cds.iCompression);
|
sqlite3_result_int(ctx, pCsr->cds.iCompression);
|
||||||
break;
|
break;
|
||||||
|
case 7: /* z */
|
||||||
|
sqlite3_result_int64(ctx, pCsr->iId);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@ -1553,6 +1575,84 @@ static int zipfileRollback(sqlite3_vtab *pVtab){
|
|||||||
return zipfileCommit(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.
|
** Register the "zipfile" virtual table.
|
||||||
*/
|
*/
|
||||||
@ -1576,11 +1676,14 @@ static int zipfileRegister(sqlite3 *db){
|
|||||||
0, /* xSync */
|
0, /* xSync */
|
||||||
zipfileCommit, /* xCommit */
|
zipfileCommit, /* xCommit */
|
||||||
zipfileRollback, /* xRollback */
|
zipfileRollback, /* xRollback */
|
||||||
0, /* xFindMethod */
|
zipfileFindFunction, /* xFindMethod */
|
||||||
0, /* xRename */
|
0, /* xRename */
|
||||||
};
|
};
|
||||||
|
|
||||||
int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
|
int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = sqlite3_overload_function(db, "zipfile_cds", -1);
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#else /* SQLITE_OMIT_VIRTUALTABLE */
|
#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.
|
C Fix\sa\szipfile\sproblem\swith\sextracting\szero\slength\sfiles\scompressed\susing\ndeflate.
|
||||||
D 2018-01-15T14:32:37.594
|
D 2018-01-15T15:49:46.517
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F Makefile.in 38f84f301cbef443b2d269f67a74b8cc536469831f70df7c3e912acc04932cc2
|
F Makefile.in 38f84f301cbef443b2d269f67a74b8cc536469831f70df7c3e912acc04932cc2
|
||||||
@ -303,7 +303,7 @@ F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178
|
|||||||
F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9
|
F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9
|
||||||
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
||||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
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/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
|
||||||
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
|
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
|
||||||
F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee
|
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.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P a4fa0581ba7cfd45fabe0198f55b3c2c8ee3ecfd2825aeed91116f44e77d760b
|
P 8151913a3987f4dd2d6efee046727f5fa9b6f11d5d3867ea8f512c03a212ac2b
|
||||||
R 755347b860dbdbaa8de782672cfa2550
|
R d9864f9f3d3219c31b427d2f3aa9a193
|
||||||
U drh
|
U dan
|
||||||
Z bf44e658c85afb034dcb761e50e86217
|
Z 4b1456c73d542678caf828eee79b5bff
|
||||||
|
@ -1 +1 @@
|
|||||||
8151913a3987f4dd2d6efee046727f5fa9b6f11d5d3867ea8f512c03a212ac2b
|
cf64087224aff1a2fe169d23996d9e5ed8d86459c655eb5d0bace0466a557ec6
|
Reference in New Issue
Block a user