xref: /sqlite-3.40.0/ext/misc/zipfile.c (revision 76fc88fe)
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   if( aBuf==0 ) return 0;
565   return ((u32)(aBuf[3]) << 24)
566        + ((u32)(aBuf[2]) << 16)
567        + ((u32)(aBuf[1]) <<  8)
568        + ((u32)(aBuf[0]) <<  0);
569 }
570 
571 /*
572 ** Write a 16-bit little endiate integer into buffer aBuf.
573 */
574 static void zipfilePutU16(u8 *aBuf, u16 val){
575   aBuf[0] = val & 0xFF;
576   aBuf[1] = (val>>8) & 0xFF;
577 }
578 
579 /*
580 ** Write a 32-bit little endiate integer into buffer aBuf.
581 */
582 static void zipfilePutU32(u8 *aBuf, u32 val){
583   aBuf[0] = val & 0xFF;
584   aBuf[1] = (val>>8) & 0xFF;
585   aBuf[2] = (val>>16) & 0xFF;
586   aBuf[3] = (val>>24) & 0xFF;
587 }
588 
589 #define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) )
590 #define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) )
591 
592 #define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; }
593 #define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; }
594 
595 /*
596 ** Magic numbers used to read CDS records.
597 */
598 #define ZIPFILE_CDS_NFILE_OFF        28
599 #define ZIPFILE_CDS_SZCOMPRESSED_OFF 20
600 
601 /*
602 ** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR
603 ** if the record is not well-formed, or SQLITE_OK otherwise.
604 */
605 static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){
606   u8 *aRead = aBuf;
607   u32 sig = zipfileRead32(aRead);
608   int rc = SQLITE_OK;
609   if( sig!=ZIPFILE_SIGNATURE_CDS ){
610     rc = SQLITE_ERROR;
611   }else{
612     pCDS->iVersionMadeBy = zipfileRead16(aRead);
613     pCDS->iVersionExtract = zipfileRead16(aRead);
614     pCDS->flags = zipfileRead16(aRead);
615     pCDS->iCompression = zipfileRead16(aRead);
616     pCDS->mTime = zipfileRead16(aRead);
617     pCDS->mDate = zipfileRead16(aRead);
618     pCDS->crc32 = zipfileRead32(aRead);
619     pCDS->szCompressed = zipfileRead32(aRead);
620     pCDS->szUncompressed = zipfileRead32(aRead);
621     assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
622     pCDS->nFile = zipfileRead16(aRead);
623     pCDS->nExtra = zipfileRead16(aRead);
624     pCDS->nComment = zipfileRead16(aRead);
625     pCDS->iDiskStart = zipfileRead16(aRead);
626     pCDS->iInternalAttr = zipfileRead16(aRead);
627     pCDS->iExternalAttr = zipfileRead32(aRead);
628     pCDS->iOffset = zipfileRead32(aRead);
629     assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] );
630   }
631 
632   return rc;
633 }
634 
635 /*
636 ** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR
637 ** if the record is not well-formed, or SQLITE_OK otherwise.
638 */
639 static int zipfileReadLFH(
640   u8 *aBuffer,
641   ZipfileLFH *pLFH
642 ){
643   u8 *aRead = aBuffer;
644   int rc = SQLITE_OK;
645 
646   u32 sig = zipfileRead32(aRead);
647   if( sig!=ZIPFILE_SIGNATURE_LFH ){
648     rc = SQLITE_ERROR;
649   }else{
650     pLFH->iVersionExtract = zipfileRead16(aRead);
651     pLFH->flags = zipfileRead16(aRead);
652     pLFH->iCompression = zipfileRead16(aRead);
653     pLFH->mTime = zipfileRead16(aRead);
654     pLFH->mDate = zipfileRead16(aRead);
655     pLFH->crc32 = zipfileRead32(aRead);
656     pLFH->szCompressed = zipfileRead32(aRead);
657     pLFH->szUncompressed = zipfileRead32(aRead);
658     pLFH->nFile = zipfileRead16(aRead);
659     pLFH->nExtra = zipfileRead16(aRead);
660   }
661   return rc;
662 }
663 
664 
665 /*
666 ** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields.
667 ** Scan through this buffer to find an "extra-timestamp" field. If one
668 ** exists, extract the 32-bit modification-timestamp from it and store
669 ** the value in output parameter *pmTime.
670 **
671 ** Zero is returned if no extra-timestamp record could be found (and so
672 ** *pmTime is left unchanged), or non-zero otherwise.
673 **
674 ** The general format of an extra field is:
675 **
676 **   Header ID    2 bytes
677 **   Data Size    2 bytes
678 **   Data         N bytes
679 */
680 static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){
681   int ret = 0;
682   u8 *p = aExtra;
683   u8 *pEnd = &aExtra[nExtra];
684 
685   while( p<pEnd ){
686     u16 id = zipfileRead16(p);
687     u16 nByte = zipfileRead16(p);
688 
689     switch( id ){
690       case ZIPFILE_EXTRA_TIMESTAMP: {
691         u8 b = p[0];
692         if( b & 0x01 ){     /* 0x01 -> modtime is present */
693           *pmTime = zipfileGetU32(&p[1]);
694           ret = 1;
695         }
696         break;
697       }
698     }
699 
700     p += nByte;
701   }
702   return ret;
703 }
704 
705 /*
706 ** Convert the standard MS-DOS timestamp stored in the mTime and mDate
707 ** fields of the CDS structure passed as the only argument to a 32-bit
708 ** UNIX seconds-since-the-epoch timestamp. Return the result.
709 **
710 ** "Standard" MS-DOS time format:
711 **
712 **   File modification time:
713 **     Bits 00-04: seconds divided by 2
714 **     Bits 05-10: minute
715 **     Bits 11-15: hour
716 **   File modification date:
717 **     Bits 00-04: day
718 **     Bits 05-08: month (1-12)
719 **     Bits 09-15: years from 1980
720 **
721 ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx
722 */
723 static u32 zipfileMtime(ZipfileCDS *pCDS){
724   int Y,M,D,X1,X2,A,B,sec,min,hr;
725   i64 JDsec;
726   Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
727   M = ((pCDS->mDate >> 5) & 0x0F);
728   D = (pCDS->mDate & 0x1F);
729   sec = (pCDS->mTime & 0x1F)*2;
730   min = (pCDS->mTime >> 5) & 0x3F;
731   hr = (pCDS->mTime >> 11) & 0x1F;
732   if( M<=2 ){
733     Y--;
734     M += 12;
735   }
736   X1 = 36525*(Y+4716)/100;
737   X2 = 306001*(M+1)/10000;
738   A = Y/100;
739   B = 2 - A + (A/4);
740   JDsec = (i64)((X1 + X2 + D + B - 1524.5)*86400) + hr*3600 + min*60 + sec;
741   return (u32)(JDsec - (i64)24405875*(i64)8640);
742 }
743 
744 /*
745 ** The opposite of zipfileMtime(). This function populates the mTime and
746 ** mDate fields of the CDS structure passed as the first argument according
747 ** to the UNIX timestamp value passed as the second.
748 */
749 static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){
750   /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */
751   i64 JD = (i64)2440588 + mUnixTime / (24*60*60);
752 
753   int A, B, C, D, E;
754   int yr, mon, day;
755   int hr, min, sec;
756 
757   A = (int)((JD - 1867216.25)/36524.25);
758   A = (int)(JD + 1 + A - (A/4));
759   B = A + 1524;
760   C = (int)((B - 122.1)/365.25);
761   D = (36525*(C&32767))/100;
762   E = (int)((B-D)/30.6001);
763 
764   day = B - D - (int)(30.6001*E);
765   mon = (E<14 ? E-1 : E-13);
766   yr = mon>2 ? C-4716 : C-4715;
767 
768   hr = (mUnixTime % (24*60*60)) / (60*60);
769   min = (mUnixTime % (60*60)) / 60;
770   sec = (mUnixTime % 60);
771 
772   if( yr>=1980 ){
773     pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9));
774     pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11));
775   }else{
776     pCds->mDate = pCds->mTime = 0;
777   }
778 
779   assert( mUnixTime<315507600
780        || mUnixTime==zipfileMtime(pCds)
781        || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds))
782        /* || (mUnixTime % 2) */
783   );
784 }
785 
786 /*
787 ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in
788 ** size) containing an entire zip archive image. Or, if aBlob is NULL,
789 ** then pFile is a file-handle open on a zip file. In either case, this
790 ** function creates a ZipfileEntry object based on the zip archive entry
791 ** for which the CDS record is at offset iOff.
792 **
793 ** If successful, SQLITE_OK is returned and (*ppEntry) set to point to
794 ** the new object. Otherwise, an SQLite error code is returned and the
795 ** final value of (*ppEntry) undefined.
796 */
797 static int zipfileGetEntry(
798   ZipfileTab *pTab,               /* Store any error message here */
799   const u8 *aBlob,                /* Pointer to in-memory file image */
800   int nBlob,                      /* Size of aBlob[] in bytes */
801   FILE *pFile,                    /* If aBlob==0, read from this file */
802   i64 iOff,                       /* Offset of CDS record */
803   ZipfileEntry **ppEntry          /* OUT: Pointer to new object */
804 ){
805   u8 *aRead;
806   char **pzErr = &pTab->base.zErrMsg;
807   int rc = SQLITE_OK;
808 
809   if( aBlob==0 ){
810     aRead = pTab->aBuffer;
811     rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr);
812   }else{
813     aRead = (u8*)&aBlob[iOff];
814   }
815 
816   if( rc==SQLITE_OK ){
817     sqlite3_int64 nAlloc;
818     ZipfileEntry *pNew;
819 
820     int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]);
821     int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]);
822     nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]);
823 
824     nAlloc = sizeof(ZipfileEntry) + nExtra;
825     if( aBlob ){
826       nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]);
827     }
828 
829     pNew = (ZipfileEntry*)sqlite3_malloc64(nAlloc);
830     if( pNew==0 ){
831       rc = SQLITE_NOMEM;
832     }else{
833       memset(pNew, 0, sizeof(ZipfileEntry));
834       rc = zipfileReadCDS(aRead, &pNew->cds);
835       if( rc!=SQLITE_OK ){
836         *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff);
837       }else if( aBlob==0 ){
838         rc = zipfileReadData(
839             pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr
840         );
841       }else{
842         aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ];
843       }
844     }
845 
846     if( rc==SQLITE_OK ){
847       u32 *pt = &pNew->mUnixTime;
848       pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead);
849       pNew->aExtra = (u8*)&pNew[1];
850       memcpy(pNew->aExtra, &aRead[nFile], nExtra);
851       if( pNew->cds.zFile==0 ){
852         rc = SQLITE_NOMEM;
853       }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){
854         pNew->mUnixTime = zipfileMtime(&pNew->cds);
855       }
856     }
857 
858     if( rc==SQLITE_OK ){
859       static const int szFix = ZIPFILE_LFH_FIXED_SZ;
860       ZipfileLFH lfh;
861       if( pFile ){
862         rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr);
863       }else{
864         aRead = (u8*)&aBlob[pNew->cds.iOffset];
865       }
866 
867       if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh);
868       if( rc==SQLITE_OK ){
869         pNew->iDataOff =  pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
870         pNew->iDataOff += lfh.nFile + lfh.nExtra;
871         if( aBlob && pNew->cds.szCompressed ){
872           pNew->aData = &pNew->aExtra[nExtra];
873           memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
874         }
875       }else{
876         *pzErr = sqlite3_mprintf("failed to read LFH at offset %d",
877             (int)pNew->cds.iOffset
878         );
879       }
880     }
881 
882     if( rc!=SQLITE_OK ){
883       zipfileEntryFree(pNew);
884     }else{
885       *ppEntry = pNew;
886     }
887   }
888 
889   return rc;
890 }
891 
892 /*
893 ** Advance an ZipfileCsr to its next row of output.
894 */
895 static int zipfileNext(sqlite3_vtab_cursor *cur){
896   ZipfileCsr *pCsr = (ZipfileCsr*)cur;
897   int rc = SQLITE_OK;
898 
899   if( pCsr->pFile ){
900     i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize;
901     zipfileEntryFree(pCsr->pCurrent);
902     pCsr->pCurrent = 0;
903     if( pCsr->iNextOff>=iEof ){
904       pCsr->bEof = 1;
905     }else{
906       ZipfileEntry *p = 0;
907       ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab);
908       rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p);
909       if( rc==SQLITE_OK ){
910         pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ;
911         pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment;
912       }
913       pCsr->pCurrent = p;
914     }
915   }else{
916     if( !pCsr->bNoop ){
917       pCsr->pCurrent = pCsr->pCurrent->pNext;
918     }
919     if( pCsr->pCurrent==0 ){
920       pCsr->bEof = 1;
921     }
922   }
923 
924   pCsr->bNoop = 0;
925   return rc;
926 }
927 
928 static void zipfileFree(void *p) {
929   sqlite3_free(p);
930 }
931 
932 /*
933 ** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the
934 ** size is nOut bytes. This function uncompresses the data and sets the
935 ** return value in context pCtx to the result (a blob).
936 **
937 ** If an error occurs, an error code is left in pCtx instead.
938 */
939 static void zipfileInflate(
940   sqlite3_context *pCtx,          /* Store result here */
941   const u8 *aIn,                  /* Compressed data */
942   int nIn,                        /* Size of buffer aIn[] in bytes */
943   int nOut                        /* Expected output size */
944 ){
945   u8 *aRes = sqlite3_malloc(nOut);
946   if( aRes==0 ){
947     sqlite3_result_error_nomem(pCtx);
948   }else{
949     int err;
950     z_stream str;
951     memset(&str, 0, sizeof(str));
952 
953     str.next_in = (Byte*)aIn;
954     str.avail_in = nIn;
955     str.next_out = (Byte*)aRes;
956     str.avail_out = nOut;
957 
958     err = inflateInit2(&str, -15);
959     if( err!=Z_OK ){
960       zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err);
961     }else{
962       err = inflate(&str, Z_NO_FLUSH);
963       if( err!=Z_STREAM_END ){
964         zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err);
965       }else{
966         sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree);
967         aRes = 0;
968       }
969     }
970     sqlite3_free(aRes);
971     inflateEnd(&str);
972   }
973 }
974 
975 /*
976 ** Buffer aIn (size nIn bytes) contains uncompressed data. This function
977 ** compresses it and sets (*ppOut) to point to a buffer containing the
978 ** compressed data. The caller is responsible for eventually calling
979 ** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut)
980 ** is set to the size of buffer (*ppOut) in bytes.
981 **
982 ** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error
983 ** code is returned and an error message left in virtual-table handle
984 ** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this
985 ** case.
986 */
987 static int zipfileDeflate(
988   const u8 *aIn, int nIn,         /* Input */
989   u8 **ppOut, int *pnOut,         /* Output */
990   char **pzErr                    /* OUT: Error message */
991 ){
992   int rc = SQLITE_OK;
993   sqlite3_int64 nAlloc;
994   z_stream str;
995   u8 *aOut;
996 
997   memset(&str, 0, sizeof(str));
998   str.next_in = (Bytef*)aIn;
999   str.avail_in = nIn;
1000   deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
1001 
1002   nAlloc = deflateBound(&str, nIn);
1003   aOut = (u8*)sqlite3_malloc64(nAlloc);
1004   if( aOut==0 ){
1005     rc = SQLITE_NOMEM;
1006   }else{
1007     int res;
1008     str.next_out = aOut;
1009     str.avail_out = nAlloc;
1010     res = deflate(&str, Z_FINISH);
1011     if( res==Z_STREAM_END ){
1012       *ppOut = aOut;
1013       *pnOut = (int)str.total_out;
1014     }else{
1015       sqlite3_free(aOut);
1016       *pzErr = sqlite3_mprintf("zipfile: deflate() error");
1017       rc = SQLITE_ERROR;
1018     }
1019     deflateEnd(&str);
1020   }
1021 
1022   return rc;
1023 }
1024 
1025 
1026 /*
1027 ** Return values of columns for the row at which the series_cursor
1028 ** is currently pointing.
1029 */
1030 static int zipfileColumn(
1031   sqlite3_vtab_cursor *cur,   /* The cursor */
1032   sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
1033   int i                       /* Which column to return */
1034 ){
1035   ZipfileCsr *pCsr = (ZipfileCsr*)cur;
1036   ZipfileCDS *pCDS = &pCsr->pCurrent->cds;
1037   int rc = SQLITE_OK;
1038   switch( i ){
1039     case 0:   /* name */
1040       sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT);
1041       break;
1042     case 1:   /* mode */
1043       /* TODO: Whether or not the following is correct surely depends on
1044       ** the platform on which the archive was created.  */
1045       sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16);
1046       break;
1047     case 2: { /* mtime */
1048       sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime);
1049       break;
1050     }
1051     case 3: { /* sz */
1052       if( sqlite3_vtab_nochange(ctx)==0 ){
1053         sqlite3_result_int64(ctx, pCDS->szUncompressed);
1054       }
1055       break;
1056     }
1057     case 4:   /* rawdata */
1058       if( sqlite3_vtab_nochange(ctx) ) break;
1059     case 5: { /* data */
1060       if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){
1061         int sz = pCDS->szCompressed;
1062         int szFinal = pCDS->szUncompressed;
1063         if( szFinal>0 ){
1064           u8 *aBuf;
1065           u8 *aFree = 0;
1066           if( pCsr->pCurrent->aData ){
1067             aBuf = pCsr->pCurrent->aData;
1068           }else{
1069             aBuf = aFree = sqlite3_malloc64(sz);
1070             if( aBuf==0 ){
1071               rc = SQLITE_NOMEM;
1072             }else{
1073               FILE *pFile = pCsr->pFile;
1074               if( pFile==0 ){
1075                 pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd;
1076               }
1077               rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff,
1078                   &pCsr->base.pVtab->zErrMsg
1079               );
1080             }
1081           }
1082           if( rc==SQLITE_OK ){
1083             if( i==5 && pCDS->iCompression ){
1084               zipfileInflate(ctx, aBuf, sz, szFinal);
1085             }else{
1086               sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
1087             }
1088           }
1089           sqlite3_free(aFree);
1090         }else{
1091           /* Figure out if this is a directory or a zero-sized file. Consider
1092           ** it to be a directory either if the mode suggests so, or if
1093           ** the final character in the name is '/'.  */
1094           u32 mode = pCDS->iExternalAttr >> 16;
1095           if( !(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile-1]!='/' ){
1096             sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC);
1097           }
1098         }
1099       }
1100       break;
1101     }
1102     case 6:   /* method */
1103       sqlite3_result_int(ctx, pCDS->iCompression);
1104       break;
1105     default:  /* z */
1106       assert( i==7 );
1107       sqlite3_result_int64(ctx, pCsr->iId);
1108       break;
1109   }
1110 
1111   return rc;
1112 }
1113 
1114 /*
1115 ** Return TRUE if the cursor is at EOF.
1116 */
1117 static int zipfileEof(sqlite3_vtab_cursor *cur){
1118   ZipfileCsr *pCsr = (ZipfileCsr*)cur;
1119   return pCsr->bEof;
1120 }
1121 
1122 /*
1123 ** If aBlob is not NULL, then it points to a buffer nBlob bytes in size
1124 ** containing an entire zip archive image. Or, if aBlob is NULL, then pFile
1125 ** is guaranteed to be a file-handle open on a zip file.
1126 **
1127 ** This function attempts to locate the EOCD record within the zip archive
1128 ** and populate *pEOCD with the results of decoding it. SQLITE_OK is
1129 ** returned if successful. Otherwise, an SQLite error code is returned and
1130 ** an English language error message may be left in virtual-table pTab.
1131 */
1132 static int zipfileReadEOCD(
1133   ZipfileTab *pTab,               /* Return errors here */
1134   const u8 *aBlob,                /* Pointer to in-memory file image */
1135   int nBlob,                      /* Size of aBlob[] in bytes */
1136   FILE *pFile,                    /* Read from this file if aBlob==0 */
1137   ZipfileEOCD *pEOCD              /* Object to populate */
1138 ){
1139   u8 *aRead = pTab->aBuffer;      /* Temporary buffer */
1140   int nRead;                      /* Bytes to read from file */
1141   int rc = SQLITE_OK;
1142 
1143   memset(pEOCD, 0, sizeof(ZipfileEOCD));
1144   if( aBlob==0 ){
1145     i64 iOff;                     /* Offset to read from */
1146     i64 szFile;                   /* Total size of file in bytes */
1147     fseek(pFile, 0, SEEK_END);
1148     szFile = (i64)ftell(pFile);
1149     if( szFile==0 ){
1150       return SQLITE_OK;
1151     }
1152     nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
1153     iOff = szFile - nRead;
1154     rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg);
1155   }else{
1156     nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE));
1157     aRead = (u8*)&aBlob[nBlob-nRead];
1158   }
1159 
1160   if( rc==SQLITE_OK ){
1161     int i;
1162 
1163     /* Scan backwards looking for the signature bytes */
1164     for(i=nRead-20; i>=0; i--){
1165       if( aRead[i]==0x50 && aRead[i+1]==0x4b
1166        && aRead[i+2]==0x05 && aRead[i+3]==0x06
1167       ){
1168         break;
1169       }
1170     }
1171     if( i<0 ){
1172       pTab->base.zErrMsg = sqlite3_mprintf(
1173           "cannot find end of central directory record"
1174       );
1175       return SQLITE_ERROR;
1176     }
1177 
1178     aRead += i+4;
1179     pEOCD->iDisk = zipfileRead16(aRead);
1180     pEOCD->iFirstDisk = zipfileRead16(aRead);
1181     pEOCD->nEntry = zipfileRead16(aRead);
1182     pEOCD->nEntryTotal = zipfileRead16(aRead);
1183     pEOCD->nSize = zipfileRead32(aRead);
1184     pEOCD->iOffset = zipfileRead32(aRead);
1185   }
1186 
1187   return rc;
1188 }
1189 
1190 /*
1191 ** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry
1192 ** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added
1193 ** to the end of the list. Otherwise, it is added to the list immediately
1194 ** before pBefore (which is guaranteed to be a part of said list).
1195 */
1196 static void zipfileAddEntry(
1197   ZipfileTab *pTab,
1198   ZipfileEntry *pBefore,
1199   ZipfileEntry *pNew
1200 ){
1201   assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) );
1202   assert( pNew->pNext==0 );
1203   if( pBefore==0 ){
1204     if( pTab->pFirstEntry==0 ){
1205       pTab->pFirstEntry = pTab->pLastEntry = pNew;
1206     }else{
1207       assert( pTab->pLastEntry->pNext==0 );
1208       pTab->pLastEntry->pNext = pNew;
1209       pTab->pLastEntry = pNew;
1210     }
1211   }else{
1212     ZipfileEntry **pp;
1213     for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext));
1214     pNew->pNext = pBefore;
1215     *pp = pNew;
1216   }
1217 }
1218 
1219 static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){
1220   ZipfileEOCD eocd;
1221   int rc;
1222   int i;
1223   i64 iOff;
1224 
1225   rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd);
1226   iOff = eocd.iOffset;
1227   for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){
1228     ZipfileEntry *pNew = 0;
1229     rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew);
1230 
1231     if( rc==SQLITE_OK ){
1232       zipfileAddEntry(pTab, 0, pNew);
1233       iOff += ZIPFILE_CDS_FIXED_SZ;
1234       iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment;
1235     }
1236   }
1237   return rc;
1238 }
1239 
1240 /*
1241 ** xFilter callback.
1242 */
1243 static int zipfileFilter(
1244   sqlite3_vtab_cursor *cur,
1245   int idxNum, const char *idxStr,
1246   int argc, sqlite3_value **argv
1247 ){
1248   ZipfileTab *pTab = (ZipfileTab*)cur->pVtab;
1249   ZipfileCsr *pCsr = (ZipfileCsr*)cur;
1250   const char *zFile = 0;          /* Zip file to scan */
1251   int rc = SQLITE_OK;             /* Return Code */
1252   int bInMemory = 0;              /* True for an in-memory zipfile */
1253 
1254   zipfileResetCursor(pCsr);
1255 
1256   if( pTab->zFile ){
1257     zFile = pTab->zFile;
1258   }else if( idxNum==0 ){
1259     zipfileCursorErr(pCsr, "zipfile() function requires an argument");
1260     return SQLITE_ERROR;
1261   }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
1262     const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
1263     int nBlob = sqlite3_value_bytes(argv[0]);
1264     assert( pTab->pFirstEntry==0 );
1265     rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
1266     pCsr->pFreeEntry = pTab->pFirstEntry;
1267     pTab->pFirstEntry = pTab->pLastEntry = 0;
1268     if( rc!=SQLITE_OK ) return rc;
1269     bInMemory = 1;
1270   }else{
1271     zFile = (const char*)sqlite3_value_text(argv[0]);
1272   }
1273 
1274   if( 0==pTab->pWriteFd && 0==bInMemory ){
1275     pCsr->pFile = fopen(zFile, "rb");
1276     if( pCsr->pFile==0 ){
1277       zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
1278       rc = SQLITE_ERROR;
1279     }else{
1280       rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd);
1281       if( rc==SQLITE_OK ){
1282         if( pCsr->eocd.nEntry==0 ){
1283           pCsr->bEof = 1;
1284         }else{
1285           pCsr->iNextOff = pCsr->eocd.iOffset;
1286           rc = zipfileNext(cur);
1287         }
1288       }
1289     }
1290   }else{
1291     pCsr->bNoop = 1;
1292     pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry;
1293     rc = zipfileNext(cur);
1294   }
1295 
1296   return rc;
1297 }
1298 
1299 /*
1300 ** xBestIndex callback.
1301 */
1302 static int zipfileBestIndex(
1303   sqlite3_vtab *tab,
1304   sqlite3_index_info *pIdxInfo
1305 ){
1306   int i;
1307   int idx = -1;
1308   int unusable = 0;
1309 
1310   for(i=0; i<pIdxInfo->nConstraint; i++){
1311     const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
1312     if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
1313     if( pCons->usable==0 ){
1314       unusable = 1;
1315     }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
1316       idx = i;
1317     }
1318   }
1319   pIdxInfo->estimatedCost = 1000.0;
1320   if( idx>=0 ){
1321     pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
1322     pIdxInfo->aConstraintUsage[idx].omit = 1;
1323     pIdxInfo->idxNum = 1;
1324   }else if( unusable ){
1325     return SQLITE_CONSTRAINT;
1326   }
1327   return SQLITE_OK;
1328 }
1329 
1330 static ZipfileEntry *zipfileNewEntry(const char *zPath){
1331   ZipfileEntry *pNew;
1332   pNew = sqlite3_malloc(sizeof(ZipfileEntry));
1333   if( pNew ){
1334     memset(pNew, 0, sizeof(ZipfileEntry));
1335     pNew->cds.zFile = sqlite3_mprintf("%s", zPath);
1336     if( pNew->cds.zFile==0 ){
1337       sqlite3_free(pNew);
1338       pNew = 0;
1339     }
1340   }
1341   return pNew;
1342 }
1343 
1344 static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){
1345   ZipfileCDS *pCds = &pEntry->cds;
1346   u8 *a = aBuf;
1347 
1348   pCds->nExtra = 9;
1349 
1350   /* Write the LFH itself */
1351   zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH);
1352   zipfileWrite16(a, pCds->iVersionExtract);
1353   zipfileWrite16(a, pCds->flags);
1354   zipfileWrite16(a, pCds->iCompression);
1355   zipfileWrite16(a, pCds->mTime);
1356   zipfileWrite16(a, pCds->mDate);
1357   zipfileWrite32(a, pCds->crc32);
1358   zipfileWrite32(a, pCds->szCompressed);
1359   zipfileWrite32(a, pCds->szUncompressed);
1360   zipfileWrite16(a, (u16)pCds->nFile);
1361   zipfileWrite16(a, pCds->nExtra);
1362   assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] );
1363 
1364   /* Add the file name */
1365   memcpy(a, pCds->zFile, (int)pCds->nFile);
1366   a += (int)pCds->nFile;
1367 
1368   /* The "extra" data */
1369   zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
1370   zipfileWrite16(a, 5);
1371   *a++ = 0x01;
1372   zipfileWrite32(a, pEntry->mUnixTime);
1373 
1374   return a-aBuf;
1375 }
1376 
1377 static int zipfileAppendEntry(
1378   ZipfileTab *pTab,
1379   ZipfileEntry *pEntry,
1380   const u8 *pData,
1381   int nData
1382 ){
1383   u8 *aBuf = pTab->aBuffer;
1384   int nBuf;
1385   int rc;
1386 
1387   nBuf = zipfileSerializeLFH(pEntry, aBuf);
1388   rc = zipfileAppendData(pTab, aBuf, nBuf);
1389   if( rc==SQLITE_OK ){
1390     pEntry->iDataOff = pTab->szCurrent;
1391     rc = zipfileAppendData(pTab, pData, nData);
1392   }
1393 
1394   return rc;
1395 }
1396 
1397 static int zipfileGetMode(
1398   sqlite3_value *pVal,
1399   int bIsDir,                     /* If true, default to directory */
1400   u32 *pMode,                     /* OUT: Mode value */
1401   char **pzErr                    /* OUT: Error message */
1402 ){
1403   const char *z = (const char*)sqlite3_value_text(pVal);
1404   u32 mode = 0;
1405   if( z==0 ){
1406     mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644));
1407   }else if( z[0]>='0' && z[0]<='9' ){
1408     mode = (unsigned int)sqlite3_value_int(pVal);
1409   }else{
1410     const char zTemplate[11] = "-rwxrwxrwx";
1411     int i;
1412     if( strlen(z)!=10 ) goto parse_error;
1413     switch( z[0] ){
1414       case '-': mode |= S_IFREG; break;
1415       case 'd': mode |= S_IFDIR; break;
1416       case 'l': mode |= S_IFLNK; break;
1417       default: goto parse_error;
1418     }
1419     for(i=1; i<10; i++){
1420       if( z[i]==zTemplate[i] ) mode |= 1 << (9-i);
1421       else if( z[i]!='-' ) goto parse_error;
1422     }
1423   }
1424   if( ((mode & S_IFDIR)==0)==bIsDir ){
1425     /* The "mode" attribute is a directory, but data has been specified.
1426     ** Or vice-versa - no data but "mode" is a file or symlink.  */
1427     *pzErr = sqlite3_mprintf("zipfile: mode does not match data");
1428     return SQLITE_CONSTRAINT;
1429   }
1430   *pMode = mode;
1431   return SQLITE_OK;
1432 
1433  parse_error:
1434   *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z);
1435   return SQLITE_ERROR;
1436 }
1437 
1438 /*
1439 ** Both (const char*) arguments point to nul-terminated strings. Argument
1440 ** nB is the value of strlen(zB). This function returns 0 if the strings are
1441 ** identical, ignoring any trailing '/' character in either path.  */
1442 static int zipfileComparePath(const char *zA, const char *zB, int nB){
1443   int nA = (int)strlen(zA);
1444   if( nA>0 && zA[nA-1]=='/' ) nA--;
1445   if( nB>0 && zB[nB-1]=='/' ) nB--;
1446   if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
1447   return 1;
1448 }
1449 
1450 static int zipfileBegin(sqlite3_vtab *pVtab){
1451   ZipfileTab *pTab = (ZipfileTab*)pVtab;
1452   int rc = SQLITE_OK;
1453 
1454   assert( pTab->pWriteFd==0 );
1455   if( pTab->zFile==0 || pTab->zFile[0]==0 ){
1456     pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename");
1457     return SQLITE_ERROR;
1458   }
1459 
1460   /* Open a write fd on the file. Also load the entire central directory
1461   ** structure into memory. During the transaction any new file data is
1462   ** appended to the archive file, but the central directory is accumulated
1463   ** in main-memory until the transaction is committed.  */
1464   pTab->pWriteFd = fopen(pTab->zFile, "ab+");
1465   if( pTab->pWriteFd==0 ){
1466     pTab->base.zErrMsg = sqlite3_mprintf(
1467         "zipfile: failed to open file %s for writing", pTab->zFile
1468         );
1469     rc = SQLITE_ERROR;
1470   }else{
1471     fseek(pTab->pWriteFd, 0, SEEK_END);
1472     pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd);
1473     rc = zipfileLoadDirectory(pTab, 0, 0);
1474   }
1475 
1476   if( rc!=SQLITE_OK ){
1477     zipfileCleanupTransaction(pTab);
1478   }
1479 
1480   return rc;
1481 }
1482 
1483 /*
1484 ** Return the current time as a 32-bit timestamp in UNIX epoch format (like
1485 ** time(2)).
1486 */
1487 static u32 zipfileTime(void){
1488   sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
1489   u32 ret;
1490   if( pVfs==0 ) return 0;
1491   if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
1492     i64 ms;
1493     pVfs->xCurrentTimeInt64(pVfs, &ms);
1494     ret = (u32)((ms/1000) - ((i64)24405875 * 8640));
1495   }else{
1496     double day;
1497     pVfs->xCurrentTime(pVfs, &day);
1498     ret = (u32)((day - 2440587.5) * 86400);
1499   }
1500   return ret;
1501 }
1502 
1503 /*
1504 ** Return a 32-bit timestamp in UNIX epoch format.
1505 **
1506 ** If the value passed as the only argument is either NULL or an SQL NULL,
1507 ** return the current time. Otherwise, return the value stored in (*pVal)
1508 ** cast to a 32-bit unsigned integer.
1509 */
1510 static u32 zipfileGetTime(sqlite3_value *pVal){
1511   if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
1512     return zipfileTime();
1513   }
1514   return (u32)sqlite3_value_int64(pVal);
1515 }
1516 
1517 /*
1518 ** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry
1519 ** linked list.  Remove it from the list and free the object.
1520 */
1521 static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){
1522   if( pOld ){
1523     ZipfileEntry **pp;
1524     for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext));
1525     *pp = (*pp)->pNext;
1526     zipfileEntryFree(pOld);
1527   }
1528 }
1529 
1530 /*
1531 ** xUpdate method.
1532 */
1533 static int zipfileUpdate(
1534   sqlite3_vtab *pVtab,
1535   int nVal,
1536   sqlite3_value **apVal,
1537   sqlite_int64 *pRowid
1538 ){
1539   ZipfileTab *pTab = (ZipfileTab*)pVtab;
1540   int rc = SQLITE_OK;             /* Return Code */
1541   ZipfileEntry *pNew = 0;         /* New in-memory CDS entry */
1542 
1543   u32 mode = 0;                   /* Mode for new entry */
1544   u32 mTime = 0;                  /* Modification time for new entry */
1545   i64 sz = 0;                     /* Uncompressed size */
1546   const char *zPath = 0;          /* Path for new entry */
1547   int nPath = 0;                  /* strlen(zPath) */
1548   const u8 *pData = 0;            /* Pointer to buffer containing content */
1549   int nData = 0;                  /* Size of pData buffer in bytes */
1550   int iMethod = 0;                /* Compression method for new entry */
1551   u8 *pFree = 0;                  /* Free this */
1552   char *zFree = 0;                /* Also free this */
1553   ZipfileEntry *pOld = 0;
1554   ZipfileEntry *pOld2 = 0;
1555   int bUpdate = 0;                /* True for an update that modifies "name" */
1556   int bIsDir = 0;
1557   u32 iCrc32 = 0;
1558 
1559   if( pTab->pWriteFd==0 ){
1560     rc = zipfileBegin(pVtab);
1561     if( rc!=SQLITE_OK ) return rc;
1562   }
1563 
1564   /* If this is a DELETE or UPDATE, find the archive entry to delete. */
1565   if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
1566     const char *zDelete = (const char*)sqlite3_value_text(apVal[0]);
1567     int nDelete = (int)strlen(zDelete);
1568     if( nVal>1 ){
1569       const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]);
1570       if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
1571         bUpdate = 1;
1572       }
1573     }
1574     for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
1575       if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
1576         break;
1577       }
1578       assert( pOld->pNext );
1579     }
1580   }
1581 
1582   if( nVal>1 ){
1583     /* Check that "sz" and "rawdata" are both NULL: */
1584     if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){
1585       zipfileTableErr(pTab, "sz must be NULL");
1586       rc = SQLITE_CONSTRAINT;
1587     }
1588     if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){
1589       zipfileTableErr(pTab, "rawdata must be NULL");
1590       rc = SQLITE_CONSTRAINT;
1591     }
1592 
1593     if( rc==SQLITE_OK ){
1594       if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){
1595         /* data=NULL. A directory */
1596         bIsDir = 1;
1597       }else{
1598         /* Value specified for "data", and possibly "method". This must be
1599         ** a regular file or a symlink. */
1600         const u8 *aIn = sqlite3_value_blob(apVal[7]);
1601         int nIn = sqlite3_value_bytes(apVal[7]);
1602         int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL;
1603 
1604         iMethod = sqlite3_value_int(apVal[8]);
1605         sz = nIn;
1606         pData = aIn;
1607         nData = nIn;
1608         if( iMethod!=0 && iMethod!=8 ){
1609           zipfileTableErr(pTab, "unknown compression method: %d", iMethod);
1610           rc = SQLITE_CONSTRAINT;
1611         }else{
1612           if( bAuto || iMethod ){
1613             int nCmp;
1614             rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg);
1615             if( rc==SQLITE_OK ){
1616               if( iMethod || nCmp<nIn ){
1617                 iMethod = 8;
1618                 pData = pFree;
1619                 nData = nCmp;
1620               }
1621             }
1622           }
1623           iCrc32 = crc32(0, aIn, nIn);
1624         }
1625       }
1626     }
1627 
1628     if( rc==SQLITE_OK ){
1629       rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg);
1630     }
1631 
1632     if( rc==SQLITE_OK ){
1633       zPath = (const char*)sqlite3_value_text(apVal[2]);
1634       if( zPath==0 ) zPath = "";
1635       nPath = (int)strlen(zPath);
1636       mTime = zipfileGetTime(apVal[4]);
1637     }
1638 
1639     if( rc==SQLITE_OK && bIsDir ){
1640       /* For a directory, check that the last character in the path is a
1641       ** '/'. This appears to be required for compatibility with info-zip
1642       ** (the unzip command on unix). It does not create directories
1643       ** otherwise.  */
1644       if( nPath<=0 || zPath[nPath-1]!='/' ){
1645         zFree = sqlite3_mprintf("%s/", zPath);
1646         zPath = (const char*)zFree;
1647         if( zFree==0 ){
1648           rc = SQLITE_NOMEM;
1649           nPath = 0;
1650         }else{
1651           nPath = (int)strlen(zPath);
1652         }
1653       }
1654     }
1655 
1656     /* Check that we're not inserting a duplicate entry -OR- updating an
1657     ** entry with a path, thereby making it into a duplicate. */
1658     if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
1659       ZipfileEntry *p;
1660       for(p=pTab->pFirstEntry; p; p=p->pNext){
1661         if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){
1662           switch( sqlite3_vtab_on_conflict(pTab->db) ){
1663             case SQLITE_IGNORE: {
1664               goto zipfile_update_done;
1665             }
1666             case SQLITE_REPLACE: {
1667               pOld2 = p;
1668               break;
1669             }
1670             default: {
1671               zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath);
1672               rc = SQLITE_CONSTRAINT;
1673               break;
1674             }
1675           }
1676           break;
1677         }
1678       }
1679     }
1680 
1681     if( rc==SQLITE_OK ){
1682       /* Create the new CDS record. */
1683       pNew = zipfileNewEntry(zPath);
1684       if( pNew==0 ){
1685         rc = SQLITE_NOMEM;
1686       }else{
1687         pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
1688         pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
1689         pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS;
1690         pNew->cds.iCompression = (u16)iMethod;
1691         zipfileMtimeToDos(&pNew->cds, mTime);
1692         pNew->cds.crc32 = iCrc32;
1693         pNew->cds.szCompressed = nData;
1694         pNew->cds.szUncompressed = (u32)sz;
1695         pNew->cds.iExternalAttr = (mode<<16);
1696         pNew->cds.iOffset = (u32)pTab->szCurrent;
1697         pNew->cds.nFile = (u16)nPath;
1698         pNew->mUnixTime = (u32)mTime;
1699         rc = zipfileAppendEntry(pTab, pNew, pData, nData);
1700         zipfileAddEntry(pTab, pOld, pNew);
1701       }
1702     }
1703   }
1704 
1705   if( rc==SQLITE_OK && (pOld || pOld2) ){
1706     ZipfileCsr *pCsr;
1707     for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
1708       if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){
1709         pCsr->pCurrent = pCsr->pCurrent->pNext;
1710         pCsr->bNoop = 1;
1711       }
1712     }
1713 
1714     zipfileRemoveEntryFromList(pTab, pOld);
1715     zipfileRemoveEntryFromList(pTab, pOld2);
1716   }
1717 
1718 zipfile_update_done:
1719   sqlite3_free(pFree);
1720   sqlite3_free(zFree);
1721   return rc;
1722 }
1723 
1724 static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){
1725   u8 *a = aBuf;
1726   zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD);
1727   zipfileWrite16(a, p->iDisk);
1728   zipfileWrite16(a, p->iFirstDisk);
1729   zipfileWrite16(a, p->nEntry);
1730   zipfileWrite16(a, p->nEntryTotal);
1731   zipfileWrite32(a, p->nSize);
1732   zipfileWrite32(a, p->iOffset);
1733   zipfileWrite16(a, 0);        /* Size of trailing comment in bytes*/
1734 
1735   return a-aBuf;
1736 }
1737 
1738 static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){
1739   int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer);
1740   assert( nBuf==ZIPFILE_EOCD_FIXED_SZ );
1741   return zipfileAppendData(pTab, pTab->aBuffer, nBuf);
1742 }
1743 
1744 /*
1745 ** Serialize the CDS structure into buffer aBuf[]. Return the number
1746 ** of bytes written.
1747 */
1748 static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){
1749   u8 *a = aBuf;
1750   ZipfileCDS *pCDS = &pEntry->cds;
1751 
1752   if( pEntry->aExtra==0 ){
1753     pCDS->nExtra = 9;
1754   }
1755 
1756   zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS);
1757   zipfileWrite16(a, pCDS->iVersionMadeBy);
1758   zipfileWrite16(a, pCDS->iVersionExtract);
1759   zipfileWrite16(a, pCDS->flags);
1760   zipfileWrite16(a, pCDS->iCompression);
1761   zipfileWrite16(a, pCDS->mTime);
1762   zipfileWrite16(a, pCDS->mDate);
1763   zipfileWrite32(a, pCDS->crc32);
1764   zipfileWrite32(a, pCDS->szCompressed);
1765   zipfileWrite32(a, pCDS->szUncompressed);
1766   assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
1767   zipfileWrite16(a, pCDS->nFile);
1768   zipfileWrite16(a, pCDS->nExtra);
1769   zipfileWrite16(a, pCDS->nComment);
1770   zipfileWrite16(a, pCDS->iDiskStart);
1771   zipfileWrite16(a, pCDS->iInternalAttr);
1772   zipfileWrite32(a, pCDS->iExternalAttr);
1773   zipfileWrite32(a, pCDS->iOffset);
1774 
1775   memcpy(a, pCDS->zFile, pCDS->nFile);
1776   a += pCDS->nFile;
1777 
1778   if( pEntry->aExtra ){
1779     int n = (int)pCDS->nExtra + (int)pCDS->nComment;
1780     memcpy(a, pEntry->aExtra, n);
1781     a += n;
1782   }else{
1783     assert( pCDS->nExtra==9 );
1784     zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
1785     zipfileWrite16(a, 5);
1786     *a++ = 0x01;
1787     zipfileWrite32(a, pEntry->mUnixTime);
1788   }
1789 
1790   return a-aBuf;
1791 }
1792 
1793 static int zipfileCommit(sqlite3_vtab *pVtab){
1794   ZipfileTab *pTab = (ZipfileTab*)pVtab;
1795   int rc = SQLITE_OK;
1796   if( pTab->pWriteFd ){
1797     i64 iOffset = pTab->szCurrent;
1798     ZipfileEntry *p;
1799     ZipfileEOCD eocd;
1800     int nEntry = 0;
1801 
1802     /* Write out all entries */
1803     for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){
1804       int n = zipfileSerializeCDS(p, pTab->aBuffer);
1805       rc = zipfileAppendData(pTab, pTab->aBuffer, n);
1806       nEntry++;
1807     }
1808 
1809     /* Write out the EOCD record */
1810     eocd.iDisk = 0;
1811     eocd.iFirstDisk = 0;
1812     eocd.nEntry = (u16)nEntry;
1813     eocd.nEntryTotal = (u16)nEntry;
1814     eocd.nSize = (u32)(pTab->szCurrent - iOffset);
1815     eocd.iOffset = (u32)iOffset;
1816     rc = zipfileAppendEOCD(pTab, &eocd);
1817 
1818     zipfileCleanupTransaction(pTab);
1819   }
1820   return rc;
1821 }
1822 
1823 static int zipfileRollback(sqlite3_vtab *pVtab){
1824   return zipfileCommit(pVtab);
1825 }
1826 
1827 static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){
1828   ZipfileCsr *pCsr;
1829   for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
1830     if( iId==pCsr->iId ) break;
1831   }
1832   return pCsr;
1833 }
1834 
1835 static void zipfileFunctionCds(
1836   sqlite3_context *context,
1837   int argc,
1838   sqlite3_value **argv
1839 ){
1840   ZipfileCsr *pCsr;
1841   ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
1842   assert( argc>0 );
1843 
1844   pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
1845   if( pCsr ){
1846     ZipfileCDS *p = &pCsr->pCurrent->cds;
1847     char *zRes = sqlite3_mprintf("{"
1848         "\"version-made-by\" : %u, "
1849         "\"version-to-extract\" : %u, "
1850         "\"flags\" : %u, "
1851         "\"compression\" : %u, "
1852         "\"time\" : %u, "
1853         "\"date\" : %u, "
1854         "\"crc32\" : %u, "
1855         "\"compressed-size\" : %u, "
1856         "\"uncompressed-size\" : %u, "
1857         "\"file-name-length\" : %u, "
1858         "\"extra-field-length\" : %u, "
1859         "\"file-comment-length\" : %u, "
1860         "\"disk-number-start\" : %u, "
1861         "\"internal-attr\" : %u, "
1862         "\"external-attr\" : %u, "
1863         "\"offset\" : %u }",
1864         (u32)p->iVersionMadeBy, (u32)p->iVersionExtract,
1865         (u32)p->flags, (u32)p->iCompression,
1866         (u32)p->mTime, (u32)p->mDate,
1867         (u32)p->crc32, (u32)p->szCompressed,
1868         (u32)p->szUncompressed, (u32)p->nFile,
1869         (u32)p->nExtra, (u32)p->nComment,
1870         (u32)p->iDiskStart, (u32)p->iInternalAttr,
1871         (u32)p->iExternalAttr, (u32)p->iOffset
1872     );
1873 
1874     if( zRes==0 ){
1875       sqlite3_result_error_nomem(context);
1876     }else{
1877       sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
1878       sqlite3_free(zRes);
1879     }
1880   }
1881 }
1882 
1883 /*
1884 ** xFindFunction method.
1885 */
1886 static int zipfileFindFunction(
1887   sqlite3_vtab *pVtab,            /* Virtual table handle */
1888   int nArg,                       /* Number of SQL function arguments */
1889   const char *zName,              /* Name of SQL function */
1890   void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
1891   void **ppArg                    /* OUT: User data for *pxFunc */
1892 ){
1893   if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
1894     *pxFunc = zipfileFunctionCds;
1895     *ppArg = (void*)pVtab;
1896     return 1;
1897   }
1898   return 0;
1899 }
1900 
1901 typedef struct ZipfileBuffer ZipfileBuffer;
1902 struct ZipfileBuffer {
1903   u8 *a;                          /* Pointer to buffer */
1904   int n;                          /* Size of buffer in bytes */
1905   int nAlloc;                     /* Byte allocated at a[] */
1906 };
1907 
1908 typedef struct ZipfileCtx ZipfileCtx;
1909 struct ZipfileCtx {
1910   int nEntry;
1911   ZipfileBuffer body;
1912   ZipfileBuffer cds;
1913 };
1914 
1915 static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
1916   if( pBuf->n+nByte>pBuf->nAlloc ){
1917     u8 *aNew;
1918     sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512;
1919     int nReq = pBuf->n + nByte;
1920 
1921     while( nNew<nReq ) nNew = nNew*2;
1922     aNew = sqlite3_realloc64(pBuf->a, nNew);
1923     if( aNew==0 ) return SQLITE_NOMEM;
1924     pBuf->a = aNew;
1925     pBuf->nAlloc = (int)nNew;
1926   }
1927   return SQLITE_OK;
1928 }
1929 
1930 /*
1931 ** xStep() callback for the zipfile() aggregate. This can be called in
1932 ** any of the following ways:
1933 **
1934 **   SELECT zipfile(name,data) ...
1935 **   SELECT zipfile(name,mode,mtime,data) ...
1936 **   SELECT zipfile(name,mode,mtime,data,method) ...
1937 */
1938 void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
1939   ZipfileCtx *p;                  /* Aggregate function context */
1940   ZipfileEntry e;                 /* New entry to add to zip archive */
1941 
1942   sqlite3_value *pName = 0;
1943   sqlite3_value *pMode = 0;
1944   sqlite3_value *pMtime = 0;
1945   sqlite3_value *pData = 0;
1946   sqlite3_value *pMethod = 0;
1947 
1948   int bIsDir = 0;
1949   u32 mode;
1950   int rc = SQLITE_OK;
1951   char *zErr = 0;
1952 
1953   int iMethod = -1;               /* Compression method to use (0 or 8) */
1954 
1955   const u8 *aData = 0;            /* Possibly compressed data for new entry */
1956   int nData = 0;                  /* Size of aData[] in bytes */
1957   int szUncompressed = 0;         /* Size of data before compression */
1958   u8 *aFree = 0;                  /* Free this before returning */
1959   u32 iCrc32 = 0;                 /* crc32 of uncompressed data */
1960 
1961   char *zName = 0;                /* Path (name) of new entry */
1962   int nName = 0;                  /* Size of zName in bytes */
1963   char *zFree = 0;                /* Free this before returning */
1964   int nByte;
1965 
1966   memset(&e, 0, sizeof(e));
1967   p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
1968   if( p==0 ) return;
1969 
1970   /* Martial the arguments into stack variables */
1971   if( nVal!=2 && nVal!=4 && nVal!=5 ){
1972     zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()");
1973     rc = SQLITE_ERROR;
1974     goto zipfile_step_out;
1975   }
1976   pName = apVal[0];
1977   if( nVal==2 ){
1978     pData = apVal[1];
1979   }else{
1980     pMode = apVal[1];
1981     pMtime = apVal[2];
1982     pData = apVal[3];
1983     if( nVal==5 ){
1984       pMethod = apVal[4];
1985     }
1986   }
1987 
1988   /* Check that the 'name' parameter looks ok. */
1989   zName = (char*)sqlite3_value_text(pName);
1990   nName = sqlite3_value_bytes(pName);
1991   if( zName==0 ){
1992     zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
1993     rc = SQLITE_ERROR;
1994     goto zipfile_step_out;
1995   }
1996 
1997   /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
1998   ** deflate compression) or NULL (choose automatically).  */
1999   if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
2000     iMethod = (int)sqlite3_value_int64(pMethod);
2001     if( iMethod!=0 && iMethod!=8 ){
2002       zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
2003       rc = SQLITE_ERROR;
2004       goto zipfile_step_out;
2005     }
2006   }
2007 
2008   /* Now inspect the data. If this is NULL, then the new entry must be a
2009   ** directory.  Otherwise, figure out whether or not the data should
2010   ** be deflated or simply stored in the zip archive. */
2011   if( sqlite3_value_type(pData)==SQLITE_NULL ){
2012     bIsDir = 1;
2013     iMethod = 0;
2014   }else{
2015     aData = sqlite3_value_blob(pData);
2016     szUncompressed = nData = sqlite3_value_bytes(pData);
2017     iCrc32 = crc32(0, aData, nData);
2018     if( iMethod<0 || iMethod==8 ){
2019       int nOut = 0;
2020       rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr);
2021       if( rc!=SQLITE_OK ){
2022         goto zipfile_step_out;
2023       }
2024       if( iMethod==8 || nOut<nData ){
2025         aData = aFree;
2026         nData = nOut;
2027         iMethod = 8;
2028       }else{
2029         iMethod = 0;
2030       }
2031     }
2032   }
2033 
2034   /* Decode the "mode" argument. */
2035   rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr);
2036   if( rc ) goto zipfile_step_out;
2037 
2038   /* Decode the "mtime" argument. */
2039   e.mUnixTime = zipfileGetTime(pMtime);
2040 
2041   /* If this is a directory entry, ensure that there is exactly one '/'
2042   ** at the end of the path. Or, if this is not a directory and the path
2043   ** ends in '/' it is an error. */
2044   if( bIsDir==0 ){
2045     if( nName>0 && zName[nName-1]=='/' ){
2046       zErr = sqlite3_mprintf("non-directory name must not end with /");
2047       rc = SQLITE_ERROR;
2048       goto zipfile_step_out;
2049     }
2050   }else{
2051     if( nName==0 || zName[nName-1]!='/' ){
2052       zName = zFree = sqlite3_mprintf("%s/", zName);
2053       if( zName==0 ){
2054         rc = SQLITE_NOMEM;
2055         goto zipfile_step_out;
2056       }
2057       nName = (int)strlen(zName);
2058     }else{
2059       while( nName>1 && zName[nName-2]=='/' ) nName--;
2060     }
2061   }
2062 
2063   /* Assemble the ZipfileEntry object for the new zip archive entry */
2064   e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
2065   e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
2066   e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
2067   e.cds.iCompression = (u16)iMethod;
2068   zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
2069   e.cds.crc32 = iCrc32;
2070   e.cds.szCompressed = nData;
2071   e.cds.szUncompressed = szUncompressed;
2072   e.cds.iExternalAttr = (mode<<16);
2073   e.cds.iOffset = p->body.n;
2074   e.cds.nFile = (u16)nName;
2075   e.cds.zFile = zName;
2076 
2077   /* Append the LFH to the body of the new archive */
2078   nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9;
2079   if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out;
2080   p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);
2081 
2082   /* Append the data to the body of the new archive */
2083   if( nData>0 ){
2084     if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out;
2085     memcpy(&p->body.a[p->body.n], aData, nData);
2086     p->body.n += nData;
2087   }
2088 
2089   /* Append the CDS record to the directory of the new archive */
2090   nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9;
2091   if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out;
2092   p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]);
2093 
2094   /* Increment the count of entries in the archive */
2095   p->nEntry++;
2096 
2097  zipfile_step_out:
2098   sqlite3_free(aFree);
2099   sqlite3_free(zFree);
2100   if( rc ){
2101     if( zErr ){
2102       sqlite3_result_error(pCtx, zErr, -1);
2103     }else{
2104       sqlite3_result_error_code(pCtx, rc);
2105     }
2106   }
2107   sqlite3_free(zErr);
2108 }
2109 
2110 /*
2111 ** xFinalize() callback for zipfile aggregate function.
2112 */
2113 void zipfileFinal(sqlite3_context *pCtx){
2114   ZipfileCtx *p;
2115   ZipfileEOCD eocd;
2116   sqlite3_int64 nZip;
2117   u8 *aZip;
2118 
2119   p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
2120   if( p==0 ) return;
2121   if( p->nEntry>0 ){
2122     memset(&eocd, 0, sizeof(eocd));
2123     eocd.nEntry = (u16)p->nEntry;
2124     eocd.nEntryTotal = (u16)p->nEntry;
2125     eocd.nSize = p->cds.n;
2126     eocd.iOffset = p->body.n;
2127 
2128     nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
2129     aZip = (u8*)sqlite3_malloc64(nZip);
2130     if( aZip==0 ){
2131       sqlite3_result_error_nomem(pCtx);
2132     }else{
2133       memcpy(aZip, p->body.a, p->body.n);
2134       memcpy(&aZip[p->body.n], p->cds.a, p->cds.n);
2135       zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]);
2136       sqlite3_result_blob(pCtx, aZip, (int)nZip, zipfileFree);
2137     }
2138   }
2139 
2140   sqlite3_free(p->body.a);
2141   sqlite3_free(p->cds.a);
2142 }
2143 
2144 
2145 /*
2146 ** Register the "zipfile" virtual table.
2147 */
2148 static int zipfileRegister(sqlite3 *db){
2149   static sqlite3_module zipfileModule = {
2150     1,                         /* iVersion */
2151     zipfileConnect,            /* xCreate */
2152     zipfileConnect,            /* xConnect */
2153     zipfileBestIndex,          /* xBestIndex */
2154     zipfileDisconnect,         /* xDisconnect */
2155     zipfileDisconnect,         /* xDestroy */
2156     zipfileOpen,               /* xOpen - open a cursor */
2157     zipfileClose,              /* xClose - close a cursor */
2158     zipfileFilter,             /* xFilter - configure scan constraints */
2159     zipfileNext,               /* xNext - advance a cursor */
2160     zipfileEof,                /* xEof - check for end of scan */
2161     zipfileColumn,             /* xColumn - read data */
2162     0,                         /* xRowid - read data */
2163     zipfileUpdate,             /* xUpdate */
2164     zipfileBegin,              /* xBegin */
2165     0,                         /* xSync */
2166     zipfileCommit,             /* xCommit */
2167     zipfileRollback,           /* xRollback */
2168     zipfileFindFunction,       /* xFindMethod */
2169     0,                         /* xRename */
2170   };
2171 
2172   int rc = sqlite3_create_module(db, "zipfile"  , &zipfileModule, 0);
2173   if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
2174   if( rc==SQLITE_OK ){
2175     rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0,
2176         zipfileStep, zipfileFinal
2177     );
2178   }
2179   assert( sizeof(i64)==8 );
2180   assert( sizeof(u32)==4 );
2181   assert( sizeof(u16)==2 );
2182   assert( sizeof(u8)==1 );
2183   return rc;
2184 }
2185 #else         /* SQLITE_OMIT_VIRTUALTABLE */
2186 # define zipfileRegister(x) SQLITE_OK
2187 #endif
2188 
2189 #ifdef _WIN32
2190 __declspec(dllexport)
2191 #endif
2192 int sqlite3_zipfile_init(
2193   sqlite3 *db,
2194   char **pzErrMsg,
2195   const sqlite3_api_routines *pApi
2196 ){
2197   SQLITE_EXTENSION_INIT2(pApi);
2198   (void)pzErrMsg;  /* Unused parameter */
2199   return zipfileRegister(db);
2200 }
2201