xref: /sqlite-3.40.0/ext/misc/zipfile.c (revision aeb4e6ee)
1 /*
2 ** 2017-12-26
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 ******************************************************************************
12 **
13 ** This file implements a virtual table for reading and writing ZIP archive
14 ** files.
15 **
16 ** Usage example:
17 **
18 **     SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename);
19 **
20 ** Current limitations:
21 **
22 **    *  No support for encryption
23 **    *  No support for ZIP archives spanning multiple files
24 **    *  No support for zip64 extensions
25 **    *  Only the "inflate/deflate" (zlib) compression method is supported
26 */
27 #include "sqlite3ext.h"
28 SQLITE_EXTENSION_INIT1
29 #include <stdio.h>
30 #include <string.h>
31 #include <assert.h>
32 
33 #include <zlib.h>
34 
35 #ifndef SQLITE_OMIT_VIRTUALTABLE
36 
37 #ifndef SQLITE_AMALGAMATION
38 
39 typedef sqlite3_int64 i64;
40 typedef unsigned char u8;
41 typedef unsigned short u16;
42 typedef unsigned long u32;
43 #define MIN(a,b) ((a)<(b) ? (a) : (b))
44 
45 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
46 # define ALWAYS(X)      (1)
47 # define NEVER(X)       (0)
48 #elif !defined(NDEBUG)
49 # define ALWAYS(X)      ((X)?1:(assert(0),0))
50 # define NEVER(X)       ((X)?(assert(0),1):0)
51 #else
52 # define ALWAYS(X)      (X)
53 # define NEVER(X)       (X)
54 #endif
55 
56 #endif   /* SQLITE_AMALGAMATION */
57 
58 /*
59 ** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK.
60 **
61 ** In some ways it would be better to obtain these values from system
62 ** header files. But, the dependency is undesirable and (a) these
63 ** have been stable for decades, (b) the values are part of POSIX and
64 ** are also made explicit in [man stat], and (c) are part of the
65 ** file format for zip archives.
66 */
67 #ifndef S_IFDIR
68 # define S_IFDIR 0040000
69 #endif
70 #ifndef S_IFREG
71 # define S_IFREG 0100000
72 #endif
73 #ifndef S_IFLNK
74 # define S_IFLNK 0120000
75 #endif
76 
77 static const char ZIPFILE_SCHEMA[] =
78   "CREATE TABLE y("
79     "name PRIMARY KEY,"  /* 0: Name of file in zip archive */
80     "mode,"              /* 1: POSIX mode for file */
81     "mtime,"             /* 2: Last modification time (secs since 1970)*/
82     "sz,"                /* 3: Size of object */
83     "rawdata,"           /* 4: Raw data */
84     "data,"              /* 5: Uncompressed data */
85     "method,"            /* 6: Compression method (integer) */
86     "z HIDDEN"           /* 7: Name of zip file */
87   ") WITHOUT ROWID;";
88 
89 #define ZIPFILE_F_COLUMN_IDX 7    /* Index of column "file" in the above */
90 #define ZIPFILE_BUFFER_SIZE (64*1024)
91 
92 
93 /*
94 ** Magic numbers used to read and write zip files.
95 **
96 ** ZIPFILE_NEWENTRY_MADEBY:
97 **   Use this value for the "version-made-by" field in new zip file
98 **   entries. The upper byte indicates "unix", and the lower byte
99 **   indicates that the zip file matches pkzip specification 3.0.
100 **   This is what info-zip seems to do.
101 **
102 ** ZIPFILE_NEWENTRY_REQUIRED:
103 **   Value for "version-required-to-extract" field of new entries.
104 **   Version 2.0 is required to support folders and deflate compression.
105 **
106 ** ZIPFILE_NEWENTRY_FLAGS:
107 **   Value for "general-purpose-bit-flags" field of new entries. Bit
108 **   11 means "utf-8 filename and comment".
109 **
110 ** ZIPFILE_SIGNATURE_CDS:
111 **   First 4 bytes of a valid CDS record.
112 **
113 ** ZIPFILE_SIGNATURE_LFH:
114 **   First 4 bytes of a valid LFH record.
115 **
116 ** ZIPFILE_SIGNATURE_EOCD
117 **   First 4 bytes of a valid EOCD record.
118 */
119 #define ZIPFILE_EXTRA_TIMESTAMP   0x5455
120 #define ZIPFILE_NEWENTRY_MADEBY   ((3<<8) + 30)
121 #define ZIPFILE_NEWENTRY_REQUIRED 20
122 #define ZIPFILE_NEWENTRY_FLAGS    0x800
123 #define ZIPFILE_SIGNATURE_CDS     0x02014b50
124 #define ZIPFILE_SIGNATURE_LFH     0x04034b50
125 #define ZIPFILE_SIGNATURE_EOCD    0x06054b50
126 
127 /*
128 ** The sizes of the fixed-size part of each of the three main data
129 ** structures in a zip archive.
130 */
131 #define ZIPFILE_LFH_FIXED_SZ      30
132 #define ZIPFILE_EOCD_FIXED_SZ     22
133 #define ZIPFILE_CDS_FIXED_SZ      46
134 
135 /*
136 *** 4.3.16  End of central directory record:
137 ***
138 ***   end of central dir signature    4 bytes  (0x06054b50)
139 ***   number of this disk             2 bytes
140 ***   number of the disk with the
141 ***   start of the central directory  2 bytes
142 ***   total number of entries in the
143 ***   central directory on this disk  2 bytes
144 ***   total number of entries in
145 ***   the central directory           2 bytes
146 ***   size of the central directory   4 bytes
147 ***   offset of start of central
148 ***   directory with respect to
149 ***   the starting disk number        4 bytes
150 ***   .ZIP file comment length        2 bytes
151 ***   .ZIP file comment       (variable size)
152 */
153 typedef struct ZipfileEOCD ZipfileEOCD;
154 struct ZipfileEOCD {
155   u16 iDisk;
156   u16 iFirstDisk;
157   u16 nEntry;
158   u16 nEntryTotal;
159   u32 nSize;
160   u32 iOffset;
161 };
162 
163 /*
164 *** 4.3.12  Central directory structure:
165 ***
166 *** ...
167 ***
168 ***   central file header signature   4 bytes  (0x02014b50)
169 ***   version made by                 2 bytes
170 ***   version needed to extract       2 bytes
171 ***   general purpose bit flag        2 bytes
172 ***   compression method              2 bytes
173 ***   last mod file time              2 bytes
174 ***   last mod file date              2 bytes
175 ***   crc-32                          4 bytes
176 ***   compressed size                 4 bytes
177 ***   uncompressed size               4 bytes
178 ***   file name length                2 bytes
179 ***   extra field length              2 bytes
180 ***   file comment length             2 bytes
181 ***   disk number start               2 bytes
182 ***   internal file attributes        2 bytes
183 ***   external file attributes        4 bytes
184 ***   relative offset of local header 4 bytes
185 */
186 typedef struct ZipfileCDS ZipfileCDS;
187 struct ZipfileCDS {
188   u16 iVersionMadeBy;
189   u16 iVersionExtract;
190   u16 flags;
191   u16 iCompression;
192   u16 mTime;
193   u16 mDate;
194   u32 crc32;
195   u32 szCompressed;
196   u32 szUncompressed;
197   u16 nFile;
198   u16 nExtra;
199   u16 nComment;
200   u16 iDiskStart;
201   u16 iInternalAttr;
202   u32 iExternalAttr;
203   u32 iOffset;
204   char *zFile;                    /* Filename (sqlite3_malloc()) */
205 };
206 
207 /*
208 *** 4.3.7  Local file header:
209 ***
210 ***   local file header signature     4 bytes  (0x04034b50)
211 ***   version needed to extract       2 bytes
212 ***   general purpose bit flag        2 bytes
213 ***   compression method              2 bytes
214 ***   last mod file time              2 bytes
215 ***   last mod file date              2 bytes
216 ***   crc-32                          4 bytes
217 ***   compressed size                 4 bytes
218 ***   uncompressed size               4 bytes
219 ***   file name length                2 bytes
220 ***   extra field length              2 bytes
221 ***
222 */
223 typedef struct ZipfileLFH ZipfileLFH;
224 struct ZipfileLFH {
225   u16 iVersionExtract;
226   u16 flags;
227   u16 iCompression;
228   u16 mTime;
229   u16 mDate;
230   u32 crc32;
231   u32 szCompressed;
232   u32 szUncompressed;
233   u16 nFile;
234   u16 nExtra;
235 };
236 
237 typedef struct ZipfileEntry ZipfileEntry;
238 struct ZipfileEntry {
239   ZipfileCDS cds;            /* Parsed CDS record */
240   u32 mUnixTime;             /* Modification time, in UNIX format */
241   u8 *aExtra;                /* cds.nExtra+cds.nComment bytes of extra data */
242   i64 iDataOff;              /* Offset to data in file (if aData==0) */
243   u8 *aData;                 /* cds.szCompressed bytes of compressed data */
244   ZipfileEntry *pNext;       /* Next element in in-memory CDS */
245 };
246 
247 /*
248 ** Cursor type for zipfile tables.
249 */
250 typedef struct ZipfileCsr ZipfileCsr;
251 struct ZipfileCsr {
252   sqlite3_vtab_cursor base;  /* Base class - must be first */
253   i64 iId;                   /* Cursor ID */
254   u8 bEof;                   /* True when at EOF */
255   u8 bNoop;                  /* If next xNext() call is no-op */
256 
257   /* Used outside of write transactions */
258   FILE *pFile;               /* Zip file */
259   i64 iNextOff;              /* Offset of next record in central directory */
260   ZipfileEOCD eocd;          /* Parse of central directory record */
261 
262   ZipfileEntry *pFreeEntry;  /* Free this list when cursor is closed or reset */
263   ZipfileEntry *pCurrent;    /* Current entry */
264   ZipfileCsr *pCsrNext;      /* Next cursor on same virtual table */
265 };
266 
267 typedef struct ZipfileTab ZipfileTab;
268 struct ZipfileTab {
269   sqlite3_vtab base;         /* Base class - must be first */
270   char *zFile;               /* Zip file this table accesses (may be NULL) */
271   sqlite3 *db;               /* Host database connection */
272   u8 *aBuffer;               /* Temporary buffer used for various tasks */
273 
274   ZipfileCsr *pCsrList;      /* List of cursors */
275   i64 iNextCsrid;
276 
277   /* The following are used by write transactions only */
278   ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */
279   ZipfileEntry *pLastEntry;  /* Last element in pFirstEntry list */
280   FILE *pWriteFd;            /* File handle open on zip archive */
281   i64 szCurrent;             /* Current size of zip archive */
282   i64 szOrig;                /* Size of archive at start of transaction */
283 };
284 
285 /*
286 ** Set the error message contained in context ctx to the results of
287 ** vprintf(zFmt, ...).
288 */
289 static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
290   char *zMsg = 0;
291   va_list ap;
292   va_start(ap, zFmt);
293   zMsg = sqlite3_vmprintf(zFmt, ap);
294   sqlite3_result_error(ctx, zMsg, -1);
295   sqlite3_free(zMsg);
296   va_end(ap);
297 }
298 
299 /*
300 ** If string zIn is quoted, dequote it in place. Otherwise, if the string
301 ** is not quoted, do nothing.
302 */
303 static void zipfileDequote(char *zIn){
304   char q = zIn[0];
305   if( q=='"' || q=='\'' || q=='`' || q=='[' ){
306     int iIn = 1;
307     int iOut = 0;
308     if( q=='[' ) q = ']';
309     while( ALWAYS(zIn[iIn]) ){
310       char c = zIn[iIn++];
311       if( c==q && zIn[iIn++]!=q ) break;
312       zIn[iOut++] = c;
313     }
314     zIn[iOut] = '\0';
315   }
316 }
317 
318 /*
319 ** Construct a new ZipfileTab virtual table object.
320 **
321 **   argv[0]   -> module name  ("zipfile")
322 **   argv[1]   -> database name
323 **   argv[2]   -> table name
324 **   argv[...] -> "column name" and other module argument fields.
325 */
326 static int zipfileConnect(
327   sqlite3 *db,
328   void *pAux,
329   int argc, const char *const*argv,
330   sqlite3_vtab **ppVtab,
331   char **pzErr
332 ){
333   int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE;
334   int nFile = 0;
335   const char *zFile = 0;
336   ZipfileTab *pNew = 0;
337   int rc;
338 
339   /* If the table name is not "zipfile", require that the argument be
340   ** specified. This stops zipfile tables from being created as:
341   **
342   **   CREATE VIRTUAL TABLE zzz USING zipfile();
343   **
344   ** It does not prevent:
345   **
346   **   CREATE VIRTUAL TABLE zipfile USING zipfile();
347   */
348   assert( 0==sqlite3_stricmp(argv[0], "zipfile") );
349   if( (0!=sqlite3_stricmp(argv[2], "zipfile") && argc<4) || argc>4 ){
350     *pzErr = sqlite3_mprintf("zipfile constructor requires one argument");
351     return SQLITE_ERROR;
352   }
353 
354   if( argc>3 ){
355     zFile = argv[3];
356     nFile = (int)strlen(zFile)+1;
357   }
358 
359   rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);
360   if( rc==SQLITE_OK ){
361     pNew = (ZipfileTab*)sqlite3_malloc64((sqlite3_int64)nByte+nFile);
362     if( pNew==0 ) return SQLITE_NOMEM;
363     memset(pNew, 0, nByte+nFile);
364     pNew->db = db;
365     pNew->aBuffer = (u8*)&pNew[1];
366     if( zFile ){
367       pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE];
368       memcpy(pNew->zFile, zFile, nFile);
369       zipfileDequote(pNew->zFile);
370     }
371   }
372   sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
373   *ppVtab = (sqlite3_vtab*)pNew;
374   return rc;
375 }
376 
377 /*
378 ** Free the ZipfileEntry structure indicated by the only argument.
379 */
380 static void zipfileEntryFree(ZipfileEntry *p){
381   if( p ){
382     sqlite3_free(p->cds.zFile);
383     sqlite3_free(p);
384   }
385 }
386 
387 /*
388 ** Release resources that should be freed at the end of a write
389 ** transaction.
390 */
391 static void zipfileCleanupTransaction(ZipfileTab *pTab){
392   ZipfileEntry *pEntry;
393   ZipfileEntry *pNext;
394 
395   if( pTab->pWriteFd ){
396     fclose(pTab->pWriteFd);
397     pTab->pWriteFd = 0;
398   }
399   for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){
400     pNext = pEntry->pNext;
401     zipfileEntryFree(pEntry);
402   }
403   pTab->pFirstEntry = 0;
404   pTab->pLastEntry = 0;
405   pTab->szCurrent = 0;
406   pTab->szOrig = 0;
407 }
408 
409 /*
410 ** This method is the destructor for zipfile vtab objects.
411 */
412 static int zipfileDisconnect(sqlite3_vtab *pVtab){
413   zipfileCleanupTransaction((ZipfileTab*)pVtab);
414   sqlite3_free(pVtab);
415   return SQLITE_OK;
416 }
417 
418 /*
419 ** Constructor for a new ZipfileCsr object.
420 */
421 static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
422   ZipfileTab *pTab = (ZipfileTab*)p;
423   ZipfileCsr *pCsr;
424   pCsr = sqlite3_malloc(sizeof(*pCsr));
425   *ppCsr = (sqlite3_vtab_cursor*)pCsr;
426   if( pCsr==0 ){
427     return SQLITE_NOMEM;
428   }
429   memset(pCsr, 0, sizeof(*pCsr));
430   pCsr->iId = ++pTab->iNextCsrid;
431   pCsr->pCsrNext = pTab->pCsrList;
432   pTab->pCsrList = pCsr;
433   return SQLITE_OK;
434 }
435 
436 /*
437 ** Reset a cursor back to the state it was in when first returned
438 ** by zipfileOpen().
439 */
440 static void zipfileResetCursor(ZipfileCsr *pCsr){
441   ZipfileEntry *p;
442   ZipfileEntry *pNext;
443 
444   pCsr->bEof = 0;
445   if( pCsr->pFile ){
446     fclose(pCsr->pFile);
447     pCsr->pFile = 0;
448     zipfileEntryFree(pCsr->pCurrent);
449     pCsr->pCurrent = 0;
450   }
451 
452   for(p=pCsr->pFreeEntry; p; p=pNext){
453     pNext = p->pNext;
454     zipfileEntryFree(p);
455   }
456 }
457 
458 /*
459 ** Destructor for an ZipfileCsr.
460 */
461 static int zipfileClose(sqlite3_vtab_cursor *cur){
462   ZipfileCsr *pCsr = (ZipfileCsr*)cur;
463   ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab);
464   ZipfileCsr **pp;
465   zipfileResetCursor(pCsr);
466 
467   /* Remove this cursor from the ZipfileTab.pCsrList list. */
468   for(pp=&pTab->pCsrList; *pp!=pCsr; pp=&((*pp)->pCsrNext));
469   *pp = pCsr->pCsrNext;
470 
471   sqlite3_free(pCsr);
472   return SQLITE_OK;
473 }
474 
475 /*
476 ** Set the error message for the virtual table associated with cursor
477 ** pCsr to the results of vprintf(zFmt, ...).
478 */
479 static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){
480   va_list ap;
481   va_start(ap, zFmt);
482   sqlite3_free(pTab->base.zErrMsg);
483   pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap);
484   va_end(ap);
485 }
486 static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){
487   va_list ap;
488   va_start(ap, zFmt);
489   sqlite3_free(pCsr->base.pVtab->zErrMsg);
490   pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
491   va_end(ap);
492 }
493 
494 /*
495 ** Read nRead bytes of data from offset iOff of file pFile into buffer
496 ** aRead[]. Return SQLITE_OK if successful, or an SQLite error code
497 ** otherwise.
498 **
499 ** If an error does occur, output variable (*pzErrmsg) may be set to point
500 ** to an English language error message. It is the responsibility of the
501 ** caller to eventually free this buffer using
502 ** sqlite3_free().
503 */
504 static int zipfileReadData(
505   FILE *pFile,                    /* Read from this file */
506   u8 *aRead,                      /* Read into this buffer */
507   int nRead,                      /* Number of bytes to read */
508   i64 iOff,                       /* Offset to read from */
509   char **pzErrmsg                 /* OUT: Error message (from sqlite3_malloc) */
510 ){
511   size_t n;
512   fseek(pFile, (long)iOff, SEEK_SET);
513   n = fread(aRead, 1, nRead, pFile);
514   if( (int)n!=nRead ){
515     *pzErrmsg = sqlite3_mprintf("error in fread()");
516     return SQLITE_ERROR;
517   }
518   return SQLITE_OK;
519 }
520 
521 static int zipfileAppendData(
522   ZipfileTab *pTab,
523   const u8 *aWrite,
524   int nWrite
525 ){
526   if( nWrite>0 ){
527     size_t n = nWrite;
528     fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
529     n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
530     if( (int)n!=nWrite ){
531       pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
532       return SQLITE_ERROR;
533     }
534     pTab->szCurrent += nWrite;
535   }
536   return SQLITE_OK;
537 }
538 
539 /*
540 ** Read and return a 16-bit little-endian unsigned integer from buffer aBuf.
541 */
542 static u16 zipfileGetU16(const u8 *aBuf){
543   return (aBuf[1] << 8) + aBuf[0];
544 }
545 
546 /*
547 ** Read and return a 32-bit little-endian unsigned integer from buffer aBuf.
548 */
549 static u32 zipfileGetU32(const u8 *aBuf){
550   return ((u32)(aBuf[3]) << 24)
551        + ((u32)(aBuf[2]) << 16)
552        + ((u32)(aBuf[1]) <<  8)
553        + ((u32)(aBuf[0]) <<  0);
554 }
555 
556 /*
557 ** Write a 16-bit little endiate integer into buffer aBuf.
558 */
559 static void zipfilePutU16(u8 *aBuf, u16 val){
560   aBuf[0] = val & 0xFF;
561   aBuf[1] = (val>>8) & 0xFF;
562 }
563 
564 /*
565 ** Write a 32-bit little endiate integer into buffer aBuf.
566 */
567 static void zipfilePutU32(u8 *aBuf, u32 val){
568   aBuf[0] = val & 0xFF;
569   aBuf[1] = (val>>8) & 0xFF;
570   aBuf[2] = (val>>16) & 0xFF;
571   aBuf[3] = (val>>24) & 0xFF;
572 }
573 
574 #define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) )
575 #define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) )
576 
577 #define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; }
578 #define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; }
579 
580 /*
581 ** Magic numbers used to read CDS records.
582 */
583 #define ZIPFILE_CDS_NFILE_OFF        28
584 #define ZIPFILE_CDS_SZCOMPRESSED_OFF 20
585 
586 /*
587 ** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR
588 ** if the record is not well-formed, or SQLITE_OK otherwise.
589 */
590 static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){
591   u8 *aRead = aBuf;
592   u32 sig = zipfileRead32(aRead);
593   int rc = SQLITE_OK;
594   if( sig!=ZIPFILE_SIGNATURE_CDS ){
595     rc = SQLITE_ERROR;
596   }else{
597     pCDS->iVersionMadeBy = zipfileRead16(aRead);
598     pCDS->iVersionExtract = zipfileRead16(aRead);
599     pCDS->flags = zipfileRead16(aRead);
600     pCDS->iCompression = zipfileRead16(aRead);
601     pCDS->mTime = zipfileRead16(aRead);
602     pCDS->mDate = zipfileRead16(aRead);
603     pCDS->crc32 = zipfileRead32(aRead);
604     pCDS->szCompressed = zipfileRead32(aRead);
605     pCDS->szUncompressed = zipfileRead32(aRead);
606     assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
607     pCDS->nFile = zipfileRead16(aRead);
608     pCDS->nExtra = zipfileRead16(aRead);
609     pCDS->nComment = zipfileRead16(aRead);
610     pCDS->iDiskStart = zipfileRead16(aRead);
611     pCDS->iInternalAttr = zipfileRead16(aRead);
612     pCDS->iExternalAttr = zipfileRead32(aRead);
613     pCDS->iOffset = zipfileRead32(aRead);
614     assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] );
615   }
616 
617   return rc;
618 }
619 
620 /*
621 ** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR
622 ** if the record is not well-formed, or SQLITE_OK otherwise.
623 */
624 static int zipfileReadLFH(
625   u8 *aBuffer,
626   ZipfileLFH *pLFH
627 ){
628   u8 *aRead = aBuffer;
629   int rc = SQLITE_OK;
630 
631   u32 sig = zipfileRead32(aRead);
632   if( sig!=ZIPFILE_SIGNATURE_LFH ){
633     rc = SQLITE_ERROR;
634   }else{
635     pLFH->iVersionExtract = zipfileRead16(aRead);
636     pLFH->flags = zipfileRead16(aRead);
637     pLFH->iCompression = zipfileRead16(aRead);
638     pLFH->mTime = zipfileRead16(aRead);
639     pLFH->mDate = zipfileRead16(aRead);
640     pLFH->crc32 = zipfileRead32(aRead);
641     pLFH->szCompressed = zipfileRead32(aRead);
642     pLFH->szUncompressed = zipfileRead32(aRead);
643     pLFH->nFile = zipfileRead16(aRead);
644     pLFH->nExtra = zipfileRead16(aRead);
645   }
646   return rc;
647 }
648 
649 
650 /*
651 ** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields.
652 ** Scan through this buffer to find an "extra-timestamp" field. If one
653 ** exists, extract the 32-bit modification-timestamp from it and store
654 ** the value in output parameter *pmTime.
655 **
656 ** Zero is returned if no extra-timestamp record could be found (and so
657 ** *pmTime is left unchanged), or non-zero otherwise.
658 **
659 ** The general format of an extra field is:
660 **
661 **   Header ID    2 bytes
662 **   Data Size    2 bytes
663 **   Data         N bytes
664 */
665 static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){
666   int ret = 0;
667   u8 *p = aExtra;
668   u8 *pEnd = &aExtra[nExtra];
669 
670   while( p<pEnd ){
671     u16 id = zipfileRead16(p);
672     u16 nByte = zipfileRead16(p);
673 
674     switch( id ){
675       case ZIPFILE_EXTRA_TIMESTAMP: {
676         u8 b = p[0];
677         if( b & 0x01 ){     /* 0x01 -> modtime is present */
678           *pmTime = zipfileGetU32(&p[1]);
679           ret = 1;
680         }
681         break;
682       }
683     }
684 
685     p += nByte;
686   }
687   return ret;
688 }
689 
690 /*
691 ** Convert the standard MS-DOS timestamp stored in the mTime and mDate
692 ** fields of the CDS structure passed as the only argument to a 32-bit
693 ** UNIX seconds-since-the-epoch timestamp. Return the result.
694 **
695 ** "Standard" MS-DOS time format:
696 **
697 **   File modification time:
698 **     Bits 00-04: seconds divided by 2
699 **     Bits 05-10: minute
700 **     Bits 11-15: hour
701 **   File modification date:
702 **     Bits 00-04: day
703 **     Bits 05-08: month (1-12)
704 **     Bits 09-15: years from 1980
705 **
706 ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx
707 */
708 static u32 zipfileMtime(ZipfileCDS *pCDS){
709   int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
710   int M = ((pCDS->mDate >> 5) & 0x0F);
711   int D = (pCDS->mDate & 0x1F);
712   int B = -13;
713 
714   int sec = (pCDS->mTime & 0x1F)*2;
715   int min = (pCDS->mTime >> 5) & 0x3F;
716   int hr = (pCDS->mTime >> 11) & 0x1F;
717   i64 JD;
718 
719   /* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */
720 
721   /* Calculate the JD in seconds for noon on the day in question */
722   if( M<3 ){
723     Y = Y-1;
724     M = M+12;
725   }
726   JD = (i64)(24*60*60) * (
727       (int)(365.25 * (Y + 4716))
728     + (int)(30.6001 * (M + 1))
729     + D + B - 1524
730   );
731 
732   /* Correct the JD for the time within the day */
733   JD += (hr-12) * 3600 + min * 60 + sec;
734 
735   /* Convert JD to unix timestamp (the JD epoch is 2440587.5) */
736   return (u32)(JD - (i64)(24405875) * 24*60*6);
737 }
738 
739 /*
740 ** The opposite of zipfileMtime(). This function populates the mTime and
741 ** mDate fields of the CDS structure passed as the first argument according
742 ** to the UNIX timestamp value passed as the second.
743 */
744 static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){
745   /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */
746   i64 JD = (i64)2440588 + mUnixTime / (24*60*60);
747 
748   int A, B, C, D, E;
749   int yr, mon, day;
750   int hr, min, sec;
751 
752   A = (int)((JD - 1867216.25)/36524.25);
753   A = (int)(JD + 1 + A - (A/4));
754   B = A + 1524;
755   C = (int)((B - 122.1)/365.25);
756   D = (36525*(C&32767))/100;
757   E = (int)((B-D)/30.6001);
758 
759   day = B - D - (int)(30.6001*E);
760   mon = (E<14 ? E-1 : E-13);
761   yr = mon>2 ? C-4716 : C-4715;
762 
763   hr = (mUnixTime % (24*60*60)) / (60*60);
764   min = (mUnixTime % (60*60)) / 60;
765   sec = (mUnixTime % 60);
766 
767   if( yr>=1980 ){
768     pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9));
769     pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11));
770   }else{
771     pCds->mDate = pCds->mTime = 0;
772   }
773 
774   assert( mUnixTime<315507600
775        || mUnixTime==zipfileMtime(pCds)
776        || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds))
777        /* || (mUnixTime % 2) */
778   );
779 }
780 
781 /*
782 ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in
783 ** size) containing an entire zip archive image. Or, if aBlob is NULL,
784 ** then pFile is a file-handle open on a zip file. In either case, this
785 ** function creates a ZipfileEntry object based on the zip archive entry
786 ** for which the CDS record is at offset iOff.
787 **
788 ** If successful, SQLITE_OK is returned and (*ppEntry) set to point to
789 ** the new object. Otherwise, an SQLite error code is returned and the
790 ** final value of (*ppEntry) undefined.
791 */
792 static int zipfileGetEntry(
793   ZipfileTab *pTab,               /* Store any error message here */
794   const u8 *aBlob,                /* Pointer to in-memory file image */
795   int nBlob,                      /* Size of aBlob[] in bytes */
796   FILE *pFile,                    /* If aBlob==0, read from this file */
797   i64 iOff,                       /* Offset of CDS record */
798   ZipfileEntry **ppEntry          /* OUT: Pointer to new object */
799 ){
800   u8 *aRead;
801   char **pzErr = &pTab->base.zErrMsg;
802   int rc = SQLITE_OK;
803 
804   if( aBlob==0 ){
805     aRead = pTab->aBuffer;
806     rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr);
807   }else{
808     aRead = (u8*)&aBlob[iOff];
809   }
810 
811   if( rc==SQLITE_OK ){
812     sqlite3_int64 nAlloc;
813     ZipfileEntry *pNew;
814 
815     int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]);
816     int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]);
817     nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]);
818 
819     nAlloc = sizeof(ZipfileEntry) + nExtra;
820     if( aBlob ){
821       nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]);
822     }
823 
824     pNew = (ZipfileEntry*)sqlite3_malloc64(nAlloc);
825     if( pNew==0 ){
826       rc = SQLITE_NOMEM;
827     }else{
828       memset(pNew, 0, sizeof(ZipfileEntry));
829       rc = zipfileReadCDS(aRead, &pNew->cds);
830       if( rc!=SQLITE_OK ){
831         *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff);
832       }else if( aBlob==0 ){
833         rc = zipfileReadData(
834             pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr
835         );
836       }else{
837         aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ];
838       }
839     }
840 
841     if( rc==SQLITE_OK ){
842       u32 *pt = &pNew->mUnixTime;
843       pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead);
844       pNew->aExtra = (u8*)&pNew[1];
845       memcpy(pNew->aExtra, &aRead[nFile], nExtra);
846       if( pNew->cds.zFile==0 ){
847         rc = SQLITE_NOMEM;
848       }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){
849         pNew->mUnixTime = zipfileMtime(&pNew->cds);
850       }
851     }
852 
853     if( rc==SQLITE_OK ){
854       static const int szFix = ZIPFILE_LFH_FIXED_SZ;
855       ZipfileLFH lfh;
856       if( pFile ){
857         rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr);
858       }else{
859         aRead = (u8*)&aBlob[pNew->cds.iOffset];
860       }
861 
862       rc = zipfileReadLFH(aRead, &lfh);
863       if( rc==SQLITE_OK ){
864         pNew->iDataOff =  pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
865         pNew->iDataOff += lfh.nFile + lfh.nExtra;
866         if( aBlob && pNew->cds.szCompressed ){
867           pNew->aData = &pNew->aExtra[nExtra];
868           memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
869         }
870       }else{
871         *pzErr = sqlite3_mprintf("failed to read LFH at offset %d",
872             (int)pNew->cds.iOffset
873         );
874       }
875     }
876 
877     if( rc!=SQLITE_OK ){
878       zipfileEntryFree(pNew);
879     }else{
880       *ppEntry = pNew;
881     }
882   }
883 
884   return rc;
885 }
886 
887 /*
888 ** Advance an ZipfileCsr to its next row of output.
889 */
890 static int zipfileNext(sqlite3_vtab_cursor *cur){
891   ZipfileCsr *pCsr = (ZipfileCsr*)cur;
892   int rc = SQLITE_OK;
893 
894   if( pCsr->pFile ){
895     i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize;
896     zipfileEntryFree(pCsr->pCurrent);
897     pCsr->pCurrent = 0;
898     if( pCsr->iNextOff>=iEof ){
899       pCsr->bEof = 1;
900     }else{
901       ZipfileEntry *p = 0;
902       ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab);
903       rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p);
904       if( rc==SQLITE_OK ){
905         pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ;
906         pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment;
907       }
908       pCsr->pCurrent = p;
909     }
910   }else{
911     if( !pCsr->bNoop ){
912       pCsr->pCurrent = pCsr->pCurrent->pNext;
913     }
914     if( pCsr->pCurrent==0 ){
915       pCsr->bEof = 1;
916     }
917   }
918 
919   pCsr->bNoop = 0;
920   return rc;
921 }
922 
923 static void zipfileFree(void *p) {
924   sqlite3_free(p);
925 }
926 
927 /*
928 ** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the
929 ** size is nOut bytes. This function uncompresses the data and sets the
930 ** return value in context pCtx to the result (a blob).
931 **
932 ** If an error occurs, an error code is left in pCtx instead.
933 */
934 static void zipfileInflate(
935   sqlite3_context *pCtx,          /* Store result here */
936   const u8 *aIn,                  /* Compressed data */
937   int nIn,                        /* Size of buffer aIn[] in bytes */
938   int nOut                        /* Expected output size */
939 ){
940   u8 *aRes = sqlite3_malloc(nOut);
941   if( aRes==0 ){
942     sqlite3_result_error_nomem(pCtx);
943   }else{
944     int err;
945     z_stream str;
946     memset(&str, 0, sizeof(str));
947 
948     str.next_in = (Byte*)aIn;
949     str.avail_in = nIn;
950     str.next_out = (Byte*)aRes;
951     str.avail_out = nOut;
952 
953     err = inflateInit2(&str, -15);
954     if( err!=Z_OK ){
955       zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err);
956     }else{
957       err = inflate(&str, Z_NO_FLUSH);
958       if( err!=Z_STREAM_END ){
959         zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err);
960       }else{
961         sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree);
962         aRes = 0;
963       }
964     }
965     sqlite3_free(aRes);
966     inflateEnd(&str);
967   }
968 }
969 
970 /*
971 ** Buffer aIn (size nIn bytes) contains uncompressed data. This function
972 ** compresses it and sets (*ppOut) to point to a buffer containing the
973 ** compressed data. The caller is responsible for eventually calling
974 ** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut)
975 ** is set to the size of buffer (*ppOut) in bytes.
976 **
977 ** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error
978 ** code is returned and an error message left in virtual-table handle
979 ** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this
980 ** case.
981 */
982 static int zipfileDeflate(
983   const u8 *aIn, int nIn,         /* Input */
984   u8 **ppOut, int *pnOut,         /* Output */
985   char **pzErr                    /* OUT: Error message */
986 ){
987   int rc = SQLITE_OK;
988   sqlite3_int64 nAlloc;
989   z_stream str;
990   u8 *aOut;
991 
992   memset(&str, 0, sizeof(str));
993   str.next_in = (Bytef*)aIn;
994   str.avail_in = nIn;
995   deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
996 
997   nAlloc = deflateBound(&str, nIn);
998   aOut = (u8*)sqlite3_malloc64(nAlloc);
999   if( aOut==0 ){
1000     rc = SQLITE_NOMEM;
1001   }else{
1002     int res;
1003     str.next_out = aOut;
1004     str.avail_out = nAlloc;
1005     res = deflate(&str, Z_FINISH);
1006     if( res==Z_STREAM_END ){
1007       *ppOut = aOut;
1008       *pnOut = (int)str.total_out;
1009     }else{
1010       sqlite3_free(aOut);
1011       *pzErr = sqlite3_mprintf("zipfile: deflate() error");
1012       rc = SQLITE_ERROR;
1013     }
1014     deflateEnd(&str);
1015   }
1016 
1017   return rc;
1018 }
1019 
1020 
1021 /*
1022 ** Return values of columns for the row at which the series_cursor
1023 ** is currently pointing.
1024 */
1025 static int zipfileColumn(
1026   sqlite3_vtab_cursor *cur,   /* The cursor */
1027   sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
1028   int i                       /* Which column to return */
1029 ){
1030   ZipfileCsr *pCsr = (ZipfileCsr*)cur;
1031   ZipfileCDS *pCDS = &pCsr->pCurrent->cds;
1032   int rc = SQLITE_OK;
1033   switch( i ){
1034     case 0:   /* name */
1035       sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT);
1036       break;
1037     case 1:   /* mode */
1038       /* TODO: Whether or not the following is correct surely depends on
1039       ** the platform on which the archive was created.  */
1040       sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16);
1041       break;
1042     case 2: { /* mtime */
1043       sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime);
1044       break;
1045     }
1046     case 3: { /* sz */
1047       if( sqlite3_vtab_nochange(ctx)==0 ){
1048         sqlite3_result_int64(ctx, pCDS->szUncompressed);
1049       }
1050       break;
1051     }
1052     case 4:   /* rawdata */
1053       if( sqlite3_vtab_nochange(ctx) ) break;
1054     case 5: { /* data */
1055       if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){
1056         int sz = pCDS->szCompressed;
1057         int szFinal = pCDS->szUncompressed;
1058         if( szFinal>0 ){
1059           u8 *aBuf;
1060           u8 *aFree = 0;
1061           if( pCsr->pCurrent->aData ){
1062             aBuf = pCsr->pCurrent->aData;
1063           }else{
1064             aBuf = aFree = sqlite3_malloc64(sz);
1065             if( aBuf==0 ){
1066               rc = SQLITE_NOMEM;
1067             }else{
1068               FILE *pFile = pCsr->pFile;
1069               if( pFile==0 ){
1070                 pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd;
1071               }
1072               rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff,
1073                   &pCsr->base.pVtab->zErrMsg
1074               );
1075             }
1076           }
1077           if( rc==SQLITE_OK ){
1078             if( i==5 && pCDS->iCompression ){
1079               zipfileInflate(ctx, aBuf, sz, szFinal);
1080             }else{
1081               sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
1082             }
1083           }
1084           sqlite3_free(aFree);
1085         }else{
1086           /* Figure out if this is a directory or a zero-sized file. Consider
1087           ** it to be a directory either if the mode suggests so, or if
1088           ** the final character in the name is '/'.  */
1089           u32 mode = pCDS->iExternalAttr >> 16;
1090           if( !(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile-1]!='/' ){
1091             sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC);
1092           }
1093         }
1094       }
1095       break;
1096     }
1097     case 6:   /* method */
1098       sqlite3_result_int(ctx, pCDS->iCompression);
1099       break;
1100     default:  /* z */
1101       assert( i==7 );
1102       sqlite3_result_int64(ctx, pCsr->iId);
1103       break;
1104   }
1105 
1106   return rc;
1107 }
1108 
1109 /*
1110 ** Return TRUE if the cursor is at EOF.
1111 */
1112 static int zipfileEof(sqlite3_vtab_cursor *cur){
1113   ZipfileCsr *pCsr = (ZipfileCsr*)cur;
1114   return pCsr->bEof;
1115 }
1116 
1117 /*
1118 ** If aBlob is not NULL, then it points to a buffer nBlob bytes in size
1119 ** containing an entire zip archive image. Or, if aBlob is NULL, then pFile
1120 ** is guaranteed to be a file-handle open on a zip file.
1121 **
1122 ** This function attempts to locate the EOCD record within the zip archive
1123 ** and populate *pEOCD with the results of decoding it. SQLITE_OK is
1124 ** returned if successful. Otherwise, an SQLite error code is returned and
1125 ** an English language error message may be left in virtual-table pTab.
1126 */
1127 static int zipfileReadEOCD(
1128   ZipfileTab *pTab,               /* Return errors here */
1129   const u8 *aBlob,                /* Pointer to in-memory file image */
1130   int nBlob,                      /* Size of aBlob[] in bytes */
1131   FILE *pFile,                    /* Read from this file if aBlob==0 */
1132   ZipfileEOCD *pEOCD              /* Object to populate */
1133 ){
1134   u8 *aRead = pTab->aBuffer;      /* Temporary buffer */
1135   int nRead;                      /* Bytes to read from file */
1136   int rc = SQLITE_OK;
1137 
1138   if( aBlob==0 ){
1139     i64 iOff;                     /* Offset to read from */
1140     i64 szFile;                   /* Total size of file in bytes */
1141     fseek(pFile, 0, SEEK_END);
1142     szFile = (i64)ftell(pFile);
1143     if( szFile==0 ){
1144       memset(pEOCD, 0, sizeof(ZipfileEOCD));
1145       return SQLITE_OK;
1146     }
1147     nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
1148     iOff = szFile - nRead;
1149     rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg);
1150   }else{
1151     nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE));
1152     aRead = (u8*)&aBlob[nBlob-nRead];
1153   }
1154 
1155   if( rc==SQLITE_OK ){
1156     int i;
1157 
1158     /* Scan backwards looking for the signature bytes */
1159     for(i=nRead-20; i>=0; i--){
1160       if( aRead[i]==0x50 && aRead[i+1]==0x4b
1161        && aRead[i+2]==0x05 && aRead[i+3]==0x06
1162       ){
1163         break;
1164       }
1165     }
1166     if( i<0 ){
1167       pTab->base.zErrMsg = sqlite3_mprintf(
1168           "cannot find end of central directory record"
1169       );
1170       return SQLITE_ERROR;
1171     }
1172 
1173     aRead += i+4;
1174     pEOCD->iDisk = zipfileRead16(aRead);
1175     pEOCD->iFirstDisk = zipfileRead16(aRead);
1176     pEOCD->nEntry = zipfileRead16(aRead);
1177     pEOCD->nEntryTotal = zipfileRead16(aRead);
1178     pEOCD->nSize = zipfileRead32(aRead);
1179     pEOCD->iOffset = zipfileRead32(aRead);
1180   }
1181 
1182   return rc;
1183 }
1184 
1185 /*
1186 ** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry
1187 ** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added
1188 ** to the end of the list. Otherwise, it is added to the list immediately
1189 ** before pBefore (which is guaranteed to be a part of said list).
1190 */
1191 static void zipfileAddEntry(
1192   ZipfileTab *pTab,
1193   ZipfileEntry *pBefore,
1194   ZipfileEntry *pNew
1195 ){
1196   assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) );
1197   assert( pNew->pNext==0 );
1198   if( pBefore==0 ){
1199     if( pTab->pFirstEntry==0 ){
1200       pTab->pFirstEntry = pTab->pLastEntry = pNew;
1201     }else{
1202       assert( pTab->pLastEntry->pNext==0 );
1203       pTab->pLastEntry->pNext = pNew;
1204       pTab->pLastEntry = pNew;
1205     }
1206   }else{
1207     ZipfileEntry **pp;
1208     for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext));
1209     pNew->pNext = pBefore;
1210     *pp = pNew;
1211   }
1212 }
1213 
1214 static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){
1215   ZipfileEOCD eocd;
1216   int rc;
1217   int i;
1218   i64 iOff;
1219 
1220   rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd);
1221   iOff = eocd.iOffset;
1222   for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){
1223     ZipfileEntry *pNew = 0;
1224     rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew);
1225 
1226     if( rc==SQLITE_OK ){
1227       zipfileAddEntry(pTab, 0, pNew);
1228       iOff += ZIPFILE_CDS_FIXED_SZ;
1229       iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment;
1230     }
1231   }
1232   return rc;
1233 }
1234 
1235 /*
1236 ** xFilter callback.
1237 */
1238 static int zipfileFilter(
1239   sqlite3_vtab_cursor *cur,
1240   int idxNum, const char *idxStr,
1241   int argc, sqlite3_value **argv
1242 ){
1243   ZipfileTab *pTab = (ZipfileTab*)cur->pVtab;
1244   ZipfileCsr *pCsr = (ZipfileCsr*)cur;
1245   const char *zFile = 0;          /* Zip file to scan */
1246   int rc = SQLITE_OK;             /* Return Code */
1247   int bInMemory = 0;              /* True for an in-memory zipfile */
1248 
1249   zipfileResetCursor(pCsr);
1250 
1251   if( pTab->zFile ){
1252     zFile = pTab->zFile;
1253   }else if( idxNum==0 ){
1254     zipfileCursorErr(pCsr, "zipfile() function requires an argument");
1255     return SQLITE_ERROR;
1256   }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
1257     const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
1258     int nBlob = sqlite3_value_bytes(argv[0]);
1259     assert( pTab->pFirstEntry==0 );
1260     rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
1261     pCsr->pFreeEntry = pTab->pFirstEntry;
1262     pTab->pFirstEntry = pTab->pLastEntry = 0;
1263     if( rc!=SQLITE_OK ) return rc;
1264     bInMemory = 1;
1265   }else{
1266     zFile = (const char*)sqlite3_value_text(argv[0]);
1267   }
1268 
1269   if( 0==pTab->pWriteFd && 0==bInMemory ){
1270     pCsr->pFile = fopen(zFile, "rb");
1271     if( pCsr->pFile==0 ){
1272       zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
1273       rc = SQLITE_ERROR;
1274     }else{
1275       rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd);
1276       if( rc==SQLITE_OK ){
1277         if( pCsr->eocd.nEntry==0 ){
1278           pCsr->bEof = 1;
1279         }else{
1280           pCsr->iNextOff = pCsr->eocd.iOffset;
1281           rc = zipfileNext(cur);
1282         }
1283       }
1284     }
1285   }else{
1286     pCsr->bNoop = 1;
1287     pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry;
1288     rc = zipfileNext(cur);
1289   }
1290 
1291   return rc;
1292 }
1293 
1294 /*
1295 ** xBestIndex callback.
1296 */
1297 static int zipfileBestIndex(
1298   sqlite3_vtab *tab,
1299   sqlite3_index_info *pIdxInfo
1300 ){
1301   int i;
1302   int idx = -1;
1303   int unusable = 0;
1304 
1305   for(i=0; i<pIdxInfo->nConstraint; i++){
1306     const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
1307     if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
1308     if( pCons->usable==0 ){
1309       unusable = 1;
1310     }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
1311       idx = i;
1312     }
1313   }
1314   pIdxInfo->estimatedCost = 1000.0;
1315   if( idx>=0 ){
1316     pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
1317     pIdxInfo->aConstraintUsage[idx].omit = 1;
1318     pIdxInfo->idxNum = 1;
1319   }else if( unusable ){
1320     return SQLITE_CONSTRAINT;
1321   }
1322   return SQLITE_OK;
1323 }
1324 
1325 static ZipfileEntry *zipfileNewEntry(const char *zPath){
1326   ZipfileEntry *pNew;
1327   pNew = sqlite3_malloc(sizeof(ZipfileEntry));
1328   if( pNew ){
1329     memset(pNew, 0, sizeof(ZipfileEntry));
1330     pNew->cds.zFile = sqlite3_mprintf("%s", zPath);
1331     if( pNew->cds.zFile==0 ){
1332       sqlite3_free(pNew);
1333       pNew = 0;
1334     }
1335   }
1336   return pNew;
1337 }
1338 
1339 static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){
1340   ZipfileCDS *pCds = &pEntry->cds;
1341   u8 *a = aBuf;
1342 
1343   pCds->nExtra = 9;
1344 
1345   /* Write the LFH itself */
1346   zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH);
1347   zipfileWrite16(a, pCds->iVersionExtract);
1348   zipfileWrite16(a, pCds->flags);
1349   zipfileWrite16(a, pCds->iCompression);
1350   zipfileWrite16(a, pCds->mTime);
1351   zipfileWrite16(a, pCds->mDate);
1352   zipfileWrite32(a, pCds->crc32);
1353   zipfileWrite32(a, pCds->szCompressed);
1354   zipfileWrite32(a, pCds->szUncompressed);
1355   zipfileWrite16(a, (u16)pCds->nFile);
1356   zipfileWrite16(a, pCds->nExtra);
1357   assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] );
1358 
1359   /* Add the file name */
1360   memcpy(a, pCds->zFile, (int)pCds->nFile);
1361   a += (int)pCds->nFile;
1362 
1363   /* The "extra" data */
1364   zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
1365   zipfileWrite16(a, 5);
1366   *a++ = 0x01;
1367   zipfileWrite32(a, pEntry->mUnixTime);
1368 
1369   return a-aBuf;
1370 }
1371 
1372 static int zipfileAppendEntry(
1373   ZipfileTab *pTab,
1374   ZipfileEntry *pEntry,
1375   const u8 *pData,
1376   int nData
1377 ){
1378   u8 *aBuf = pTab->aBuffer;
1379   int nBuf;
1380   int rc;
1381 
1382   nBuf = zipfileSerializeLFH(pEntry, aBuf);
1383   rc = zipfileAppendData(pTab, aBuf, nBuf);
1384   if( rc==SQLITE_OK ){
1385     pEntry->iDataOff = pTab->szCurrent;
1386     rc = zipfileAppendData(pTab, pData, nData);
1387   }
1388 
1389   return rc;
1390 }
1391 
1392 static int zipfileGetMode(
1393   sqlite3_value *pVal,
1394   int bIsDir,                     /* If true, default to directory */
1395   u32 *pMode,                     /* OUT: Mode value */
1396   char **pzErr                    /* OUT: Error message */
1397 ){
1398   const char *z = (const char*)sqlite3_value_text(pVal);
1399   u32 mode = 0;
1400   if( z==0 ){
1401     mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644));
1402   }else if( z[0]>='0' && z[0]<='9' ){
1403     mode = (unsigned int)sqlite3_value_int(pVal);
1404   }else{
1405     const char zTemplate[11] = "-rwxrwxrwx";
1406     int i;
1407     if( strlen(z)!=10 ) goto parse_error;
1408     switch( z[0] ){
1409       case '-': mode |= S_IFREG; break;
1410       case 'd': mode |= S_IFDIR; break;
1411       case 'l': mode |= S_IFLNK; break;
1412       default: goto parse_error;
1413     }
1414     for(i=1; i<10; i++){
1415       if( z[i]==zTemplate[i] ) mode |= 1 << (9-i);
1416       else if( z[i]!='-' ) goto parse_error;
1417     }
1418   }
1419   if( ((mode & S_IFDIR)==0)==bIsDir ){
1420     /* The "mode" attribute is a directory, but data has been specified.
1421     ** Or vice-versa - no data but "mode" is a file or symlink.  */
1422     *pzErr = sqlite3_mprintf("zipfile: mode does not match data");
1423     return SQLITE_CONSTRAINT;
1424   }
1425   *pMode = mode;
1426   return SQLITE_OK;
1427 
1428  parse_error:
1429   *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z);
1430   return SQLITE_ERROR;
1431 }
1432 
1433 /*
1434 ** Both (const char*) arguments point to nul-terminated strings. Argument
1435 ** nB is the value of strlen(zB). This function returns 0 if the strings are
1436 ** identical, ignoring any trailing '/' character in either path.  */
1437 static int zipfileComparePath(const char *zA, const char *zB, int nB){
1438   int nA = (int)strlen(zA);
1439   if( nA>0 && zA[nA-1]=='/' ) nA--;
1440   if( nB>0 && zB[nB-1]=='/' ) nB--;
1441   if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
1442   return 1;
1443 }
1444 
1445 static int zipfileBegin(sqlite3_vtab *pVtab){
1446   ZipfileTab *pTab = (ZipfileTab*)pVtab;
1447   int rc = SQLITE_OK;
1448 
1449   assert( pTab->pWriteFd==0 );
1450   if( pTab->zFile==0 || pTab->zFile[0]==0 ){
1451     pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename");
1452     return SQLITE_ERROR;
1453   }
1454 
1455   /* Open a write fd on the file. Also load the entire central directory
1456   ** structure into memory. During the transaction any new file data is
1457   ** appended to the archive file, but the central directory is accumulated
1458   ** in main-memory until the transaction is committed.  */
1459   pTab->pWriteFd = fopen(pTab->zFile, "ab+");
1460   if( pTab->pWriteFd==0 ){
1461     pTab->base.zErrMsg = sqlite3_mprintf(
1462         "zipfile: failed to open file %s for writing", pTab->zFile
1463         );
1464     rc = SQLITE_ERROR;
1465   }else{
1466     fseek(pTab->pWriteFd, 0, SEEK_END);
1467     pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd);
1468     rc = zipfileLoadDirectory(pTab, 0, 0);
1469   }
1470 
1471   if( rc!=SQLITE_OK ){
1472     zipfileCleanupTransaction(pTab);
1473   }
1474 
1475   return rc;
1476 }
1477 
1478 /*
1479 ** Return the current time as a 32-bit timestamp in UNIX epoch format (like
1480 ** time(2)).
1481 */
1482 static u32 zipfileTime(void){
1483   sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
1484   u32 ret;
1485   if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
1486     i64 ms;
1487     pVfs->xCurrentTimeInt64(pVfs, &ms);
1488     ret = (u32)((ms/1000) - ((i64)24405875 * 8640));
1489   }else{
1490     double day;
1491     pVfs->xCurrentTime(pVfs, &day);
1492     ret = (u32)((day - 2440587.5) * 86400);
1493   }
1494   return ret;
1495 }
1496 
1497 /*
1498 ** Return a 32-bit timestamp in UNIX epoch format.
1499 **
1500 ** If the value passed as the only argument is either NULL or an SQL NULL,
1501 ** return the current time. Otherwise, return the value stored in (*pVal)
1502 ** cast to a 32-bit unsigned integer.
1503 */
1504 static u32 zipfileGetTime(sqlite3_value *pVal){
1505   if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
1506     return zipfileTime();
1507   }
1508   return (u32)sqlite3_value_int64(pVal);
1509 }
1510 
1511 /*
1512 ** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry
1513 ** linked list.  Remove it from the list and free the object.
1514 */
1515 static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){
1516   if( pOld ){
1517     ZipfileEntry **pp;
1518     for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext));
1519     *pp = (*pp)->pNext;
1520     zipfileEntryFree(pOld);
1521   }
1522 }
1523 
1524 /*
1525 ** xUpdate method.
1526 */
1527 static int zipfileUpdate(
1528   sqlite3_vtab *pVtab,
1529   int nVal,
1530   sqlite3_value **apVal,
1531   sqlite_int64 *pRowid
1532 ){
1533   ZipfileTab *pTab = (ZipfileTab*)pVtab;
1534   int rc = SQLITE_OK;             /* Return Code */
1535   ZipfileEntry *pNew = 0;         /* New in-memory CDS entry */
1536 
1537   u32 mode = 0;                   /* Mode for new entry */
1538   u32 mTime = 0;                  /* Modification time for new entry */
1539   i64 sz = 0;                     /* Uncompressed size */
1540   const char *zPath = 0;          /* Path for new entry */
1541   int nPath = 0;                  /* strlen(zPath) */
1542   const u8 *pData = 0;            /* Pointer to buffer containing content */
1543   int nData = 0;                  /* Size of pData buffer in bytes */
1544   int iMethod = 0;                /* Compression method for new entry */
1545   u8 *pFree = 0;                  /* Free this */
1546   char *zFree = 0;                /* Also free this */
1547   ZipfileEntry *pOld = 0;
1548   ZipfileEntry *pOld2 = 0;
1549   int bUpdate = 0;                /* True for an update that modifies "name" */
1550   int bIsDir = 0;
1551   u32 iCrc32 = 0;
1552 
1553   if( pTab->pWriteFd==0 ){
1554     rc = zipfileBegin(pVtab);
1555     if( rc!=SQLITE_OK ) return rc;
1556   }
1557 
1558   /* If this is a DELETE or UPDATE, find the archive entry to delete. */
1559   if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
1560     const char *zDelete = (const char*)sqlite3_value_text(apVal[0]);
1561     int nDelete = (int)strlen(zDelete);
1562     if( nVal>1 ){
1563       const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]);
1564       if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
1565         bUpdate = 1;
1566       }
1567     }
1568     for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
1569       if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
1570         break;
1571       }
1572       assert( pOld->pNext );
1573     }
1574   }
1575 
1576   if( nVal>1 ){
1577     /* Check that "sz" and "rawdata" are both NULL: */
1578     if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){
1579       zipfileTableErr(pTab, "sz must be NULL");
1580       rc = SQLITE_CONSTRAINT;
1581     }
1582     if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){
1583       zipfileTableErr(pTab, "rawdata must be NULL");
1584       rc = SQLITE_CONSTRAINT;
1585     }
1586 
1587     if( rc==SQLITE_OK ){
1588       if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){
1589         /* data=NULL. A directory */
1590         bIsDir = 1;
1591       }else{
1592         /* Value specified for "data", and possibly "method". This must be
1593         ** a regular file or a symlink. */
1594         const u8 *aIn = sqlite3_value_blob(apVal[7]);
1595         int nIn = sqlite3_value_bytes(apVal[7]);
1596         int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL;
1597 
1598         iMethod = sqlite3_value_int(apVal[8]);
1599         sz = nIn;
1600         pData = aIn;
1601         nData = nIn;
1602         if( iMethod!=0 && iMethod!=8 ){
1603           zipfileTableErr(pTab, "unknown compression method: %d", iMethod);
1604           rc = SQLITE_CONSTRAINT;
1605         }else{
1606           if( bAuto || iMethod ){
1607             int nCmp;
1608             rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg);
1609             if( rc==SQLITE_OK ){
1610               if( iMethod || nCmp<nIn ){
1611                 iMethod = 8;
1612                 pData = pFree;
1613                 nData = nCmp;
1614               }
1615             }
1616           }
1617           iCrc32 = crc32(0, aIn, nIn);
1618         }
1619       }
1620     }
1621 
1622     if( rc==SQLITE_OK ){
1623       rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg);
1624     }
1625 
1626     if( rc==SQLITE_OK ){
1627       zPath = (const char*)sqlite3_value_text(apVal[2]);
1628       if( zPath==0 ) zPath = "";
1629       nPath = (int)strlen(zPath);
1630       mTime = zipfileGetTime(apVal[4]);
1631     }
1632 
1633     if( rc==SQLITE_OK && bIsDir ){
1634       /* For a directory, check that the last character in the path is a
1635       ** '/'. This appears to be required for compatibility with info-zip
1636       ** (the unzip command on unix). It does not create directories
1637       ** otherwise.  */
1638       if( nPath<=0 || zPath[nPath-1]!='/' ){
1639         zFree = sqlite3_mprintf("%s/", zPath);
1640         zPath = (const char*)zFree;
1641         if( zFree==0 ){
1642           rc = SQLITE_NOMEM;
1643           nPath = 0;
1644         }else{
1645           nPath = (int)strlen(zPath);
1646         }
1647       }
1648     }
1649 
1650     /* Check that we're not inserting a duplicate entry -OR- updating an
1651     ** entry with a path, thereby making it into a duplicate. */
1652     if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
1653       ZipfileEntry *p;
1654       for(p=pTab->pFirstEntry; p; p=p->pNext){
1655         if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){
1656           switch( sqlite3_vtab_on_conflict(pTab->db) ){
1657             case SQLITE_IGNORE: {
1658               goto zipfile_update_done;
1659             }
1660             case SQLITE_REPLACE: {
1661               pOld2 = p;
1662               break;
1663             }
1664             default: {
1665               zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath);
1666               rc = SQLITE_CONSTRAINT;
1667               break;
1668             }
1669           }
1670           break;
1671         }
1672       }
1673     }
1674 
1675     if( rc==SQLITE_OK ){
1676       /* Create the new CDS record. */
1677       pNew = zipfileNewEntry(zPath);
1678       if( pNew==0 ){
1679         rc = SQLITE_NOMEM;
1680       }else{
1681         pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
1682         pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
1683         pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS;
1684         pNew->cds.iCompression = (u16)iMethod;
1685         zipfileMtimeToDos(&pNew->cds, mTime);
1686         pNew->cds.crc32 = iCrc32;
1687         pNew->cds.szCompressed = nData;
1688         pNew->cds.szUncompressed = (u32)sz;
1689         pNew->cds.iExternalAttr = (mode<<16);
1690         pNew->cds.iOffset = (u32)pTab->szCurrent;
1691         pNew->cds.nFile = (u16)nPath;
1692         pNew->mUnixTime = (u32)mTime;
1693         rc = zipfileAppendEntry(pTab, pNew, pData, nData);
1694         zipfileAddEntry(pTab, pOld, pNew);
1695       }
1696     }
1697   }
1698 
1699   if( rc==SQLITE_OK && (pOld || pOld2) ){
1700     ZipfileCsr *pCsr;
1701     for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
1702       if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){
1703         pCsr->pCurrent = pCsr->pCurrent->pNext;
1704         pCsr->bNoop = 1;
1705       }
1706     }
1707 
1708     zipfileRemoveEntryFromList(pTab, pOld);
1709     zipfileRemoveEntryFromList(pTab, pOld2);
1710   }
1711 
1712 zipfile_update_done:
1713   sqlite3_free(pFree);
1714   sqlite3_free(zFree);
1715   return rc;
1716 }
1717 
1718 static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){
1719   u8 *a = aBuf;
1720   zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD);
1721   zipfileWrite16(a, p->iDisk);
1722   zipfileWrite16(a, p->iFirstDisk);
1723   zipfileWrite16(a, p->nEntry);
1724   zipfileWrite16(a, p->nEntryTotal);
1725   zipfileWrite32(a, p->nSize);
1726   zipfileWrite32(a, p->iOffset);
1727   zipfileWrite16(a, 0);        /* Size of trailing comment in bytes*/
1728 
1729   return a-aBuf;
1730 }
1731 
1732 static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){
1733   int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer);
1734   assert( nBuf==ZIPFILE_EOCD_FIXED_SZ );
1735   return zipfileAppendData(pTab, pTab->aBuffer, nBuf);
1736 }
1737 
1738 /*
1739 ** Serialize the CDS structure into buffer aBuf[]. Return the number
1740 ** of bytes written.
1741 */
1742 static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){
1743   u8 *a = aBuf;
1744   ZipfileCDS *pCDS = &pEntry->cds;
1745 
1746   if( pEntry->aExtra==0 ){
1747     pCDS->nExtra = 9;
1748   }
1749 
1750   zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS);
1751   zipfileWrite16(a, pCDS->iVersionMadeBy);
1752   zipfileWrite16(a, pCDS->iVersionExtract);
1753   zipfileWrite16(a, pCDS->flags);
1754   zipfileWrite16(a, pCDS->iCompression);
1755   zipfileWrite16(a, pCDS->mTime);
1756   zipfileWrite16(a, pCDS->mDate);
1757   zipfileWrite32(a, pCDS->crc32);
1758   zipfileWrite32(a, pCDS->szCompressed);
1759   zipfileWrite32(a, pCDS->szUncompressed);
1760   assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
1761   zipfileWrite16(a, pCDS->nFile);
1762   zipfileWrite16(a, pCDS->nExtra);
1763   zipfileWrite16(a, pCDS->nComment);
1764   zipfileWrite16(a, pCDS->iDiskStart);
1765   zipfileWrite16(a, pCDS->iInternalAttr);
1766   zipfileWrite32(a, pCDS->iExternalAttr);
1767   zipfileWrite32(a, pCDS->iOffset);
1768 
1769   memcpy(a, pCDS->zFile, pCDS->nFile);
1770   a += pCDS->nFile;
1771 
1772   if( pEntry->aExtra ){
1773     int n = (int)pCDS->nExtra + (int)pCDS->nComment;
1774     memcpy(a, pEntry->aExtra, n);
1775     a += n;
1776   }else{
1777     assert( pCDS->nExtra==9 );
1778     zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
1779     zipfileWrite16(a, 5);
1780     *a++ = 0x01;
1781     zipfileWrite32(a, pEntry->mUnixTime);
1782   }
1783 
1784   return a-aBuf;
1785 }
1786 
1787 static int zipfileCommit(sqlite3_vtab *pVtab){
1788   ZipfileTab *pTab = (ZipfileTab*)pVtab;
1789   int rc = SQLITE_OK;
1790   if( pTab->pWriteFd ){
1791     i64 iOffset = pTab->szCurrent;
1792     ZipfileEntry *p;
1793     ZipfileEOCD eocd;
1794     int nEntry = 0;
1795 
1796     /* Write out all entries */
1797     for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){
1798       int n = zipfileSerializeCDS(p, pTab->aBuffer);
1799       rc = zipfileAppendData(pTab, pTab->aBuffer, n);
1800       nEntry++;
1801     }
1802 
1803     /* Write out the EOCD record */
1804     eocd.iDisk = 0;
1805     eocd.iFirstDisk = 0;
1806     eocd.nEntry = (u16)nEntry;
1807     eocd.nEntryTotal = (u16)nEntry;
1808     eocd.nSize = (u32)(pTab->szCurrent - iOffset);
1809     eocd.iOffset = (u32)iOffset;
1810     rc = zipfileAppendEOCD(pTab, &eocd);
1811 
1812     zipfileCleanupTransaction(pTab);
1813   }
1814   return rc;
1815 }
1816 
1817 static int zipfileRollback(sqlite3_vtab *pVtab){
1818   return zipfileCommit(pVtab);
1819 }
1820 
1821 static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){
1822   ZipfileCsr *pCsr;
1823   for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
1824     if( iId==pCsr->iId ) break;
1825   }
1826   return pCsr;
1827 }
1828 
1829 static void zipfileFunctionCds(
1830   sqlite3_context *context,
1831   int argc,
1832   sqlite3_value **argv
1833 ){
1834   ZipfileCsr *pCsr;
1835   ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
1836   assert( argc>0 );
1837 
1838   pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
1839   if( pCsr ){
1840     ZipfileCDS *p = &pCsr->pCurrent->cds;
1841     char *zRes = sqlite3_mprintf("{"
1842         "\"version-made-by\" : %u, "
1843         "\"version-to-extract\" : %u, "
1844         "\"flags\" : %u, "
1845         "\"compression\" : %u, "
1846         "\"time\" : %u, "
1847         "\"date\" : %u, "
1848         "\"crc32\" : %u, "
1849         "\"compressed-size\" : %u, "
1850         "\"uncompressed-size\" : %u, "
1851         "\"file-name-length\" : %u, "
1852         "\"extra-field-length\" : %u, "
1853         "\"file-comment-length\" : %u, "
1854         "\"disk-number-start\" : %u, "
1855         "\"internal-attr\" : %u, "
1856         "\"external-attr\" : %u, "
1857         "\"offset\" : %u }",
1858         (u32)p->iVersionMadeBy, (u32)p->iVersionExtract,
1859         (u32)p->flags, (u32)p->iCompression,
1860         (u32)p->mTime, (u32)p->mDate,
1861         (u32)p->crc32, (u32)p->szCompressed,
1862         (u32)p->szUncompressed, (u32)p->nFile,
1863         (u32)p->nExtra, (u32)p->nComment,
1864         (u32)p->iDiskStart, (u32)p->iInternalAttr,
1865         (u32)p->iExternalAttr, (u32)p->iOffset
1866     );
1867 
1868     if( zRes==0 ){
1869       sqlite3_result_error_nomem(context);
1870     }else{
1871       sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
1872       sqlite3_free(zRes);
1873     }
1874   }
1875 }
1876 
1877 /*
1878 ** xFindFunction method.
1879 */
1880 static int zipfileFindFunction(
1881   sqlite3_vtab *pVtab,            /* Virtual table handle */
1882   int nArg,                       /* Number of SQL function arguments */
1883   const char *zName,              /* Name of SQL function */
1884   void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
1885   void **ppArg                    /* OUT: User data for *pxFunc */
1886 ){
1887   if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
1888     *pxFunc = zipfileFunctionCds;
1889     *ppArg = (void*)pVtab;
1890     return 1;
1891   }
1892   return 0;
1893 }
1894 
1895 typedef struct ZipfileBuffer ZipfileBuffer;
1896 struct ZipfileBuffer {
1897   u8 *a;                          /* Pointer to buffer */
1898   int n;                          /* Size of buffer in bytes */
1899   int nAlloc;                     /* Byte allocated at a[] */
1900 };
1901 
1902 typedef struct ZipfileCtx ZipfileCtx;
1903 struct ZipfileCtx {
1904   int nEntry;
1905   ZipfileBuffer body;
1906   ZipfileBuffer cds;
1907 };
1908 
1909 static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
1910   if( pBuf->n+nByte>pBuf->nAlloc ){
1911     u8 *aNew;
1912     sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512;
1913     int nReq = pBuf->n + nByte;
1914 
1915     while( nNew<nReq ) nNew = nNew*2;
1916     aNew = sqlite3_realloc64(pBuf->a, nNew);
1917     if( aNew==0 ) return SQLITE_NOMEM;
1918     pBuf->a = aNew;
1919     pBuf->nAlloc = (int)nNew;
1920   }
1921   return SQLITE_OK;
1922 }
1923 
1924 /*
1925 ** xStep() callback for the zipfile() aggregate. This can be called in
1926 ** any of the following ways:
1927 **
1928 **   SELECT zipfile(name,data) ...
1929 **   SELECT zipfile(name,mode,mtime,data) ...
1930 **   SELECT zipfile(name,mode,mtime,data,method) ...
1931 */
1932 void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
1933   ZipfileCtx *p;                  /* Aggregate function context */
1934   ZipfileEntry e;                 /* New entry to add to zip archive */
1935 
1936   sqlite3_value *pName = 0;
1937   sqlite3_value *pMode = 0;
1938   sqlite3_value *pMtime = 0;
1939   sqlite3_value *pData = 0;
1940   sqlite3_value *pMethod = 0;
1941 
1942   int bIsDir = 0;
1943   u32 mode;
1944   int rc = SQLITE_OK;
1945   char *zErr = 0;
1946 
1947   int iMethod = -1;               /* Compression method to use (0 or 8) */
1948 
1949   const u8 *aData = 0;            /* Possibly compressed data for new entry */
1950   int nData = 0;                  /* Size of aData[] in bytes */
1951   int szUncompressed = 0;         /* Size of data before compression */
1952   u8 *aFree = 0;                  /* Free this before returning */
1953   u32 iCrc32 = 0;                 /* crc32 of uncompressed data */
1954 
1955   char *zName = 0;                /* Path (name) of new entry */
1956   int nName = 0;                  /* Size of zName in bytes */
1957   char *zFree = 0;                /* Free this before returning */
1958   int nByte;
1959 
1960   memset(&e, 0, sizeof(e));
1961   p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
1962   if( p==0 ) return;
1963 
1964   /* Martial the arguments into stack variables */
1965   if( nVal!=2 && nVal!=4 && nVal!=5 ){
1966     zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()");
1967     rc = SQLITE_ERROR;
1968     goto zipfile_step_out;
1969   }
1970   pName = apVal[0];
1971   if( nVal==2 ){
1972     pData = apVal[1];
1973   }else{
1974     pMode = apVal[1];
1975     pMtime = apVal[2];
1976     pData = apVal[3];
1977     if( nVal==5 ){
1978       pMethod = apVal[4];
1979     }
1980   }
1981 
1982   /* Check that the 'name' parameter looks ok. */
1983   zName = (char*)sqlite3_value_text(pName);
1984   nName = sqlite3_value_bytes(pName);
1985   if( zName==0 ){
1986     zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
1987     rc = SQLITE_ERROR;
1988     goto zipfile_step_out;
1989   }
1990 
1991   /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
1992   ** deflate compression) or NULL (choose automatically).  */
1993   if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
1994     iMethod = (int)sqlite3_value_int64(pMethod);
1995     if( iMethod!=0 && iMethod!=8 ){
1996       zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
1997       rc = SQLITE_ERROR;
1998       goto zipfile_step_out;
1999     }
2000   }
2001 
2002   /* Now inspect the data. If this is NULL, then the new entry must be a
2003   ** directory.  Otherwise, figure out whether or not the data should
2004   ** be deflated or simply stored in the zip archive. */
2005   if( sqlite3_value_type(pData)==SQLITE_NULL ){
2006     bIsDir = 1;
2007     iMethod = 0;
2008   }else{
2009     aData = sqlite3_value_blob(pData);
2010     szUncompressed = nData = sqlite3_value_bytes(pData);
2011     iCrc32 = crc32(0, aData, nData);
2012     if( iMethod<0 || iMethod==8 ){
2013       int nOut = 0;
2014       rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr);
2015       if( rc!=SQLITE_OK ){
2016         goto zipfile_step_out;
2017       }
2018       if( iMethod==8 || nOut<nData ){
2019         aData = aFree;
2020         nData = nOut;
2021         iMethod = 8;
2022       }else{
2023         iMethod = 0;
2024       }
2025     }
2026   }
2027 
2028   /* Decode the "mode" argument. */
2029   rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr);
2030   if( rc ) goto zipfile_step_out;
2031 
2032   /* Decode the "mtime" argument. */
2033   e.mUnixTime = zipfileGetTime(pMtime);
2034 
2035   /* If this is a directory entry, ensure that there is exactly one '/'
2036   ** at the end of the path. Or, if this is not a directory and the path
2037   ** ends in '/' it is an error. */
2038   if( bIsDir==0 ){
2039     if( nName>0 && zName[nName-1]=='/' ){
2040       zErr = sqlite3_mprintf("non-directory name must not end with /");
2041       rc = SQLITE_ERROR;
2042       goto zipfile_step_out;
2043     }
2044   }else{
2045     if( nName==0 || zName[nName-1]!='/' ){
2046       zName = zFree = sqlite3_mprintf("%s/", zName);
2047       if( zName==0 ){
2048         rc = SQLITE_NOMEM;
2049         goto zipfile_step_out;
2050       }
2051       nName = (int)strlen(zName);
2052     }else{
2053       while( nName>1 && zName[nName-2]=='/' ) nName--;
2054     }
2055   }
2056 
2057   /* Assemble the ZipfileEntry object for the new zip archive entry */
2058   e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
2059   e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
2060   e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
2061   e.cds.iCompression = (u16)iMethod;
2062   zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
2063   e.cds.crc32 = iCrc32;
2064   e.cds.szCompressed = nData;
2065   e.cds.szUncompressed = szUncompressed;
2066   e.cds.iExternalAttr = (mode<<16);
2067   e.cds.iOffset = p->body.n;
2068   e.cds.nFile = (u16)nName;
2069   e.cds.zFile = zName;
2070 
2071   /* Append the LFH to the body of the new archive */
2072   nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9;
2073   if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out;
2074   p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);
2075 
2076   /* Append the data to the body of the new archive */
2077   if( nData>0 ){
2078     if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out;
2079     memcpy(&p->body.a[p->body.n], aData, nData);
2080     p->body.n += nData;
2081   }
2082 
2083   /* Append the CDS record to the directory of the new archive */
2084   nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9;
2085   if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out;
2086   p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]);
2087 
2088   /* Increment the count of entries in the archive */
2089   p->nEntry++;
2090 
2091  zipfile_step_out:
2092   sqlite3_free(aFree);
2093   sqlite3_free(zFree);
2094   if( rc ){
2095     if( zErr ){
2096       sqlite3_result_error(pCtx, zErr, -1);
2097     }else{
2098       sqlite3_result_error_code(pCtx, rc);
2099     }
2100   }
2101   sqlite3_free(zErr);
2102 }
2103 
2104 /*
2105 ** xFinalize() callback for zipfile aggregate function.
2106 */
2107 void zipfileFinal(sqlite3_context *pCtx){
2108   ZipfileCtx *p;
2109   ZipfileEOCD eocd;
2110   sqlite3_int64 nZip;
2111   u8 *aZip;
2112 
2113   p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
2114   if( p==0 ) return;
2115   if( p->nEntry>0 ){
2116     memset(&eocd, 0, sizeof(eocd));
2117     eocd.nEntry = (u16)p->nEntry;
2118     eocd.nEntryTotal = (u16)p->nEntry;
2119     eocd.nSize = p->cds.n;
2120     eocd.iOffset = p->body.n;
2121 
2122     nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
2123     aZip = (u8*)sqlite3_malloc64(nZip);
2124     if( aZip==0 ){
2125       sqlite3_result_error_nomem(pCtx);
2126     }else{
2127       memcpy(aZip, p->body.a, p->body.n);
2128       memcpy(&aZip[p->body.n], p->cds.a, p->cds.n);
2129       zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]);
2130       sqlite3_result_blob(pCtx, aZip, (int)nZip, zipfileFree);
2131     }
2132   }
2133 
2134   sqlite3_free(p->body.a);
2135   sqlite3_free(p->cds.a);
2136 }
2137 
2138 
2139 /*
2140 ** Register the "zipfile" virtual table.
2141 */
2142 static int zipfileRegister(sqlite3 *db){
2143   static sqlite3_module zipfileModule = {
2144     1,                         /* iVersion */
2145     zipfileConnect,            /* xCreate */
2146     zipfileConnect,            /* xConnect */
2147     zipfileBestIndex,          /* xBestIndex */
2148     zipfileDisconnect,         /* xDisconnect */
2149     zipfileDisconnect,         /* xDestroy */
2150     zipfileOpen,               /* xOpen - open a cursor */
2151     zipfileClose,              /* xClose - close a cursor */
2152     zipfileFilter,             /* xFilter - configure scan constraints */
2153     zipfileNext,               /* xNext - advance a cursor */
2154     zipfileEof,                /* xEof - check for end of scan */
2155     zipfileColumn,             /* xColumn - read data */
2156     0,                         /* xRowid - read data */
2157     zipfileUpdate,             /* xUpdate */
2158     zipfileBegin,              /* xBegin */
2159     0,                         /* xSync */
2160     zipfileCommit,             /* xCommit */
2161     zipfileRollback,           /* xRollback */
2162     zipfileFindFunction,       /* xFindMethod */
2163     0,                         /* xRename */
2164   };
2165 
2166   int rc = sqlite3_create_module(db, "zipfile"  , &zipfileModule, 0);
2167   if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
2168   if( rc==SQLITE_OK ){
2169     rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0,
2170         zipfileStep, zipfileFinal
2171     );
2172   }
2173   return rc;
2174 }
2175 #else         /* SQLITE_OMIT_VIRTUALTABLE */
2176 # define zipfileRegister(x) SQLITE_OK
2177 #endif
2178 
2179 #ifdef _WIN32
2180 __declspec(dllexport)
2181 #endif
2182 int sqlite3_zipfile_init(
2183   sqlite3 *db,
2184   char **pzErrMsg,
2185   const sqlite3_api_routines *pApi
2186 ){
2187   SQLITE_EXTENSION_INIT2(pApi);
2188   (void)pzErrMsg;  /* Unused parameter */
2189   return zipfileRegister(db);
2190 }
2191