1
0
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:
dan
2018-01-15 15:49:46 +00:00
parent a9be508a97
commit 89fa746941
3 changed files with 124 additions and 21 deletions

View File

@ -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 */

View File

@ -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

View File

@ -1 +1 @@
8151913a3987f4dd2d6efee046727f5fa9b6f11d5d3867ea8f512c03a212ac2b
cf64087224aff1a2fe169d23996d9e5ed8d86459c655eb5d0bace0466a557ec6