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 */
zipfileCtxErrorMsg(sqlite3_context * ctx,const char * zFmt,...)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 */
zipfileDequote(char * zIn)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 */
zipfileConnect(sqlite3 * db,void * pAux,int argc,const char * const * argv,sqlite3_vtab ** ppVtab,char ** pzErr)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 */
zipfileEntryFree(ZipfileEntry * p)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 */
zipfileCleanupTransaction(ZipfileTab * pTab)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 */
zipfileDisconnect(sqlite3_vtab * pVtab)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 */
zipfileOpen(sqlite3_vtab * p,sqlite3_vtab_cursor ** ppCsr)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 */
zipfileResetCursor(ZipfileCsr * pCsr)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 */
zipfileClose(sqlite3_vtab_cursor * cur)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 */
zipfileTableErr(ZipfileTab * pTab,const char * zFmt,...)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 }
zipfileCursorErr(ZipfileCsr * pCsr,const char * zFmt,...)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 */
zipfileReadData(FILE * pFile,u8 * aRead,int nRead,i64 iOff,char ** pzErrmsg)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
zipfileAppendData(ZipfileTab * pTab,const u8 * aWrite,int nWrite)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 */
zipfileGetU16(const u8 * aBuf)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 */
zipfileGetU32(const u8 * aBuf)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 */
zipfilePutU16(u8 * aBuf,u16 val)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 */
zipfilePutU32(u8 * aBuf,u32 val)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 */
zipfileReadCDS(u8 * aBuf,ZipfileCDS * pCDS)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 */
zipfileReadLFH(u8 * aBuffer,ZipfileLFH * pLFH)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 */
zipfileScanExtra(u8 * aExtra,int nExtra,u32 * pmTime)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 */
zipfileMtime(ZipfileCDS * pCDS)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 */
zipfileMtimeToDos(ZipfileCDS * pCds,u32 mUnixTime)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 */
zipfileGetEntry(ZipfileTab * pTab,const u8 * aBlob,int nBlob,FILE * pFile,i64 iOff,ZipfileEntry ** ppEntry)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 */
zipfileNext(sqlite3_vtab_cursor * cur)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
zipfileFree(void * p)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 */
zipfileInflate(sqlite3_context * pCtx,const u8 * aIn,int nIn,int nOut)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 */
zipfileDeflate(const u8 * aIn,int nIn,u8 ** ppOut,int * pnOut,char ** pzErr)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 */
zipfileColumn(sqlite3_vtab_cursor * cur,sqlite3_context * ctx,int i)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 */
zipfileEof(sqlite3_vtab_cursor * cur)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 */
zipfileReadEOCD(ZipfileTab * pTab,const u8 * aBlob,int nBlob,FILE * pFile,ZipfileEOCD * pEOCD)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 */
zipfileAddEntry(ZipfileTab * pTab,ZipfileEntry * pBefore,ZipfileEntry * pNew)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
zipfileLoadDirectory(ZipfileTab * pTab,const u8 * aBlob,int nBlob)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 */
zipfileFilter(sqlite3_vtab_cursor * cur,int idxNum,const char * idxStr,int argc,sqlite3_value ** argv)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 static const u8 aEmptyBlob = 0;
1266 const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
1267 int nBlob = sqlite3_value_bytes(argv[0]);
1268 assert( pTab->pFirstEntry==0 );
1269 if( aBlob==0 ){
1270 aBlob = &aEmptyBlob;
1271 nBlob = 0;
1272 }
1273 rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
1274 pCsr->pFreeEntry = pTab->pFirstEntry;
1275 pTab->pFirstEntry = pTab->pLastEntry = 0;
1276 if( rc!=SQLITE_OK ) return rc;
1277 bInMemory = 1;
1278 }else{
1279 zFile = (const char*)sqlite3_value_text(argv[0]);
1280 }
1281
1282 if( 0==pTab->pWriteFd && 0==bInMemory ){
1283 pCsr->pFile = fopen(zFile, "rb");
1284 if( pCsr->pFile==0 ){
1285 zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
1286 rc = SQLITE_ERROR;
1287 }else{
1288 rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd);
1289 if( rc==SQLITE_OK ){
1290 if( pCsr->eocd.nEntry==0 ){
1291 pCsr->bEof = 1;
1292 }else{
1293 pCsr->iNextOff = pCsr->eocd.iOffset;
1294 rc = zipfileNext(cur);
1295 }
1296 }
1297 }
1298 }else{
1299 pCsr->bNoop = 1;
1300 pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry;
1301 rc = zipfileNext(cur);
1302 }
1303
1304 return rc;
1305 }
1306
1307 /*
1308 ** xBestIndex callback.
1309 */
zipfileBestIndex(sqlite3_vtab * tab,sqlite3_index_info * pIdxInfo)1310 static int zipfileBestIndex(
1311 sqlite3_vtab *tab,
1312 sqlite3_index_info *pIdxInfo
1313 ){
1314 int i;
1315 int idx = -1;
1316 int unusable = 0;
1317
1318 for(i=0; i<pIdxInfo->nConstraint; i++){
1319 const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
1320 if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
1321 if( pCons->usable==0 ){
1322 unusable = 1;
1323 }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
1324 idx = i;
1325 }
1326 }
1327 pIdxInfo->estimatedCost = 1000.0;
1328 if( idx>=0 ){
1329 pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
1330 pIdxInfo->aConstraintUsage[idx].omit = 1;
1331 pIdxInfo->idxNum = 1;
1332 }else if( unusable ){
1333 return SQLITE_CONSTRAINT;
1334 }
1335 return SQLITE_OK;
1336 }
1337
zipfileNewEntry(const char * zPath)1338 static ZipfileEntry *zipfileNewEntry(const char *zPath){
1339 ZipfileEntry *pNew;
1340 pNew = sqlite3_malloc(sizeof(ZipfileEntry));
1341 if( pNew ){
1342 memset(pNew, 0, sizeof(ZipfileEntry));
1343 pNew->cds.zFile = sqlite3_mprintf("%s", zPath);
1344 if( pNew->cds.zFile==0 ){
1345 sqlite3_free(pNew);
1346 pNew = 0;
1347 }
1348 }
1349 return pNew;
1350 }
1351
zipfileSerializeLFH(ZipfileEntry * pEntry,u8 * aBuf)1352 static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){
1353 ZipfileCDS *pCds = &pEntry->cds;
1354 u8 *a = aBuf;
1355
1356 pCds->nExtra = 9;
1357
1358 /* Write the LFH itself */
1359 zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH);
1360 zipfileWrite16(a, pCds->iVersionExtract);
1361 zipfileWrite16(a, pCds->flags);
1362 zipfileWrite16(a, pCds->iCompression);
1363 zipfileWrite16(a, pCds->mTime);
1364 zipfileWrite16(a, pCds->mDate);
1365 zipfileWrite32(a, pCds->crc32);
1366 zipfileWrite32(a, pCds->szCompressed);
1367 zipfileWrite32(a, pCds->szUncompressed);
1368 zipfileWrite16(a, (u16)pCds->nFile);
1369 zipfileWrite16(a, pCds->nExtra);
1370 assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] );
1371
1372 /* Add the file name */
1373 memcpy(a, pCds->zFile, (int)pCds->nFile);
1374 a += (int)pCds->nFile;
1375
1376 /* The "extra" data */
1377 zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
1378 zipfileWrite16(a, 5);
1379 *a++ = 0x01;
1380 zipfileWrite32(a, pEntry->mUnixTime);
1381
1382 return a-aBuf;
1383 }
1384
zipfileAppendEntry(ZipfileTab * pTab,ZipfileEntry * pEntry,const u8 * pData,int nData)1385 static int zipfileAppendEntry(
1386 ZipfileTab *pTab,
1387 ZipfileEntry *pEntry,
1388 const u8 *pData,
1389 int nData
1390 ){
1391 u8 *aBuf = pTab->aBuffer;
1392 int nBuf;
1393 int rc;
1394
1395 nBuf = zipfileSerializeLFH(pEntry, aBuf);
1396 rc = zipfileAppendData(pTab, aBuf, nBuf);
1397 if( rc==SQLITE_OK ){
1398 pEntry->iDataOff = pTab->szCurrent;
1399 rc = zipfileAppendData(pTab, pData, nData);
1400 }
1401
1402 return rc;
1403 }
1404
zipfileGetMode(sqlite3_value * pVal,int bIsDir,u32 * pMode,char ** pzErr)1405 static int zipfileGetMode(
1406 sqlite3_value *pVal,
1407 int bIsDir, /* If true, default to directory */
1408 u32 *pMode, /* OUT: Mode value */
1409 char **pzErr /* OUT: Error message */
1410 ){
1411 const char *z = (const char*)sqlite3_value_text(pVal);
1412 u32 mode = 0;
1413 if( z==0 ){
1414 mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644));
1415 }else if( z[0]>='0' && z[0]<='9' ){
1416 mode = (unsigned int)sqlite3_value_int(pVal);
1417 }else{
1418 const char zTemplate[11] = "-rwxrwxrwx";
1419 int i;
1420 if( strlen(z)!=10 ) goto parse_error;
1421 switch( z[0] ){
1422 case '-': mode |= S_IFREG; break;
1423 case 'd': mode |= S_IFDIR; break;
1424 case 'l': mode |= S_IFLNK; break;
1425 default: goto parse_error;
1426 }
1427 for(i=1; i<10; i++){
1428 if( z[i]==zTemplate[i] ) mode |= 1 << (9-i);
1429 else if( z[i]!='-' ) goto parse_error;
1430 }
1431 }
1432 if( ((mode & S_IFDIR)==0)==bIsDir ){
1433 /* The "mode" attribute is a directory, but data has been specified.
1434 ** Or vice-versa - no data but "mode" is a file or symlink. */
1435 *pzErr = sqlite3_mprintf("zipfile: mode does not match data");
1436 return SQLITE_CONSTRAINT;
1437 }
1438 *pMode = mode;
1439 return SQLITE_OK;
1440
1441 parse_error:
1442 *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z);
1443 return SQLITE_ERROR;
1444 }
1445
1446 /*
1447 ** Both (const char*) arguments point to nul-terminated strings. Argument
1448 ** nB is the value of strlen(zB). This function returns 0 if the strings are
1449 ** identical, ignoring any trailing '/' character in either path. */
zipfileComparePath(const char * zA,const char * zB,int nB)1450 static int zipfileComparePath(const char *zA, const char *zB, int nB){
1451 int nA = (int)strlen(zA);
1452 if( nA>0 && zA[nA-1]=='/' ) nA--;
1453 if( nB>0 && zB[nB-1]=='/' ) nB--;
1454 if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
1455 return 1;
1456 }
1457
zipfileBegin(sqlite3_vtab * pVtab)1458 static int zipfileBegin(sqlite3_vtab *pVtab){
1459 ZipfileTab *pTab = (ZipfileTab*)pVtab;
1460 int rc = SQLITE_OK;
1461
1462 assert( pTab->pWriteFd==0 );
1463 if( pTab->zFile==0 || pTab->zFile[0]==0 ){
1464 pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename");
1465 return SQLITE_ERROR;
1466 }
1467
1468 /* Open a write fd on the file. Also load the entire central directory
1469 ** structure into memory. During the transaction any new file data is
1470 ** appended to the archive file, but the central directory is accumulated
1471 ** in main-memory until the transaction is committed. */
1472 pTab->pWriteFd = fopen(pTab->zFile, "ab+");
1473 if( pTab->pWriteFd==0 ){
1474 pTab->base.zErrMsg = sqlite3_mprintf(
1475 "zipfile: failed to open file %s for writing", pTab->zFile
1476 );
1477 rc = SQLITE_ERROR;
1478 }else{
1479 fseek(pTab->pWriteFd, 0, SEEK_END);
1480 pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd);
1481 rc = zipfileLoadDirectory(pTab, 0, 0);
1482 }
1483
1484 if( rc!=SQLITE_OK ){
1485 zipfileCleanupTransaction(pTab);
1486 }
1487
1488 return rc;
1489 }
1490
1491 /*
1492 ** Return the current time as a 32-bit timestamp in UNIX epoch format (like
1493 ** time(2)).
1494 */
zipfileTime(void)1495 static u32 zipfileTime(void){
1496 sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
1497 u32 ret;
1498 if( pVfs==0 ) return 0;
1499 if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
1500 i64 ms;
1501 pVfs->xCurrentTimeInt64(pVfs, &ms);
1502 ret = (u32)((ms/1000) - ((i64)24405875 * 8640));
1503 }else{
1504 double day;
1505 pVfs->xCurrentTime(pVfs, &day);
1506 ret = (u32)((day - 2440587.5) * 86400);
1507 }
1508 return ret;
1509 }
1510
1511 /*
1512 ** Return a 32-bit timestamp in UNIX epoch format.
1513 **
1514 ** If the value passed as the only argument is either NULL or an SQL NULL,
1515 ** return the current time. Otherwise, return the value stored in (*pVal)
1516 ** cast to a 32-bit unsigned integer.
1517 */
zipfileGetTime(sqlite3_value * pVal)1518 static u32 zipfileGetTime(sqlite3_value *pVal){
1519 if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
1520 return zipfileTime();
1521 }
1522 return (u32)sqlite3_value_int64(pVal);
1523 }
1524
1525 /*
1526 ** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry
1527 ** linked list. Remove it from the list and free the object.
1528 */
zipfileRemoveEntryFromList(ZipfileTab * pTab,ZipfileEntry * pOld)1529 static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){
1530 if( pOld ){
1531 ZipfileEntry **pp;
1532 for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext));
1533 *pp = (*pp)->pNext;
1534 zipfileEntryFree(pOld);
1535 }
1536 }
1537
1538 /*
1539 ** xUpdate method.
1540 */
zipfileUpdate(sqlite3_vtab * pVtab,int nVal,sqlite3_value ** apVal,sqlite_int64 * pRowid)1541 static int zipfileUpdate(
1542 sqlite3_vtab *pVtab,
1543 int nVal,
1544 sqlite3_value **apVal,
1545 sqlite_int64 *pRowid
1546 ){
1547 ZipfileTab *pTab = (ZipfileTab*)pVtab;
1548 int rc = SQLITE_OK; /* Return Code */
1549 ZipfileEntry *pNew = 0; /* New in-memory CDS entry */
1550
1551 u32 mode = 0; /* Mode for new entry */
1552 u32 mTime = 0; /* Modification time for new entry */
1553 i64 sz = 0; /* Uncompressed size */
1554 const char *zPath = 0; /* Path for new entry */
1555 int nPath = 0; /* strlen(zPath) */
1556 const u8 *pData = 0; /* Pointer to buffer containing content */
1557 int nData = 0; /* Size of pData buffer in bytes */
1558 int iMethod = 0; /* Compression method for new entry */
1559 u8 *pFree = 0; /* Free this */
1560 char *zFree = 0; /* Also free this */
1561 ZipfileEntry *pOld = 0;
1562 ZipfileEntry *pOld2 = 0;
1563 int bUpdate = 0; /* True for an update that modifies "name" */
1564 int bIsDir = 0;
1565 u32 iCrc32 = 0;
1566
1567 if( pTab->pWriteFd==0 ){
1568 rc = zipfileBegin(pVtab);
1569 if( rc!=SQLITE_OK ) return rc;
1570 }
1571
1572 /* If this is a DELETE or UPDATE, find the archive entry to delete. */
1573 if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
1574 const char *zDelete = (const char*)sqlite3_value_text(apVal[0]);
1575 int nDelete = (int)strlen(zDelete);
1576 if( nVal>1 ){
1577 const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]);
1578 if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
1579 bUpdate = 1;
1580 }
1581 }
1582 for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
1583 if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
1584 break;
1585 }
1586 assert( pOld->pNext );
1587 }
1588 }
1589
1590 if( nVal>1 ){
1591 /* Check that "sz" and "rawdata" are both NULL: */
1592 if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){
1593 zipfileTableErr(pTab, "sz must be NULL");
1594 rc = SQLITE_CONSTRAINT;
1595 }
1596 if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){
1597 zipfileTableErr(pTab, "rawdata must be NULL");
1598 rc = SQLITE_CONSTRAINT;
1599 }
1600
1601 if( rc==SQLITE_OK ){
1602 if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){
1603 /* data=NULL. A directory */
1604 bIsDir = 1;
1605 }else{
1606 /* Value specified for "data", and possibly "method". This must be
1607 ** a regular file or a symlink. */
1608 const u8 *aIn = sqlite3_value_blob(apVal[7]);
1609 int nIn = sqlite3_value_bytes(apVal[7]);
1610 int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL;
1611
1612 iMethod = sqlite3_value_int(apVal[8]);
1613 sz = nIn;
1614 pData = aIn;
1615 nData = nIn;
1616 if( iMethod!=0 && iMethod!=8 ){
1617 zipfileTableErr(pTab, "unknown compression method: %d", iMethod);
1618 rc = SQLITE_CONSTRAINT;
1619 }else{
1620 if( bAuto || iMethod ){
1621 int nCmp;
1622 rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg);
1623 if( rc==SQLITE_OK ){
1624 if( iMethod || nCmp<nIn ){
1625 iMethod = 8;
1626 pData = pFree;
1627 nData = nCmp;
1628 }
1629 }
1630 }
1631 iCrc32 = crc32(0, aIn, nIn);
1632 }
1633 }
1634 }
1635
1636 if( rc==SQLITE_OK ){
1637 rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg);
1638 }
1639
1640 if( rc==SQLITE_OK ){
1641 zPath = (const char*)sqlite3_value_text(apVal[2]);
1642 if( zPath==0 ) zPath = "";
1643 nPath = (int)strlen(zPath);
1644 mTime = zipfileGetTime(apVal[4]);
1645 }
1646
1647 if( rc==SQLITE_OK && bIsDir ){
1648 /* For a directory, check that the last character in the path is a
1649 ** '/'. This appears to be required for compatibility with info-zip
1650 ** (the unzip command on unix). It does not create directories
1651 ** otherwise. */
1652 if( nPath<=0 || zPath[nPath-1]!='/' ){
1653 zFree = sqlite3_mprintf("%s/", zPath);
1654 zPath = (const char*)zFree;
1655 if( zFree==0 ){
1656 rc = SQLITE_NOMEM;
1657 nPath = 0;
1658 }else{
1659 nPath = (int)strlen(zPath);
1660 }
1661 }
1662 }
1663
1664 /* Check that we're not inserting a duplicate entry -OR- updating an
1665 ** entry with a path, thereby making it into a duplicate. */
1666 if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
1667 ZipfileEntry *p;
1668 for(p=pTab->pFirstEntry; p; p=p->pNext){
1669 if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){
1670 switch( sqlite3_vtab_on_conflict(pTab->db) ){
1671 case SQLITE_IGNORE: {
1672 goto zipfile_update_done;
1673 }
1674 case SQLITE_REPLACE: {
1675 pOld2 = p;
1676 break;
1677 }
1678 default: {
1679 zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath);
1680 rc = SQLITE_CONSTRAINT;
1681 break;
1682 }
1683 }
1684 break;
1685 }
1686 }
1687 }
1688
1689 if( rc==SQLITE_OK ){
1690 /* Create the new CDS record. */
1691 pNew = zipfileNewEntry(zPath);
1692 if( pNew==0 ){
1693 rc = SQLITE_NOMEM;
1694 }else{
1695 pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
1696 pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
1697 pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS;
1698 pNew->cds.iCompression = (u16)iMethod;
1699 zipfileMtimeToDos(&pNew->cds, mTime);
1700 pNew->cds.crc32 = iCrc32;
1701 pNew->cds.szCompressed = nData;
1702 pNew->cds.szUncompressed = (u32)sz;
1703 pNew->cds.iExternalAttr = (mode<<16);
1704 pNew->cds.iOffset = (u32)pTab->szCurrent;
1705 pNew->cds.nFile = (u16)nPath;
1706 pNew->mUnixTime = (u32)mTime;
1707 rc = zipfileAppendEntry(pTab, pNew, pData, nData);
1708 zipfileAddEntry(pTab, pOld, pNew);
1709 }
1710 }
1711 }
1712
1713 if( rc==SQLITE_OK && (pOld || pOld2) ){
1714 ZipfileCsr *pCsr;
1715 for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
1716 if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){
1717 pCsr->pCurrent = pCsr->pCurrent->pNext;
1718 pCsr->bNoop = 1;
1719 }
1720 }
1721
1722 zipfileRemoveEntryFromList(pTab, pOld);
1723 zipfileRemoveEntryFromList(pTab, pOld2);
1724 }
1725
1726 zipfile_update_done:
1727 sqlite3_free(pFree);
1728 sqlite3_free(zFree);
1729 return rc;
1730 }
1731
zipfileSerializeEOCD(ZipfileEOCD * p,u8 * aBuf)1732 static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){
1733 u8 *a = aBuf;
1734 zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD);
1735 zipfileWrite16(a, p->iDisk);
1736 zipfileWrite16(a, p->iFirstDisk);
1737 zipfileWrite16(a, p->nEntry);
1738 zipfileWrite16(a, p->nEntryTotal);
1739 zipfileWrite32(a, p->nSize);
1740 zipfileWrite32(a, p->iOffset);
1741 zipfileWrite16(a, 0); /* Size of trailing comment in bytes*/
1742
1743 return a-aBuf;
1744 }
1745
zipfileAppendEOCD(ZipfileTab * pTab,ZipfileEOCD * p)1746 static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){
1747 int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer);
1748 assert( nBuf==ZIPFILE_EOCD_FIXED_SZ );
1749 return zipfileAppendData(pTab, pTab->aBuffer, nBuf);
1750 }
1751
1752 /*
1753 ** Serialize the CDS structure into buffer aBuf[]. Return the number
1754 ** of bytes written.
1755 */
zipfileSerializeCDS(ZipfileEntry * pEntry,u8 * aBuf)1756 static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){
1757 u8 *a = aBuf;
1758 ZipfileCDS *pCDS = &pEntry->cds;
1759
1760 if( pEntry->aExtra==0 ){
1761 pCDS->nExtra = 9;
1762 }
1763
1764 zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS);
1765 zipfileWrite16(a, pCDS->iVersionMadeBy);
1766 zipfileWrite16(a, pCDS->iVersionExtract);
1767 zipfileWrite16(a, pCDS->flags);
1768 zipfileWrite16(a, pCDS->iCompression);
1769 zipfileWrite16(a, pCDS->mTime);
1770 zipfileWrite16(a, pCDS->mDate);
1771 zipfileWrite32(a, pCDS->crc32);
1772 zipfileWrite32(a, pCDS->szCompressed);
1773 zipfileWrite32(a, pCDS->szUncompressed);
1774 assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
1775 zipfileWrite16(a, pCDS->nFile);
1776 zipfileWrite16(a, pCDS->nExtra);
1777 zipfileWrite16(a, pCDS->nComment);
1778 zipfileWrite16(a, pCDS->iDiskStart);
1779 zipfileWrite16(a, pCDS->iInternalAttr);
1780 zipfileWrite32(a, pCDS->iExternalAttr);
1781 zipfileWrite32(a, pCDS->iOffset);
1782
1783 memcpy(a, pCDS->zFile, pCDS->nFile);
1784 a += pCDS->nFile;
1785
1786 if( pEntry->aExtra ){
1787 int n = (int)pCDS->nExtra + (int)pCDS->nComment;
1788 memcpy(a, pEntry->aExtra, n);
1789 a += n;
1790 }else{
1791 assert( pCDS->nExtra==9 );
1792 zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
1793 zipfileWrite16(a, 5);
1794 *a++ = 0x01;
1795 zipfileWrite32(a, pEntry->mUnixTime);
1796 }
1797
1798 return a-aBuf;
1799 }
1800
zipfileCommit(sqlite3_vtab * pVtab)1801 static int zipfileCommit(sqlite3_vtab *pVtab){
1802 ZipfileTab *pTab = (ZipfileTab*)pVtab;
1803 int rc = SQLITE_OK;
1804 if( pTab->pWriteFd ){
1805 i64 iOffset = pTab->szCurrent;
1806 ZipfileEntry *p;
1807 ZipfileEOCD eocd;
1808 int nEntry = 0;
1809
1810 /* Write out all entries */
1811 for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){
1812 int n = zipfileSerializeCDS(p, pTab->aBuffer);
1813 rc = zipfileAppendData(pTab, pTab->aBuffer, n);
1814 nEntry++;
1815 }
1816
1817 /* Write out the EOCD record */
1818 eocd.iDisk = 0;
1819 eocd.iFirstDisk = 0;
1820 eocd.nEntry = (u16)nEntry;
1821 eocd.nEntryTotal = (u16)nEntry;
1822 eocd.nSize = (u32)(pTab->szCurrent - iOffset);
1823 eocd.iOffset = (u32)iOffset;
1824 rc = zipfileAppendEOCD(pTab, &eocd);
1825
1826 zipfileCleanupTransaction(pTab);
1827 }
1828 return rc;
1829 }
1830
zipfileRollback(sqlite3_vtab * pVtab)1831 static int zipfileRollback(sqlite3_vtab *pVtab){
1832 return zipfileCommit(pVtab);
1833 }
1834
zipfileFindCursor(ZipfileTab * pTab,i64 iId)1835 static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){
1836 ZipfileCsr *pCsr;
1837 for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
1838 if( iId==pCsr->iId ) break;
1839 }
1840 return pCsr;
1841 }
1842
zipfileFunctionCds(sqlite3_context * context,int argc,sqlite3_value ** argv)1843 static void zipfileFunctionCds(
1844 sqlite3_context *context,
1845 int argc,
1846 sqlite3_value **argv
1847 ){
1848 ZipfileCsr *pCsr;
1849 ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
1850 assert( argc>0 );
1851
1852 pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
1853 if( pCsr ){
1854 ZipfileCDS *p = &pCsr->pCurrent->cds;
1855 char *zRes = sqlite3_mprintf("{"
1856 "\"version-made-by\" : %u, "
1857 "\"version-to-extract\" : %u, "
1858 "\"flags\" : %u, "
1859 "\"compression\" : %u, "
1860 "\"time\" : %u, "
1861 "\"date\" : %u, "
1862 "\"crc32\" : %u, "
1863 "\"compressed-size\" : %u, "
1864 "\"uncompressed-size\" : %u, "
1865 "\"file-name-length\" : %u, "
1866 "\"extra-field-length\" : %u, "
1867 "\"file-comment-length\" : %u, "
1868 "\"disk-number-start\" : %u, "
1869 "\"internal-attr\" : %u, "
1870 "\"external-attr\" : %u, "
1871 "\"offset\" : %u }",
1872 (u32)p->iVersionMadeBy, (u32)p->iVersionExtract,
1873 (u32)p->flags, (u32)p->iCompression,
1874 (u32)p->mTime, (u32)p->mDate,
1875 (u32)p->crc32, (u32)p->szCompressed,
1876 (u32)p->szUncompressed, (u32)p->nFile,
1877 (u32)p->nExtra, (u32)p->nComment,
1878 (u32)p->iDiskStart, (u32)p->iInternalAttr,
1879 (u32)p->iExternalAttr, (u32)p->iOffset
1880 );
1881
1882 if( zRes==0 ){
1883 sqlite3_result_error_nomem(context);
1884 }else{
1885 sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
1886 sqlite3_free(zRes);
1887 }
1888 }
1889 }
1890
1891 /*
1892 ** xFindFunction method.
1893 */
zipfileFindFunction(sqlite3_vtab * pVtab,int nArg,const char * zName,void (** pxFunc)(sqlite3_context *,int,sqlite3_value **),void ** ppArg)1894 static int zipfileFindFunction(
1895 sqlite3_vtab *pVtab, /* Virtual table handle */
1896 int nArg, /* Number of SQL function arguments */
1897 const char *zName, /* Name of SQL function */
1898 void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
1899 void **ppArg /* OUT: User data for *pxFunc */
1900 ){
1901 if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
1902 *pxFunc = zipfileFunctionCds;
1903 *ppArg = (void*)pVtab;
1904 return 1;
1905 }
1906 return 0;
1907 }
1908
1909 typedef struct ZipfileBuffer ZipfileBuffer;
1910 struct ZipfileBuffer {
1911 u8 *a; /* Pointer to buffer */
1912 int n; /* Size of buffer in bytes */
1913 int nAlloc; /* Byte allocated at a[] */
1914 };
1915
1916 typedef struct ZipfileCtx ZipfileCtx;
1917 struct ZipfileCtx {
1918 int nEntry;
1919 ZipfileBuffer body;
1920 ZipfileBuffer cds;
1921 };
1922
zipfileBufferGrow(ZipfileBuffer * pBuf,int nByte)1923 static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
1924 if( pBuf->n+nByte>pBuf->nAlloc ){
1925 u8 *aNew;
1926 sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512;
1927 int nReq = pBuf->n + nByte;
1928
1929 while( nNew<nReq ) nNew = nNew*2;
1930 aNew = sqlite3_realloc64(pBuf->a, nNew);
1931 if( aNew==0 ) return SQLITE_NOMEM;
1932 pBuf->a = aNew;
1933 pBuf->nAlloc = (int)nNew;
1934 }
1935 return SQLITE_OK;
1936 }
1937
1938 /*
1939 ** xStep() callback for the zipfile() aggregate. This can be called in
1940 ** any of the following ways:
1941 **
1942 ** SELECT zipfile(name,data) ...
1943 ** SELECT zipfile(name,mode,mtime,data) ...
1944 ** SELECT zipfile(name,mode,mtime,data,method) ...
1945 */
zipfileStep(sqlite3_context * pCtx,int nVal,sqlite3_value ** apVal)1946 static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
1947 ZipfileCtx *p; /* Aggregate function context */
1948 ZipfileEntry e; /* New entry to add to zip archive */
1949
1950 sqlite3_value *pName = 0;
1951 sqlite3_value *pMode = 0;
1952 sqlite3_value *pMtime = 0;
1953 sqlite3_value *pData = 0;
1954 sqlite3_value *pMethod = 0;
1955
1956 int bIsDir = 0;
1957 u32 mode;
1958 int rc = SQLITE_OK;
1959 char *zErr = 0;
1960
1961 int iMethod = -1; /* Compression method to use (0 or 8) */
1962
1963 const u8 *aData = 0; /* Possibly compressed data for new entry */
1964 int nData = 0; /* Size of aData[] in bytes */
1965 int szUncompressed = 0; /* Size of data before compression */
1966 u8 *aFree = 0; /* Free this before returning */
1967 u32 iCrc32 = 0; /* crc32 of uncompressed data */
1968
1969 char *zName = 0; /* Path (name) of new entry */
1970 int nName = 0; /* Size of zName in bytes */
1971 char *zFree = 0; /* Free this before returning */
1972 int nByte;
1973
1974 memset(&e, 0, sizeof(e));
1975 p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
1976 if( p==0 ) return;
1977
1978 /* Martial the arguments into stack variables */
1979 if( nVal!=2 && nVal!=4 && nVal!=5 ){
1980 zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()");
1981 rc = SQLITE_ERROR;
1982 goto zipfile_step_out;
1983 }
1984 pName = apVal[0];
1985 if( nVal==2 ){
1986 pData = apVal[1];
1987 }else{
1988 pMode = apVal[1];
1989 pMtime = apVal[2];
1990 pData = apVal[3];
1991 if( nVal==5 ){
1992 pMethod = apVal[4];
1993 }
1994 }
1995
1996 /* Check that the 'name' parameter looks ok. */
1997 zName = (char*)sqlite3_value_text(pName);
1998 nName = sqlite3_value_bytes(pName);
1999 if( zName==0 ){
2000 zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
2001 rc = SQLITE_ERROR;
2002 goto zipfile_step_out;
2003 }
2004
2005 /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
2006 ** deflate compression) or NULL (choose automatically). */
2007 if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
2008 iMethod = (int)sqlite3_value_int64(pMethod);
2009 if( iMethod!=0 && iMethod!=8 ){
2010 zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
2011 rc = SQLITE_ERROR;
2012 goto zipfile_step_out;
2013 }
2014 }
2015
2016 /* Now inspect the data. If this is NULL, then the new entry must be a
2017 ** directory. Otherwise, figure out whether or not the data should
2018 ** be deflated or simply stored in the zip archive. */
2019 if( sqlite3_value_type(pData)==SQLITE_NULL ){
2020 bIsDir = 1;
2021 iMethod = 0;
2022 }else{
2023 aData = sqlite3_value_blob(pData);
2024 szUncompressed = nData = sqlite3_value_bytes(pData);
2025 iCrc32 = crc32(0, aData, nData);
2026 if( iMethod<0 || iMethod==8 ){
2027 int nOut = 0;
2028 rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr);
2029 if( rc!=SQLITE_OK ){
2030 goto zipfile_step_out;
2031 }
2032 if( iMethod==8 || nOut<nData ){
2033 aData = aFree;
2034 nData = nOut;
2035 iMethod = 8;
2036 }else{
2037 iMethod = 0;
2038 }
2039 }
2040 }
2041
2042 /* Decode the "mode" argument. */
2043 rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr);
2044 if( rc ) goto zipfile_step_out;
2045
2046 /* Decode the "mtime" argument. */
2047 e.mUnixTime = zipfileGetTime(pMtime);
2048
2049 /* If this is a directory entry, ensure that there is exactly one '/'
2050 ** at the end of the path. Or, if this is not a directory and the path
2051 ** ends in '/' it is an error. */
2052 if( bIsDir==0 ){
2053 if( nName>0 && zName[nName-1]=='/' ){
2054 zErr = sqlite3_mprintf("non-directory name must not end with /");
2055 rc = SQLITE_ERROR;
2056 goto zipfile_step_out;
2057 }
2058 }else{
2059 if( nName==0 || zName[nName-1]!='/' ){
2060 zName = zFree = sqlite3_mprintf("%s/", zName);
2061 if( zName==0 ){
2062 rc = SQLITE_NOMEM;
2063 goto zipfile_step_out;
2064 }
2065 nName = (int)strlen(zName);
2066 }else{
2067 while( nName>1 && zName[nName-2]=='/' ) nName--;
2068 }
2069 }
2070
2071 /* Assemble the ZipfileEntry object for the new zip archive entry */
2072 e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
2073 e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
2074 e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
2075 e.cds.iCompression = (u16)iMethod;
2076 zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
2077 e.cds.crc32 = iCrc32;
2078 e.cds.szCompressed = nData;
2079 e.cds.szUncompressed = szUncompressed;
2080 e.cds.iExternalAttr = (mode<<16);
2081 e.cds.iOffset = p->body.n;
2082 e.cds.nFile = (u16)nName;
2083 e.cds.zFile = zName;
2084
2085 /* Append the LFH to the body of the new archive */
2086 nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9;
2087 if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out;
2088 p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);
2089
2090 /* Append the data to the body of the new archive */
2091 if( nData>0 ){
2092 if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out;
2093 memcpy(&p->body.a[p->body.n], aData, nData);
2094 p->body.n += nData;
2095 }
2096
2097 /* Append the CDS record to the directory of the new archive */
2098 nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9;
2099 if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out;
2100 p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]);
2101
2102 /* Increment the count of entries in the archive */
2103 p->nEntry++;
2104
2105 zipfile_step_out:
2106 sqlite3_free(aFree);
2107 sqlite3_free(zFree);
2108 if( rc ){
2109 if( zErr ){
2110 sqlite3_result_error(pCtx, zErr, -1);
2111 }else{
2112 sqlite3_result_error_code(pCtx, rc);
2113 }
2114 }
2115 sqlite3_free(zErr);
2116 }
2117
2118 /*
2119 ** xFinalize() callback for zipfile aggregate function.
2120 */
zipfileFinal(sqlite3_context * pCtx)2121 static void zipfileFinal(sqlite3_context *pCtx){
2122 ZipfileCtx *p;
2123 ZipfileEOCD eocd;
2124 sqlite3_int64 nZip;
2125 u8 *aZip;
2126
2127 p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
2128 if( p==0 ) return;
2129 if( p->nEntry>0 ){
2130 memset(&eocd, 0, sizeof(eocd));
2131 eocd.nEntry = (u16)p->nEntry;
2132 eocd.nEntryTotal = (u16)p->nEntry;
2133 eocd.nSize = p->cds.n;
2134 eocd.iOffset = p->body.n;
2135
2136 nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
2137 aZip = (u8*)sqlite3_malloc64(nZip);
2138 if( aZip==0 ){
2139 sqlite3_result_error_nomem(pCtx);
2140 }else{
2141 memcpy(aZip, p->body.a, p->body.n);
2142 memcpy(&aZip[p->body.n], p->cds.a, p->cds.n);
2143 zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]);
2144 sqlite3_result_blob(pCtx, aZip, (int)nZip, zipfileFree);
2145 }
2146 }
2147
2148 sqlite3_free(p->body.a);
2149 sqlite3_free(p->cds.a);
2150 }
2151
2152
2153 /*
2154 ** Register the "zipfile" virtual table.
2155 */
zipfileRegister(sqlite3 * db)2156 static int zipfileRegister(sqlite3 *db){
2157 static sqlite3_module zipfileModule = {
2158 1, /* iVersion */
2159 zipfileConnect, /* xCreate */
2160 zipfileConnect, /* xConnect */
2161 zipfileBestIndex, /* xBestIndex */
2162 zipfileDisconnect, /* xDisconnect */
2163 zipfileDisconnect, /* xDestroy */
2164 zipfileOpen, /* xOpen - open a cursor */
2165 zipfileClose, /* xClose - close a cursor */
2166 zipfileFilter, /* xFilter - configure scan constraints */
2167 zipfileNext, /* xNext - advance a cursor */
2168 zipfileEof, /* xEof - check for end of scan */
2169 zipfileColumn, /* xColumn - read data */
2170 0, /* xRowid - read data */
2171 zipfileUpdate, /* xUpdate */
2172 zipfileBegin, /* xBegin */
2173 0, /* xSync */
2174 zipfileCommit, /* xCommit */
2175 zipfileRollback, /* xRollback */
2176 zipfileFindFunction, /* xFindMethod */
2177 0, /* xRename */
2178 0, /* xSavepoint */
2179 0, /* xRelease */
2180 0, /* xRollback */
2181 0 /* xShadowName */
2182 };
2183
2184 int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0);
2185 if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
2186 if( rc==SQLITE_OK ){
2187 rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0,
2188 zipfileStep, zipfileFinal
2189 );
2190 }
2191 assert( sizeof(i64)==8 );
2192 assert( sizeof(u32)==4 );
2193 assert( sizeof(u16)==2 );
2194 assert( sizeof(u8)==1 );
2195 return rc;
2196 }
2197 #else /* SQLITE_OMIT_VIRTUALTABLE */
2198 # define zipfileRegister(x) SQLITE_OK
2199 #endif
2200
2201 #ifdef _WIN32
2202 __declspec(dllexport)
2203 #endif
sqlite3_zipfile_init(sqlite3 * db,char ** pzErrMsg,const sqlite3_api_routines * pApi)2204 int sqlite3_zipfile_init(
2205 sqlite3 *db,
2206 char **pzErrMsg,
2207 const sqlite3_api_routines *pApi
2208 ){
2209 SQLITE_EXTENSION_INIT2(pApi);
2210 (void)pzErrMsg; /* Unused parameter */
2211 return zipfileRegister(db);
2212 }
2213