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