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