#define MIN(a,b) ((a)<(b) ? (a) : (b))
#endif
-#define ZIPFILE_SCHEMA "CREATE TABLE y(" \
- "name, /* Name of file in zip archive */" \
- "mode, /* POSIX mode for file */" \
- "mtime, /* Last modification time in seconds since epoch */" \
- "sz, /* Size of object */" \
- "data, /* Data stored in zip file (possibly compressed) */" \
- "method, /* Compression method (integer) */" \
- "f HIDDEN /* Name of zip file */" \
+#define ZIPFILE_SCHEMA "CREATE TABLE y(" \
+ "name, /* 0: Name of file in zip archive */" \
+ "mode, /* 1: POSIX mode for file */" \
+ "mtime, /* 2: Last modification time in seconds since epoch */" \
+ "sz, /* 3: Size of object */" \
+ "rawdata, /* 4: Raw data */" \
+ "data, /* 5: Uncompressed data */" \
+ "method, /* 6: Compression method (integer) */" \
+ "file HIDDEN /* Name of zip file */" \
");"
-#define ZIPFILE_F_COLUMN_IDX 6 /* Index of column "f" in the above */
+#define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "f" in the above */
#define ZIPFILE_BUFFER_SIZE (64*1024)
((res.tm_year-80) << 9));
}
+static void zipfileInflate(
+ sqlite3_context *pCtx, /* Store error here, if any */
+ const u8 *aIn, /* Compressed data */
+ int nIn, /* Size of buffer aIn[] in bytes */
+ int nOut /* Expected output size */
+){
+ u8 *aRes = sqlite3_malloc(nOut);
+ if( aRes==0 ){
+ sqlite3_result_error_nomem(pCtx);
+ }else{
+ int err;
+ z_stream str;
+ memset(&str, 0, sizeof(str));
+
+ str.next_in = (Byte*)aIn;
+ str.avail_in = nIn;
+ str.next_out = (Byte*)aRes;
+ str.avail_out = nOut;
+
+ err = inflateInit2(&str, -15);
+ if( err!=Z_OK ){
+ zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err);
+ }else{
+ err = inflate(&str, Z_NO_FLUSH);
+ if( err!=Z_STREAM_END ){
+ zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err);
+ }else{
+ sqlite3_result_blob(pCtx, aRes, nOut, SQLITE_TRANSIENT);
+ }
+ }
+ sqlite3_free(aRes);
+ inflateEnd(&str);
+ }
+}
+
+static int zipfileDeflate(
+ ZipfileTab *pTab, /* Set error message here */
+ const u8 *aIn, int nIn, /* Input */
+ u8 **ppOut, int *pnOut /* Output */
+){
+ int nAlloc = (int)compressBound(nIn);
+ u8 *aOut;
+ int rc;
+
+ aOut = (u8*)sqlite3_malloc(nAlloc);
+ if( aOut==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ int res;
+ z_stream str;
+ memset(&str, 0, sizeof(str));
+ str.next_in = (z_const Bytef*)aIn;
+ str.avail_in = nIn;
+ str.next_out = aOut;
+ str.avail_out = nAlloc;
+
+ deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
+ res = deflate(&str, Z_FINISH);
+
+ if( res==Z_STREAM_END ){
+ *ppOut = aOut;
+ *pnOut = (int)str.total_out;
+ }else{
+ sqlite3_free(aOut);
+ pTab->base.zErrMsg = sqlite3_mprintf("zipfile: deflate() error");
+ rc = SQLITE_ERROR;
+ }
+ deflateEnd(&str);
+ }
+
+ return rc;
+}
+
+
/*
** Return values of columns for the row at which the series_cursor
** is currently pointing.
sqlite3_result_int64(ctx, pCsr->cds.szUncompressed);
break;
}
- case 4: { /* data */
- int sz = pCsr->cds.szCompressed;
- if( sz>0 ){
- u8 *aBuf = sqlite3_malloc(sz);
- if( aBuf==0 ){
- rc = SQLITE_NOMEM;
- }else{
- FILE *pFile = zipfileGetFd(pCsr);
- rc = zipfileReadData(pFile, aBuf, sz, pCsr->iDataOff,
- &pCsr->base.pVtab->zErrMsg
- );
- }
- if( rc==SQLITE_OK ){
- sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
- sqlite3_free(aBuf);
+ case 4: /* rawdata */
+ case 5: { /* data */
+ if( i==4 || pCsr->cds.iCompression==0 || pCsr->cds.iCompression==8 ){
+ int sz = pCsr->cds.szCompressed;
+ if( sz>0 ){
+ u8 *aBuf = sqlite3_malloc(sz);
+ if( aBuf==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ FILE *pFile = zipfileGetFd(pCsr);
+ rc = zipfileReadData(pFile, aBuf, sz, pCsr->iDataOff,
+ &pCsr->base.pVtab->zErrMsg
+ );
+ }
+ if( rc==SQLITE_OK ){
+ if( i==5 && pCsr->cds.iCompression ){
+ zipfileInflate(ctx, aBuf, sz, pCsr->cds.szUncompressed);
+ }else{
+ sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
+ }
+ sqlite3_free(aBuf);
+ }
}
}
break;
}
- case 5: /* method */
+ case 6: /* method */
sqlite3_result_int(ctx, pCsr->cds.iCompression);
break;
}
static int zipfileGetMode(ZipfileTab *pTab, sqlite3_value *pVal, int *pMode){
const char *z = (const char*)sqlite3_value_text(pVal);
int mode = 0;
- if( z==0 || (z[0]>=0 && z[0]<=9) ){
+ if( z==0 ){
+ mode = 33188; /* -rw-r--r-- */
+ }else if( z[0]>=0 && z[0]<=9 ){
mode = sqlite3_value_int(pVal);
}else{
const char zTemplate[11] = "-rwxrwxrwx";
i64 sz; /* Uncompressed size */
const char *zPath; /* Path for new entry */
int nPath; /* strlen(zPath) */
- const u8 *pData; /* Pointer to buffer containing content */
- int nData; /* Size of pData buffer in bytes */
+ const u8 *pData = 0; /* Pointer to buffer containing content */
+ int nData = 0; /* Size of pData buffer in bytes */
int iMethod = 0; /* Compression method for new entry */
u8 *pFree = 0; /* Free this */
ZipfileCDS cds; /* New Central Directory Structure entry */
nPath = (int)strlen(zPath);
rc = zipfileGetMode(pTab, apVal[3], &mode);
if( rc!=SQLITE_OK ) return rc;
- mTime = sqlite3_value_int64(apVal[4]);
- sz = sqlite3_value_int(apVal[5]);
- pData = sqlite3_value_blob(apVal[6]);
- nData = sqlite3_value_bytes(apVal[6]);
-
- /* If a NULL value is inserted into the 'method' column, do automatic
- ** compression. */
- if( nData>0 && sqlite3_value_type(apVal[7])==SQLITE_NULL ){
- pFree = (u8*)sqlite3_malloc(nData);
- if( pFree==0 ){
- rc = SQLITE_NOMEM;
- }else{
- int res;
- z_stream str;
- memset(&str, 0, sizeof(str));
- str.next_in = (z_const Bytef*)pData;
- str.avail_in = nData;
- str.next_out = pFree;
- str.avail_out = nData;
- deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
- res = deflate(&str, Z_FINISH);
- if( res==Z_STREAM_END ){
- pData = pFree;
- nData = str.total_out;
- iMethod = 8;
- }else if( res!=Z_OK ){
- pTab->base.zErrMsg = sqlite3_mprintf("zipfile: deflate() error");
- rc = SQLITE_ERROR;
+ if( sqlite3_value_type(apVal[4])==SQLITE_NULL ){
+ mTime = (sqlite3_int64)time(0);
+ }else{
+ mTime = sqlite3_value_int64(apVal[4]);
+ }
+
+ if( sqlite3_value_type(apVal[5])==SQLITE_NULL /* sz */
+ && sqlite3_value_type(apVal[6])==SQLITE_NULL /* rawdata */
+ && sqlite3_value_type(apVal[7])!=SQLITE_NULL /* data */
+ ){
+ const u8 *aIn = sqlite3_value_blob(apVal[7]);
+ int nIn = sqlite3_value_bytes(apVal[7]);
+ int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL;
+
+ iMethod = sqlite3_value_int(apVal[8]);
+ sz = nIn;
+ if( iMethod!=0 && iMethod!=8 ){
+ rc = SQLITE_CONSTRAINT;
+ }else if( bAuto || iMethod ){
+ rc = zipfileDeflate(pTab, aIn, nIn, &pFree, &nData);
+ if( rc==SQLITE_OK ){
+ if( iMethod || nData<nIn ){
+ iMethod = 8;
+ pData = pFree;
+ }else{
+ pData = aIn;
+ nData = nIn;
+ }
}
- deflateEnd(&str);
}
- }else{
- iMethod = sqlite3_value_int(apVal[7]);
+ }else
+ if( sqlite3_value_type(apVal[5])!=SQLITE_NULL /* sz */
+ && sqlite3_value_type(apVal[6])!=SQLITE_NULL /* rawdata */
+ && sqlite3_value_type(apVal[7])==SQLITE_NULL /* data */
+ && sqlite3_value_type(apVal[8])!=SQLITE_NULL /* method */
+ ){
+ pData = sqlite3_value_blob(apVal[6]);
+ nData = sqlite3_value_bytes(apVal[6]);
+ sz = sqlite3_value_int(apVal[5]);
+ iMethod = sqlite3_value_int(apVal[8]);
if( iMethod<0 || iMethod>65535 ){
pTab->base.zErrMsg = sqlite3_mprintf(
"zipfile: invalid compression method: %d", iMethod
);
rc = SQLITE_ERROR;
}
+ }else{
+ rc = SQLITE_CONSTRAINT;
}
if( rc==SQLITE_OK ){
# define zipfileRegister(x) SQLITE_OK
#endif
-/*
-** zipfile_uncompress(DATA, SZ, METHOD)
-*/
-static void zipfileUncompressFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- int iMethod;
-
- iMethod = sqlite3_value_int(argv[2]);
- if( iMethod==0 ){
- sqlite3_result_value(context, argv[0]);
- }else if( iMethod==8 ){
- Byte *res;
- int sz = sqlite3_value_int(argv[1]);
- z_stream str;
- memset(&str, 0, sizeof(str));
- str.next_in = (Byte*)sqlite3_value_blob(argv[0]);
- str.avail_in = sqlite3_value_bytes(argv[0]);
- res = str.next_out = (Byte*)sqlite3_malloc(sz);
- if( res==0 ){
- sqlite3_result_error_nomem(context);
- }else{
- int err;
- str.avail_out = sz;
-
- err = inflateInit2(&str, -15);
- if( err!=Z_OK ){
- zipfileCtxErrorMsg(context, "inflateInit2() failed (%d)", err);
- }else{
- err = inflate(&str, Z_NO_FLUSH);
- if( err!=Z_STREAM_END ){
- zipfileCtxErrorMsg(context, "inflate() failed (%d)", err);
- }else{
- sqlite3_result_blob(context, res, sz, SQLITE_TRANSIENT);
- }
- }
- sqlite3_free(res);
- inflateEnd(&str);
- }
- }else{
- zipfileCtxErrorMsg(context, "unrecognized compression method: %d", iMethod);
- }
-}
-
#ifdef _WIN32
__declspec(dllexport)
#endif
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
- int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "zipfile_uncompress", 3,
- SQLITE_UTF8, 0, zipfileUncompressFunc, 0, 0
- );
- if( rc!=SQLITE_OK ) return rc;
return zipfileRegister(db);
}
-C Fix\sproblems\sin\sthe\ssqlite3expert.c\scode\srevealed\sby\s-fsanitize.
-D 2018-01-08T17:34:15.620
+C Update\sthe\szipfile\smodule\sso\sthat\sit\smatches\sthe\sdocumentation.
+D 2018-01-08T19:59:59.813
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 12b6daa4bdb03fa87da27cbc205ff88ace645475b5be79414a3038b68ade14cb
F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
-F ext/misc/zipfile.c 8075df9296beeebc344567927d114c6d3201110a29110013388d233fa7d4fb2c
+F ext/misc/zipfile.c d576a5b473333f5d14f9380cf005b52a684a1ee46d4a6cfb08802564e6365e5e
F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee
F src/resolve.c bbee7e31d369a18a2f4836644769882e9c5d40ef4a3af911db06410b65cb3730
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 8b22abe193e4d8243befa2038e4ae2405802fed1c446e5e502d11f652e09ba74
-F src/shell.c.in be04d6797b4ee066f064dc370bdcb148c84c6c6979bf12f70025a7a89cf79346
+F src/shell.c.in 2aa65d155202d1caf457cb7112ec47d1aded1bc54b20e7f8f7cf81ca1dbb43bf
F src/sqlite.h.in 1f1a2da222ec57465794e8984d77f32d0bd0da80cdc136beadda461a0be9d80c
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
-F test/zipfile.test a1dd0429294cb9487900fc2b29aa9921329f20a7314aa0921b668246172ac090
+F test/zipfile.test ad4278e1ebb1c7bc0fcd7f9b47df18916b9e8f841165119865a5a6a095a2d0ba
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 7182591d351dde22ed2f6a60521d1d7c10a610d702e79693412efc6938167be0
-R 49ecd97a6ce816710af5cab9bccdaf02
+P 7a93dd784bfdbf01927979a61643796e0901d9ac285fe4214677838def93a9a4
+R 86cc2218634a3d23586f8875ed6e23c5
U dan
-Z 0d0d547dd2ee63ac3d70f7968bc046aa
+Z 3ef32c645be21defc25c769ce8063d43
1 mode {} 0 {} 0
2 mtime {} 0 {} 0
3 sz {} 0 {} 0
- 4 data {} 0 {} 0
- 5 method {} 0 {} 0
+ 4 rawdata {} 0 {} 0
+ 5 data {} 0 {} 0
+ 6 method {} 0 {} 0
}
do_execsql_test 1.1.1 {
- INSERT INTO zz VALUES('f.txt', '-rw-r--r--', 1000000000, 5, 'abcde', 0);
+ INSERT INTO zz(name, mode, mtime, sz, rawdata, method)
+ VALUES('f.txt', '-rw-r--r--', 1000000000, 5, 'abcde', 0);
}
do_execsql_test 1.1.2 {
- INSERT INTO zz VALUES('g.txt', '-rw-r--r--', 1000000002, 5, '12345', 0);
+ INSERT INTO zz(name, mtime, sz, rawdata, method)
+ VALUES('g.txt', 1000000002, 5, '12345', 0);
}
do_execsql_test 1.2 {
}
do_execsql_test 1.3 {
- INSERT INTO zz VALUES('h.txt',
- '-rw-r--r--', 1000000004, 20, 'aaaaaaaaaabbbbbbbbbb', NULL
+ INSERT INTO zz(name, mode, mtime, data) VALUES('h.txt',
+ '-rw-r--r--', 1000000004, 'aaaaaaaaaabbbbbbbbbb'
);
}
do_execsql_test 1.4 {
- SELECT name, mtime, zipfile_uncompress(data, sz, method), method
- FROM zipfile('test.zip');
+ SELECT name, mtime, data, method FROM zipfile('test.zip');
} {
f.txt 1000000000 abcde 0
g.txt 1000000002 12345 0
do_execsql_test 1.5.1 {
BEGIN;
- INSERT INTO zz VALUES('i.txt', '-rw-r--r--', 1000000006, 5, 'zxcvb', 0);
+ INSERT INTO zz(name, mode, mtime, data, method)
+ VALUES('i.txt', '-rw-r--r--', 1000000006, 'zxcvb', 0);
SELECT name FROM zz;
COMMIT;
} {f.txt g.txt h.txt i.txt}