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