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