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