** If aBlob is not NULL, then it points to a buffer nBlob bytes in size ** containing an entire zip archive image. Or, if aBlob is NULL, then pFile ** is guaranteed to be a file-handle open on a zip file. ** ** This function attempts to locate the EOCD record within the zip archive ** and populate *pEOCD with the results of decoding it. SQLITE_OK is ** returned if successful. Otherwise, an SQLite
| 7007 | ** an English language error message may be left in virtual-table pTab. |
| 7008 | */ |
| 7009 | static int zipfileReadEOCD( |
| 7010 | ZipfileTab *pTab, /* Return errors here */ |
| 7011 | const u8 *aBlob, /* Pointer to in-memory file image */ |
| 7012 | int nBlob, /* Size of aBlob[] in bytes */ |
| 7013 | FILE *pFile, /* Read from this file if aBlob==0 */ |
| 7014 | ZipfileEOCD *pEOCD /* Object to populate */ |
| 7015 | ){ |
| 7016 | u8 *aRead = pTab->aBuffer; /* Temporary buffer */ |
| 7017 | int nRead; /* Bytes to read from file */ |
| 7018 | int rc = SQLITE_OK; |
| 7019 | |
| 7020 | if( aBlob==0 ){ |
| 7021 | i64 iOff; /* Offset to read from */ |
| 7022 | i64 szFile; /* Total size of file in bytes */ |
| 7023 | fseek(pFile, 0, SEEK_END); |
| 7024 | szFile = (i64)ftell(pFile); |
| 7025 | if( szFile==0 ){ |
| 7026 | memset(pEOCD, 0, sizeof(ZipfileEOCD)); |
| 7027 | return SQLITE_OK; |
| 7028 | } |
| 7029 | nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE)); |
| 7030 | iOff = szFile - nRead; |
| 7031 | rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg); |
| 7032 | }else{ |
| 7033 | nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE)); |
| 7034 | aRead = (u8*)&aBlob[nBlob-nRead]; |
| 7035 | } |
| 7036 | |
| 7037 | if( rc==SQLITE_OK ){ |
| 7038 | int i; |
| 7039 | |
| 7040 | /* Scan backwards looking for the signature bytes */ |
| 7041 | for(i=nRead-20; i>=0; i--){ |
| 7042 | if( aRead[i]==0x50 && aRead[i+1]==0x4b |
| 7043 | && aRead[i+2]==0x05 && aRead[i+3]==0x06 |
| 7044 | ){ |
| 7045 | break; |
| 7046 | } |
| 7047 | } |
| 7048 | if( i<0 ){ |
| 7049 | pTab->base.zErrMsg = sqlite3_mprintf( |
| 7050 | "cannot find end of central directory record" |
| 7051 | ); |
| 7052 | return SQLITE_ERROR; |
| 7053 | } |
| 7054 | |
| 7055 | aRead += i+4; |
| 7056 | pEOCD->iDisk = zipfileRead16(aRead); |
| 7057 | pEOCD->iFirstDisk = zipfileRead16(aRead); |
| 7058 | pEOCD->nEntry = zipfileRead16(aRead); |
| 7059 | pEOCD->nEntryTotal = zipfileRead16(aRead); |
| 7060 | pEOCD->nSize = zipfileRead32(aRead); |
| 7061 | pEOCD->iOffset = zipfileRead32(aRead); |
| 7062 | } |
| 7063 | |
| 7064 | return rc; |
| 7065 | } |
| 7066 |
no test coverage detected