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