7zIn.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281
  1. /* 7zIn.c */
  2. #include "7zIn.h"
  3. #include "7zCrc.h"
  4. #include "7zDecode.h"
  5. #define RINOM(x) { if((x) == 0) return SZE_OUTOFMEMORY; }
  6. void SzArDbExInit(CArchiveDatabaseEx *db)
  7. {
  8. SzArchiveDatabaseInit(&db->Database);
  9. db->FolderStartPackStreamIndex = 0;
  10. db->PackStreamStartPositions = 0;
  11. db->FolderStartFileIndex = 0;
  12. db->FileIndexToFolderIndexMap = 0;
  13. }
  14. void SzArDbExFree(CArchiveDatabaseEx *db, void (*freeFunc)(void *))
  15. {
  16. freeFunc(db->FolderStartPackStreamIndex);
  17. freeFunc(db->PackStreamStartPositions);
  18. freeFunc(db->FolderStartFileIndex);
  19. freeFunc(db->FileIndexToFolderIndexMap);
  20. SzArchiveDatabaseFree(&db->Database, freeFunc);
  21. SzArDbExInit(db);
  22. }
  23. /*
  24. CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
  25. {
  26. return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
  27. }
  28. CFileSize GetFilePackSize(int fileIndex) const
  29. {
  30. int folderIndex = FileIndexToFolderIndexMap[fileIndex];
  31. if (folderIndex >= 0)
  32. {
  33. const CFolder &folderInfo = Folders[folderIndex];
  34. if (FolderStartFileIndex[folderIndex] == fileIndex)
  35. return GetFolderFullPackSize(folderIndex);
  36. }
  37. return 0;
  38. }
  39. */
  40. #define MY_ALLOC(T, p, size, allocFunc) { if ((size) == 0) p = 0; else \
  41. if ((p = (T *)allocFunc((size) * sizeof(T))) == 0) return SZE_OUTOFMEMORY; }
  42. SZ_RESULT SzArDbExFill(CArchiveDatabaseEx *db, void * (*allocFunc)(size_t size))
  43. {
  44. UInt32 startPos = 0;
  45. CFileSize startPosSize = 0;
  46. UInt32 i;
  47. UInt32 folderIndex = 0;
  48. UInt32 indexInFolder = 0;
  49. MY_ALLOC(UInt32, db->FolderStartPackStreamIndex, db->Database.NumFolders, allocFunc);
  50. for(i = 0; i < db->Database.NumFolders; i++)
  51. {
  52. db->FolderStartPackStreamIndex[i] = startPos;
  53. startPos += db->Database.Folders[i].NumPackStreams;
  54. }
  55. MY_ALLOC(CFileSize, db->PackStreamStartPositions, db->Database.NumPackStreams, allocFunc);
  56. for(i = 0; i < db->Database.NumPackStreams; i++)
  57. {
  58. db->PackStreamStartPositions[i] = startPosSize;
  59. startPosSize += db->Database.PackSizes[i];
  60. }
  61. MY_ALLOC(UInt32, db->FolderStartFileIndex, db->Database.NumFolders, allocFunc);
  62. MY_ALLOC(UInt32, db->FileIndexToFolderIndexMap, db->Database.NumFiles, allocFunc);
  63. for (i = 0; i < db->Database.NumFiles; i++)
  64. {
  65. CFileItem *file = db->Database.Files + i;
  66. int emptyStream = !file->HasStream;
  67. if (emptyStream && indexInFolder == 0)
  68. {
  69. db->FileIndexToFolderIndexMap[i] = (UInt32)-1;
  70. continue;
  71. }
  72. if (indexInFolder == 0)
  73. {
  74. /*
  75. v3.13 incorrectly worked with empty folders
  76. v4.07: Loop for skipping empty folders
  77. */
  78. while(1)
  79. {
  80. if (folderIndex >= db->Database.NumFolders)
  81. return SZE_ARCHIVE_ERROR;
  82. db->FolderStartFileIndex[folderIndex] = i;
  83. if (db->Database.Folders[folderIndex].NumUnPackStreams != 0)
  84. break;
  85. folderIndex++;
  86. }
  87. }
  88. db->FileIndexToFolderIndexMap[i] = folderIndex;
  89. if (emptyStream)
  90. continue;
  91. indexInFolder++;
  92. if (indexInFolder >= db->Database.Folders[folderIndex].NumUnPackStreams)
  93. {
  94. folderIndex++;
  95. indexInFolder = 0;
  96. }
  97. }
  98. return SZ_OK;
  99. }
  100. CFileSize SzArDbGetFolderStreamPos(CArchiveDatabaseEx *db, UInt32 folderIndex, UInt32 indexInFolder)
  101. {
  102. return db->ArchiveInfo.DataStartPosition +
  103. db->PackStreamStartPositions[db->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
  104. }
  105. CFileSize SzArDbGetFolderFullPackSize(CArchiveDatabaseEx *db, UInt32 folderIndex)
  106. {
  107. UInt32 packStreamIndex = db->FolderStartPackStreamIndex[folderIndex];
  108. CFolder *folder = db->Database.Folders + folderIndex;
  109. CFileSize size = 0;
  110. UInt32 i;
  111. for (i = 0; i < folder->NumPackStreams; i++)
  112. size += db->Database.PackSizes[packStreamIndex + i];
  113. return size;
  114. }
  115. /*
  116. SZ_RESULT SzReadTime(const CObjectVector<CSzByteBuffer> &dataVector,
  117. CObjectVector<CFileItem> &files, UInt64 type)
  118. {
  119. CBoolVector boolVector;
  120. RINOK(ReadBoolVector2(files.Size(), boolVector))
  121. CStreamSwitch streamSwitch;
  122. RINOK(streamSwitch.Set(this, &dataVector));
  123. for(int i = 0; i < files.Size(); i++)
  124. {
  125. CFileItem &file = files[i];
  126. CArchiveFileTime fileTime;
  127. bool defined = boolVector[i];
  128. if (defined)
  129. {
  130. UInt32 low, high;
  131. RINOK(SzReadUInt32(low));
  132. RINOK(SzReadUInt32(high));
  133. fileTime.dwLowDateTime = low;
  134. fileTime.dwHighDateTime = high;
  135. }
  136. switch(type)
  137. {
  138. case k7zIdCreationTime:
  139. file.IsCreationTimeDefined = defined;
  140. if (defined)
  141. file.CreationTime = fileTime;
  142. break;
  143. case k7zIdLastWriteTime:
  144. file.IsLastWriteTimeDefined = defined;
  145. if (defined)
  146. file.LastWriteTime = fileTime;
  147. break;
  148. case k7zIdLastAccessTime:
  149. file.IsLastAccessTimeDefined = defined;
  150. if (defined)
  151. file.LastAccessTime = fileTime;
  152. break;
  153. }
  154. }
  155. return SZ_OK;
  156. }
  157. */
  158. SZ_RESULT SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
  159. {
  160. #ifdef _LZMA_IN_CB
  161. while (size > 0)
  162. {
  163. void *inBuffer; // Dennis Schridde: Make this compile with -Wall -Werror. Was Byte* before.
  164. size_t processedSize;
  165. RINOK(inStream->Read(inStream, (void **)&inBuffer, size, &processedSize));
  166. if (processedSize == 0 || processedSize > size)
  167. return SZE_FAIL;
  168. size -= processedSize;
  169. do
  170. {
  171. *data++ = *(Byte*)inBuffer++;
  172. }
  173. while (--processedSize != 0);
  174. }
  175. #else
  176. size_t processedSize;
  177. RINOK(inStream->Read(inStream, data, size, &processedSize));
  178. if (processedSize != size)
  179. return SZE_FAIL;
  180. #endif
  181. return SZ_OK;
  182. }
  183. SZ_RESULT SafeReadDirectByte(ISzInStream *inStream, Byte *data)
  184. {
  185. return SafeReadDirect(inStream, data, 1);
  186. }
  187. SZ_RESULT SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value)
  188. {
  189. int i;
  190. *value = 0;
  191. for (i = 0; i < 4; i++)
  192. {
  193. Byte b;
  194. RINOK(SafeReadDirectByte(inStream, &b));
  195. *value |= ((UInt32)b << (8 * i));
  196. }
  197. return SZ_OK;
  198. }
  199. SZ_RESULT SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value)
  200. {
  201. int i;
  202. *value = 0;
  203. for (i = 0; i < 8; i++)
  204. {
  205. Byte b;
  206. RINOK(SafeReadDirectByte(inStream, &b));
  207. *value |= ((UInt32)b << (8 * i));
  208. }
  209. return SZ_OK;
  210. }
  211. int TestSignatureCandidate(Byte *testBytes)
  212. {
  213. size_t i;
  214. for (i = 0; i < k7zSignatureSize; i++)
  215. if (testBytes[i] != k7zSignature[i])
  216. return 0;
  217. return 1;
  218. }
  219. typedef struct _CSzState
  220. {
  221. Byte *Data;
  222. size_t Size;
  223. }CSzData;
  224. SZ_RESULT SzReadByte(CSzData *sd, Byte *b)
  225. {
  226. if (sd->Size == 0)
  227. return SZE_ARCHIVE_ERROR;
  228. sd->Size--;
  229. *b = *sd->Data++;
  230. return SZ_OK;
  231. }
  232. SZ_RESULT SzReadBytes(CSzData *sd, Byte *data, size_t size)
  233. {
  234. size_t i;
  235. for (i = 0; i < size; i++)
  236. {
  237. RINOK(SzReadByte(sd, data + i));
  238. }
  239. return SZ_OK;
  240. }
  241. SZ_RESULT SzReadUInt32(CSzData *sd, UInt32 *value)
  242. {
  243. int i;
  244. *value = 0;
  245. for (i = 0; i < 4; i++)
  246. {
  247. Byte b;
  248. RINOK(SzReadByte(sd, &b));
  249. *value |= ((UInt32)(b) << (8 * i));
  250. }
  251. return SZ_OK;
  252. }
  253. SZ_RESULT SzReadNumber(CSzData *sd, UInt64 *value)
  254. {
  255. Byte firstByte;
  256. Byte mask = 0x80;
  257. int i;
  258. RINOK(SzReadByte(sd, &firstByte));
  259. *value = 0;
  260. for (i = 0; i < 8; i++)
  261. {
  262. Byte b;
  263. if ((firstByte & mask) == 0)
  264. {
  265. UInt64 highPart = firstByte & (mask - 1);
  266. *value += (highPart << (8 * i));
  267. return SZ_OK;
  268. }
  269. RINOK(SzReadByte(sd, &b));
  270. *value |= ((UInt64)b << (8 * i));
  271. mask >>= 1;
  272. }
  273. return SZ_OK;
  274. }
  275. SZ_RESULT SzReadSize(CSzData *sd, CFileSize *value)
  276. {
  277. UInt64 value64;
  278. RINOK(SzReadNumber(sd, &value64));
  279. *value = (CFileSize)value64;
  280. return SZ_OK;
  281. }
  282. SZ_RESULT SzReadNumber32(CSzData *sd, UInt32 *value)
  283. {
  284. UInt64 value64;
  285. RINOK(SzReadNumber(sd, &value64));
  286. if (value64 >= 0x80000000)
  287. return SZE_NOTIMPL;
  288. if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 2)))
  289. return SZE_NOTIMPL;
  290. *value = (UInt32)value64;
  291. return SZ_OK;
  292. }
  293. SZ_RESULT SzReadID(CSzData *sd, UInt64 *value)
  294. {
  295. return SzReadNumber(sd, value);
  296. }
  297. SZ_RESULT SzSkeepDataSize(CSzData *sd, UInt64 size)
  298. {
  299. if (size > sd->Size)
  300. return SZE_ARCHIVE_ERROR;
  301. sd->Size -= (size_t)size;
  302. sd->Data += (size_t)size;
  303. return SZ_OK;
  304. }
  305. SZ_RESULT SzSkeepData(CSzData *sd)
  306. {
  307. UInt64 size;
  308. RINOK(SzReadNumber(sd, &size));
  309. return SzSkeepDataSize(sd, size);
  310. }
  311. SZ_RESULT SzReadArchiveProperties(CSzData *sd)
  312. {
  313. while(1)
  314. {
  315. UInt64 type;
  316. RINOK(SzReadID(sd, &type));
  317. if (type == k7zIdEnd)
  318. break;
  319. SzSkeepData(sd);
  320. }
  321. return SZ_OK;
  322. }
  323. SZ_RESULT SzWaitAttribute(CSzData *sd, UInt64 attribute)
  324. {
  325. while(1)
  326. {
  327. UInt64 type;
  328. RINOK(SzReadID(sd, &type));
  329. if (type == attribute)
  330. return SZ_OK;
  331. if (type == k7zIdEnd)
  332. return SZE_ARCHIVE_ERROR;
  333. RINOK(SzSkeepData(sd));
  334. }
  335. }
  336. SZ_RESULT SzReadBoolVector(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
  337. {
  338. Byte b = 0;
  339. Byte mask = 0;
  340. size_t i;
  341. MY_ALLOC(Byte, *v, numItems, allocFunc);
  342. for(i = 0; i < numItems; i++)
  343. {
  344. if (mask == 0)
  345. {
  346. RINOK(SzReadByte(sd, &b));
  347. mask = 0x80;
  348. }
  349. (*v)[i] = (Byte)(((b & mask) != 0) ? 1 : 0);
  350. mask >>= 1;
  351. }
  352. return SZ_OK;
  353. }
  354. SZ_RESULT SzReadBoolVector2(CSzData *sd, size_t numItems, Byte **v, void * (*allocFunc)(size_t size))
  355. {
  356. Byte allAreDefined;
  357. size_t i;
  358. RINOK(SzReadByte(sd, &allAreDefined));
  359. if (allAreDefined == 0)
  360. return SzReadBoolVector(sd, numItems, v, allocFunc);
  361. MY_ALLOC(Byte, *v, numItems, allocFunc);
  362. for(i = 0; i < numItems; i++)
  363. (*v)[i] = 1;
  364. return SZ_OK;
  365. }
  366. SZ_RESULT SzReadHashDigests(
  367. CSzData *sd,
  368. size_t numItems,
  369. Byte **digestsDefined,
  370. UInt32 **digests,
  371. void * (*allocFunc)(size_t size))
  372. {
  373. size_t i;
  374. RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, allocFunc));
  375. MY_ALLOC(UInt32, *digests, numItems, allocFunc);
  376. for(i = 0; i < numItems; i++)
  377. if ((*digestsDefined)[i])
  378. {
  379. RINOK(SzReadUInt32(sd, (*digests) + i));
  380. }
  381. return SZ_OK;
  382. }
  383. SZ_RESULT SzReadPackInfo(
  384. CSzData *sd,
  385. CFileSize *dataOffset,
  386. UInt32 *numPackStreams,
  387. CFileSize **packSizes,
  388. Byte **packCRCsDefined,
  389. UInt32 **packCRCs,
  390. void * (*allocFunc)(size_t size))
  391. {
  392. UInt32 i;
  393. RINOK(SzReadSize(sd, dataOffset));
  394. RINOK(SzReadNumber32(sd, numPackStreams));
  395. RINOK(SzWaitAttribute(sd, k7zIdSize));
  396. MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, allocFunc);
  397. for(i = 0; i < *numPackStreams; i++)
  398. {
  399. RINOK(SzReadSize(sd, (*packSizes) + i));
  400. }
  401. while(1)
  402. {
  403. UInt64 type;
  404. RINOK(SzReadID(sd, &type));
  405. if (type == k7zIdEnd)
  406. break;
  407. if (type == k7zIdCRC)
  408. {
  409. RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, allocFunc));
  410. continue;
  411. }
  412. RINOK(SzSkeepData(sd));
  413. }
  414. if (*packCRCsDefined == 0)
  415. {
  416. MY_ALLOC(Byte, *packCRCsDefined, (size_t)*numPackStreams, allocFunc);
  417. MY_ALLOC(UInt32, *packCRCs, (size_t)*numPackStreams, allocFunc);
  418. for(i = 0; i < *numPackStreams; i++)
  419. {
  420. (*packCRCsDefined)[i] = 0;
  421. (*packCRCs)[i] = 0;
  422. }
  423. }
  424. return SZ_OK;
  425. }
  426. SZ_RESULT SzReadSwitch(CSzData *sd)
  427. {
  428. Byte external;
  429. RINOK(SzReadByte(sd, &external));
  430. return (external == 0) ? SZ_OK: SZE_ARCHIVE_ERROR;
  431. }
  432. SZ_RESULT SzGetNextFolderItem(CSzData *sd, CFolder *folder, void * (*allocFunc)(size_t size))
  433. {
  434. UInt32 numCoders;
  435. UInt32 numBindPairs;
  436. UInt32 numPackedStreams;
  437. UInt32 i;
  438. UInt32 numInStreams = 0;
  439. UInt32 numOutStreams = 0;
  440. RINOK(SzReadNumber32(sd, &numCoders));
  441. folder->NumCoders = numCoders;
  442. MY_ALLOC(CCoderInfo, folder->Coders, (size_t)numCoders, allocFunc);
  443. for (i = 0; i < numCoders; i++)
  444. SzCoderInfoInit(folder->Coders + i);
  445. for (i = 0; i < numCoders; i++)
  446. {
  447. Byte mainByte;
  448. CCoderInfo *coder = folder->Coders + i;
  449. {
  450. RINOK(SzReadByte(sd, &mainByte));
  451. coder->MethodID.IDSize = (Byte)(mainByte & 0xF);
  452. RINOK(SzReadBytes(sd, coder->MethodID.ID, coder->MethodID.IDSize));
  453. if ((mainByte & 0x10) != 0)
  454. {
  455. RINOK(SzReadNumber32(sd, &coder->NumInStreams));
  456. RINOK(SzReadNumber32(sd, &coder->NumOutStreams));
  457. }
  458. else
  459. {
  460. coder->NumInStreams = 1;
  461. coder->NumOutStreams = 1;
  462. }
  463. if ((mainByte & 0x20) != 0)
  464. {
  465. UInt64 propertiesSize = 0;
  466. RINOK(SzReadNumber(sd, &propertiesSize));
  467. if (!SzByteBufferCreate(&coder->Properties, (size_t)propertiesSize, allocFunc))
  468. return SZE_OUTOFMEMORY;
  469. RINOK(SzReadBytes(sd, coder->Properties.Items, (size_t)propertiesSize));
  470. }
  471. }
  472. while ((mainByte & 0x80) != 0)
  473. {
  474. RINOK(SzReadByte(sd, &mainByte));
  475. RINOK(SzSkeepDataSize(sd, (mainByte & 0xF)));
  476. if ((mainByte & 0x10) != 0)
  477. {
  478. UInt32 n;
  479. RINOK(SzReadNumber32(sd, &n));
  480. RINOK(SzReadNumber32(sd, &n));
  481. }
  482. if ((mainByte & 0x20) != 0)
  483. {
  484. UInt64 propertiesSize = 0;
  485. RINOK(SzReadNumber(sd, &propertiesSize));
  486. RINOK(SzSkeepDataSize(sd, propertiesSize));
  487. }
  488. }
  489. numInStreams += (UInt32)coder->NumInStreams;
  490. numOutStreams += (UInt32)coder->NumOutStreams;
  491. }
  492. numBindPairs = numOutStreams - 1;
  493. folder->NumBindPairs = numBindPairs;
  494. MY_ALLOC(CBindPair, folder->BindPairs, (size_t)numBindPairs, allocFunc);
  495. for (i = 0; i < numBindPairs; i++)
  496. {
  497. CBindPair *bindPair = folder->BindPairs + i;;
  498. RINOK(SzReadNumber32(sd, &bindPair->InIndex));
  499. RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
  500. }
  501. numPackedStreams = numInStreams - (UInt32)numBindPairs;
  502. folder->NumPackStreams = numPackedStreams;
  503. MY_ALLOC(UInt32, folder->PackStreams, (size_t)numPackedStreams, allocFunc);
  504. if (numPackedStreams == 1)
  505. {
  506. UInt32 j;
  507. UInt32 pi = 0;
  508. for (j = 0; j < numInStreams; j++)
  509. if (SzFolderFindBindPairForInStream(folder, j) < 0)
  510. {
  511. folder->PackStreams[pi++] = j;
  512. break;
  513. }
  514. }
  515. else
  516. for(i = 0; i < numPackedStreams; i++)
  517. {
  518. RINOK(SzReadNumber32(sd, folder->PackStreams + i));
  519. }
  520. return SZ_OK;
  521. }
  522. SZ_RESULT SzReadUnPackInfo(
  523. CSzData *sd,
  524. UInt32 *numFolders,
  525. CFolder **folders, /* for allocFunc */
  526. void * (*allocFunc)(size_t size),
  527. ISzAlloc *allocTemp)
  528. {
  529. UInt32 i;
  530. RINOK(SzWaitAttribute(sd, k7zIdFolder));
  531. RINOK(SzReadNumber32(sd, numFolders));
  532. {
  533. RINOK(SzReadSwitch(sd));
  534. MY_ALLOC(CFolder, *folders, (size_t)*numFolders, allocFunc);
  535. for(i = 0; i < *numFolders; i++)
  536. SzFolderInit((*folders) + i);
  537. for(i = 0; i < *numFolders; i++)
  538. {
  539. RINOK(SzGetNextFolderItem(sd, (*folders) + i, allocFunc));
  540. }
  541. }
  542. RINOK(SzWaitAttribute(sd, k7zIdCodersUnPackSize));
  543. for(i = 0; i < *numFolders; i++)
  544. {
  545. UInt32 j;
  546. CFolder *folder = (*folders) + i;
  547. UInt32 numOutStreams = SzFolderGetNumOutStreams(folder);
  548. MY_ALLOC(CFileSize, folder->UnPackSizes, (size_t)numOutStreams, allocFunc);
  549. for(j = 0; j < numOutStreams; j++)
  550. {
  551. RINOK(SzReadSize(sd, folder->UnPackSizes + j));
  552. }
  553. }
  554. while(1)
  555. {
  556. UInt64 type;
  557. RINOK(SzReadID(sd, &type));
  558. if (type == k7zIdEnd)
  559. return SZ_OK;
  560. if (type == k7zIdCRC)
  561. {
  562. SZ_RESULT res;
  563. Byte *crcsDefined = 0;
  564. UInt32 *crcs = 0;
  565. res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp->Alloc);
  566. if (res == SZ_OK)
  567. {
  568. for(i = 0; i < *numFolders; i++)
  569. {
  570. CFolder *folder = (*folders) + i;
  571. folder->UnPackCRCDefined = crcsDefined[i];
  572. folder->UnPackCRC = crcs[i];
  573. }
  574. }
  575. allocTemp->Free(crcs);
  576. allocTemp->Free(crcsDefined);
  577. RINOK(res);
  578. continue;
  579. }
  580. RINOK(SzSkeepData(sd));
  581. }
  582. }
  583. SZ_RESULT SzReadSubStreamsInfo(
  584. CSzData *sd,
  585. UInt32 numFolders,
  586. CFolder *folders,
  587. UInt32 *numUnPackStreams,
  588. CFileSize **unPackSizes,
  589. Byte **digestsDefined,
  590. UInt32 **digests,
  591. ISzAlloc *allocTemp)
  592. {
  593. UInt64 type = 0;
  594. UInt32 i;
  595. UInt32 si = 0;
  596. UInt32 numDigests = 0;
  597. for(i = 0; i < numFolders; i++)
  598. folders[i].NumUnPackStreams = 1;
  599. *numUnPackStreams = numFolders;
  600. while(1)
  601. {
  602. RINOK(SzReadID(sd, &type));
  603. if (type == k7zIdNumUnPackStream)
  604. {
  605. *numUnPackStreams = 0;
  606. for(i = 0; i < numFolders; i++)
  607. {
  608. UInt32 numStreams;
  609. RINOK(SzReadNumber32(sd, &numStreams));
  610. folders[i].NumUnPackStreams = numStreams;
  611. *numUnPackStreams += numStreams;
  612. }
  613. continue;
  614. }
  615. if (type == k7zIdCRC || type == k7zIdSize)
  616. break;
  617. if (type == k7zIdEnd)
  618. break;
  619. RINOK(SzSkeepData(sd));
  620. }
  621. if (*numUnPackStreams == 0)
  622. {
  623. *unPackSizes = 0;
  624. *digestsDefined = 0;
  625. *digests = 0;
  626. }
  627. else
  628. {
  629. *unPackSizes = (CFileSize *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(CFileSize));
  630. RINOM(*unPackSizes);
  631. *digestsDefined = (Byte *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(Byte));
  632. RINOM(*digestsDefined);
  633. *digests = (UInt32 *)allocTemp->Alloc((size_t)*numUnPackStreams * sizeof(UInt32));
  634. RINOM(*digests);
  635. }
  636. for(i = 0; i < numFolders; i++)
  637. {
  638. /*
  639. v3.13 incorrectly worked with empty folders
  640. v4.07: we check that folder is empty
  641. */
  642. CFileSize sum = 0;
  643. UInt32 j;
  644. UInt32 numSubstreams = folders[i].NumUnPackStreams;
  645. if (numSubstreams == 0)
  646. continue;
  647. if (type == k7zIdSize)
  648. for (j = 1; j < numSubstreams; j++)
  649. {
  650. CFileSize size;
  651. RINOK(SzReadSize(sd, &size));
  652. (*unPackSizes)[si++] = size;
  653. sum += size;
  654. }
  655. (*unPackSizes)[si++] = SzFolderGetUnPackSize(folders + i) - sum;
  656. }
  657. if (type == k7zIdSize)
  658. {
  659. RINOK(SzReadID(sd, &type));
  660. }
  661. for(i = 0; i < *numUnPackStreams; i++)
  662. {
  663. (*digestsDefined)[i] = 0;
  664. (*digests)[i] = 0;
  665. }
  666. for(i = 0; i < numFolders; i++)
  667. {
  668. UInt32 numSubstreams = folders[i].NumUnPackStreams;
  669. if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
  670. numDigests += numSubstreams;
  671. }
  672. si = 0;
  673. while(1)
  674. {
  675. if (type == k7zIdCRC)
  676. {
  677. int digestIndex = 0;
  678. Byte *digestsDefined2 = 0;
  679. UInt32 *digests2 = 0;
  680. SZ_RESULT res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp->Alloc);
  681. if (res == SZ_OK)
  682. {
  683. for (i = 0; i < numFolders; i++)
  684. {
  685. CFolder *folder = folders + i;
  686. UInt32 numSubstreams = folder->NumUnPackStreams;
  687. if (numSubstreams == 1 && folder->UnPackCRCDefined)
  688. {
  689. (*digestsDefined)[si] = 1;
  690. (*digests)[si] = folder->UnPackCRC;
  691. si++;
  692. }
  693. else
  694. {
  695. UInt32 j;
  696. for (j = 0; j < numSubstreams; j++, digestIndex++)
  697. {
  698. (*digestsDefined)[si] = digestsDefined2[digestIndex];
  699. (*digests)[si] = digests2[digestIndex];
  700. si++;
  701. }
  702. }
  703. }
  704. }
  705. allocTemp->Free(digestsDefined2);
  706. allocTemp->Free(digests2);
  707. RINOK(res);
  708. }
  709. else if (type == k7zIdEnd)
  710. return SZ_OK;
  711. else
  712. {
  713. RINOK(SzSkeepData(sd));
  714. }
  715. RINOK(SzReadID(sd, &type));
  716. }
  717. }
  718. SZ_RESULT SzReadStreamsInfo(
  719. CSzData *sd,
  720. CFileSize *dataOffset,
  721. CArchiveDatabase *db,
  722. UInt32 *numUnPackStreams,
  723. CFileSize **unPackSizes, /* allocTemp */
  724. Byte **digestsDefined, /* allocTemp */
  725. UInt32 **digests, /* allocTemp */
  726. void * (*allocFunc)(size_t size),
  727. ISzAlloc *allocTemp)
  728. {
  729. while(1)
  730. {
  731. UInt64 type;
  732. RINOK(SzReadID(sd, &type));
  733. if ((UInt64)(int)type != type)
  734. return SZE_FAIL;
  735. switch((int)type)
  736. {
  737. case k7zIdEnd:
  738. return SZ_OK;
  739. case k7zIdPackInfo:
  740. {
  741. RINOK(SzReadPackInfo(sd, dataOffset, &db->NumPackStreams,
  742. &db->PackSizes, &db->PackCRCsDefined, &db->PackCRCs, allocFunc));
  743. break;
  744. }
  745. case k7zIdUnPackInfo:
  746. {
  747. RINOK(SzReadUnPackInfo(sd, &db->NumFolders, &db->Folders, allocFunc, allocTemp));
  748. break;
  749. }
  750. case k7zIdSubStreamsInfo:
  751. {
  752. RINOK(SzReadSubStreamsInfo(sd, db->NumFolders, db->Folders,
  753. numUnPackStreams, unPackSizes, digestsDefined, digests, allocTemp));
  754. break;
  755. }
  756. default:
  757. return SZE_FAIL;
  758. }
  759. }
  760. }
  761. Byte kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
  762. SZ_RESULT SzReadFileNames(CSzData *sd, UInt32 numFiles, CFileItem *files,
  763. void * (*allocFunc)(size_t size))
  764. {
  765. UInt32 i;
  766. for(i = 0; i < numFiles; i++)
  767. {
  768. UInt32 len = 0;
  769. UInt32 pos = 0;
  770. CFileItem *file = files + i;
  771. while(pos + 2 <= sd->Size)
  772. {
  773. int numAdds;
  774. UInt32 value = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
  775. pos += 2;
  776. len++;
  777. if (value == 0)
  778. break;
  779. if (value < 0x80)
  780. continue;
  781. if (value >= 0xD800 && value < 0xE000)
  782. {
  783. UInt32 c2;
  784. if (value >= 0xDC00)
  785. return SZE_ARCHIVE_ERROR;
  786. if (pos + 2 > sd->Size)
  787. return SZE_ARCHIVE_ERROR;
  788. c2 = (UInt32)(sd->Data[pos] | (((UInt32)sd->Data[pos + 1]) << 8));
  789. pos += 2;
  790. if (c2 < 0xDC00 || c2 >= 0xE000)
  791. return SZE_ARCHIVE_ERROR;
  792. value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
  793. }
  794. for (numAdds = 1; numAdds < 5; numAdds++)
  795. if (value < (((UInt32)1) << (numAdds * 5 + 6)))
  796. break;
  797. len += numAdds;
  798. }
  799. MY_ALLOC(char, file->Name, (size_t)len, allocFunc);
  800. len = 0;
  801. while(2 <= sd->Size)
  802. {
  803. int numAdds;
  804. UInt32 value = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
  805. SzSkeepDataSize(sd, 2);
  806. if (value < 0x80)
  807. {
  808. file->Name[len++] = (char)value;
  809. if (value == 0)
  810. break;
  811. continue;
  812. }
  813. if (value >= 0xD800 && value < 0xE000)
  814. {
  815. UInt32 c2 = (UInt32)(sd->Data[0] | (((UInt32)sd->Data[1]) << 8));
  816. SzSkeepDataSize(sd, 2);
  817. value = ((value - 0xD800) << 10) | (c2 - 0xDC00);
  818. }
  819. for (numAdds = 1; numAdds < 5; numAdds++)
  820. if (value < (((UInt32)1) << (numAdds * 5 + 6)))
  821. break;
  822. file->Name[len++] = (char)(kUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
  823. do
  824. {
  825. numAdds--;
  826. file->Name[len++] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
  827. }
  828. while(numAdds > 0);
  829. len += numAdds;
  830. }
  831. }
  832. return SZ_OK;
  833. }
  834. SZ_RESULT SzReadHeader2(
  835. CSzData *sd,
  836. CArchiveDatabaseEx *db, /* allocMain */
  837. CFileSize **unPackSizes, /* allocTemp */
  838. Byte **digestsDefined, /* allocTemp */
  839. UInt32 **digests, /* allocTemp */
  840. Byte **emptyStreamVector, /* allocTemp */
  841. Byte **emptyFileVector, /* allocTemp */
  842. ISzAlloc *allocMain,
  843. ISzAlloc *allocTemp)
  844. {
  845. UInt64 type;
  846. UInt32 numUnPackStreams = 0;
  847. UInt32 numFiles = 0;
  848. CFileItem *files = 0;
  849. UInt32 numEmptyStreams = 0;
  850. UInt32 i;
  851. RINOK(SzReadID(sd, &type));
  852. if (type == k7zIdArchiveProperties)
  853. {
  854. RINOK(SzReadArchiveProperties(sd));
  855. RINOK(SzReadID(sd, &type));
  856. }
  857. if (type == k7zIdMainStreamsInfo)
  858. {
  859. RINOK(SzReadStreamsInfo(sd,
  860. &db->ArchiveInfo.DataStartPosition,
  861. &db->Database,
  862. &numUnPackStreams,
  863. unPackSizes,
  864. digestsDefined,
  865. digests, allocMain->Alloc, allocTemp));
  866. db->ArchiveInfo.DataStartPosition += db->ArchiveInfo.StartPositionAfterHeader;
  867. RINOK(SzReadID(sd, &type));
  868. }
  869. if (type == k7zIdEnd)
  870. return SZ_OK;
  871. if (type != k7zIdFilesInfo)
  872. return SZE_ARCHIVE_ERROR;
  873. RINOK(SzReadNumber32(sd, &numFiles));
  874. db->Database.NumFiles = numFiles;
  875. MY_ALLOC(CFileItem, files, (size_t)numFiles, allocMain->Alloc);
  876. db->Database.Files = files;
  877. for(i = 0; i < numFiles; i++)
  878. SzFileInit(files + i);
  879. while(1)
  880. {
  881. UInt64 type;
  882. UInt64 size;
  883. RINOK(SzReadID(sd, &type));
  884. if (type == k7zIdEnd)
  885. break;
  886. RINOK(SzReadNumber(sd, &size));
  887. if ((UInt64)(int)type != type)
  888. {
  889. RINOK(SzSkeepDataSize(sd, size));
  890. }
  891. else
  892. switch((int)type)
  893. {
  894. case k7zIdName:
  895. {
  896. RINOK(SzReadSwitch(sd));
  897. RINOK(SzReadFileNames(sd, numFiles, files, allocMain->Alloc))
  898. break;
  899. }
  900. case k7zIdEmptyStream:
  901. {
  902. RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp->Alloc));
  903. numEmptyStreams = 0;
  904. for (i = 0; i < numFiles; i++)
  905. if ((*emptyStreamVector)[i])
  906. numEmptyStreams++;
  907. break;
  908. }
  909. case k7zIdEmptyFile:
  910. {
  911. RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp->Alloc));
  912. break;
  913. }
  914. default:
  915. {
  916. RINOK(SzSkeepDataSize(sd, size));
  917. }
  918. }
  919. }
  920. {
  921. UInt32 emptyFileIndex = 0;
  922. UInt32 sizeIndex = 0;
  923. for(i = 0; i < numFiles; i++)
  924. {
  925. CFileItem *file = files + i;
  926. file->IsAnti = 0;
  927. if (*emptyStreamVector == 0)
  928. file->HasStream = 1;
  929. else
  930. file->HasStream = (Byte)((*emptyStreamVector)[i] ? 0 : 1);
  931. if(file->HasStream)
  932. {
  933. file->IsDirectory = 0;
  934. file->Size = (*unPackSizes)[sizeIndex];
  935. file->FileCRC = (*digests)[sizeIndex];
  936. file->IsFileCRCDefined = (Byte)(*digestsDefined)[sizeIndex];
  937. sizeIndex++;
  938. }
  939. else
  940. {
  941. if (*emptyFileVector == 0)
  942. file->IsDirectory = 1;
  943. else
  944. file->IsDirectory = (Byte)((*emptyFileVector)[emptyFileIndex] ? 0 : 1);
  945. emptyFileIndex++;
  946. file->Size = 0;
  947. file->IsFileCRCDefined = 0;
  948. }
  949. }
  950. }
  951. return SzArDbExFill(db, allocMain->Alloc);
  952. }
  953. SZ_RESULT SzReadHeader(
  954. CSzData *sd,
  955. CArchiveDatabaseEx *db,
  956. ISzAlloc *allocMain,
  957. ISzAlloc *allocTemp)
  958. {
  959. CFileSize *unPackSizes = 0;
  960. Byte *digestsDefined = 0;
  961. UInt32 *digests = 0;
  962. Byte *emptyStreamVector = 0;
  963. Byte *emptyFileVector = 0;
  964. SZ_RESULT res = SzReadHeader2(sd, db,
  965. &unPackSizes, &digestsDefined, &digests,
  966. &emptyStreamVector, &emptyFileVector,
  967. allocMain, allocTemp);
  968. allocTemp->Free(unPackSizes);
  969. allocTemp->Free(digestsDefined);
  970. allocTemp->Free(digests);
  971. allocTemp->Free(emptyStreamVector);
  972. allocTemp->Free(emptyFileVector);
  973. return res;
  974. }
  975. SZ_RESULT SzReadAndDecodePackedStreams2(
  976. ISzInStream *inStream,
  977. CSzData *sd,
  978. CSzByteBuffer *outBuffer,
  979. CFileSize baseOffset,
  980. CArchiveDatabase *db,
  981. CFileSize **unPackSizes,
  982. Byte **digestsDefined,
  983. UInt32 **digests,
  984. #ifndef _LZMA_IN_CB
  985. Byte **inBuffer,
  986. #endif
  987. ISzAlloc *allocTemp)
  988. {
  989. UInt32 numUnPackStreams = 0;
  990. CFileSize dataStartPos;
  991. CFolder *folder;
  992. #ifndef _LZMA_IN_CB
  993. CFileSize packSize = 0;
  994. UInt32 i = 0;
  995. #endif
  996. CFileSize unPackSize;
  997. size_t outRealSize;
  998. SZ_RESULT res;
  999. RINOK(SzReadStreamsInfo(sd, &dataStartPos, db,
  1000. &numUnPackStreams, unPackSizes, digestsDefined, digests,
  1001. allocTemp->Alloc, allocTemp));
  1002. dataStartPos += baseOffset;
  1003. if (db->NumFolders != 1)
  1004. return SZE_ARCHIVE_ERROR;
  1005. folder = db->Folders;
  1006. unPackSize = SzFolderGetUnPackSize(folder);
  1007. RINOK(inStream->Seek(inStream, dataStartPos));
  1008. #ifndef _LZMA_IN_CB
  1009. for (i = 0; i < db->NumPackStreams; i++)
  1010. packSize += db->PackSizes[i];
  1011. MY_ALLOC(Byte, *inBuffer, (size_t)packSize, allocTemp->Alloc);
  1012. RINOK(SafeReadDirect(inStream, *inBuffer, (size_t)packSize));
  1013. #endif
  1014. if (!SzByteBufferCreate(outBuffer, (size_t)unPackSize, allocTemp->Alloc))
  1015. return SZE_OUTOFMEMORY;
  1016. res = SzDecode(db->PackSizes, folder,
  1017. #ifdef _LZMA_IN_CB
  1018. inStream,
  1019. #else
  1020. *inBuffer,
  1021. #endif
  1022. outBuffer->Items, (size_t)unPackSize,
  1023. &outRealSize, allocTemp);
  1024. RINOK(res)
  1025. if (outRealSize != (UInt32)unPackSize)
  1026. return SZE_FAIL;
  1027. if (folder->UnPackCRCDefined)
  1028. if (!CrcVerifyDigest(folder->UnPackCRC, outBuffer->Items, (size_t)unPackSize))
  1029. return SZE_FAIL;
  1030. return SZ_OK;
  1031. }
  1032. SZ_RESULT SzReadAndDecodePackedStreams(
  1033. ISzInStream *inStream,
  1034. CSzData *sd,
  1035. CSzByteBuffer *outBuffer,
  1036. CFileSize baseOffset,
  1037. ISzAlloc *allocTemp)
  1038. {
  1039. CArchiveDatabase db;
  1040. CFileSize *unPackSizes = 0;
  1041. Byte *digestsDefined = 0;
  1042. UInt32 *digests = 0;
  1043. #ifndef _LZMA_IN_CB
  1044. Byte *inBuffer = 0;
  1045. #endif
  1046. SZ_RESULT res;
  1047. SzArchiveDatabaseInit(&db);
  1048. res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset,
  1049. &db, &unPackSizes, &digestsDefined, &digests,
  1050. #ifndef _LZMA_IN_CB
  1051. &inBuffer,
  1052. #endif
  1053. allocTemp);
  1054. SzArchiveDatabaseFree(&db, allocTemp->Free);
  1055. allocTemp->Free(unPackSizes);
  1056. allocTemp->Free(digestsDefined);
  1057. allocTemp->Free(digests);
  1058. #ifndef _LZMA_IN_CB
  1059. allocTemp->Free(inBuffer);
  1060. #endif
  1061. return res;
  1062. }
  1063. SZ_RESULT SzArchiveOpen2(
  1064. ISzInStream *inStream,
  1065. CArchiveDatabaseEx *db,
  1066. ISzAlloc *allocMain,
  1067. ISzAlloc *allocTemp)
  1068. {
  1069. Byte signature[k7zSignatureSize];
  1070. Byte version;
  1071. UInt32 crcFromArchive;
  1072. UInt64 nextHeaderOffset;
  1073. UInt64 nextHeaderSize;
  1074. UInt32 nextHeaderCRC;
  1075. UInt32 crc;
  1076. CFileSize pos = 0;
  1077. CSzByteBuffer buffer;
  1078. CSzData sd;
  1079. SZ_RESULT res;
  1080. RINOK(SafeReadDirect(inStream, signature, k7zSignatureSize));
  1081. if (!TestSignatureCandidate(signature))
  1082. return SZE_ARCHIVE_ERROR;
  1083. /*
  1084. db.Clear();
  1085. db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
  1086. */
  1087. RINOK(SafeReadDirectByte(inStream, &version));
  1088. if (version != k7zMajorVersion)
  1089. return SZE_ARCHIVE_ERROR;
  1090. RINOK(SafeReadDirectByte(inStream, &version));
  1091. RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive));
  1092. CrcInit(&crc);
  1093. RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset));
  1094. CrcUpdateUInt64(&crc, nextHeaderOffset);
  1095. RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize));
  1096. CrcUpdateUInt64(&crc, nextHeaderSize);
  1097. RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC));
  1098. CrcUpdateUInt32(&crc, nextHeaderCRC);
  1099. pos = k7zStartHeaderSize;
  1100. db->ArchiveInfo.StartPositionAfterHeader = pos;
  1101. if (CrcGetDigest(&crc) != crcFromArchive)
  1102. return SZE_ARCHIVE_ERROR;
  1103. if (nextHeaderSize == 0)
  1104. return SZ_OK;
  1105. RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset)));
  1106. if (!SzByteBufferCreate(&buffer, (size_t)nextHeaderSize, allocTemp->Alloc))
  1107. return SZE_OUTOFMEMORY;
  1108. res = SafeReadDirect(inStream, buffer.Items, (size_t)nextHeaderSize);
  1109. if (res == SZ_OK)
  1110. {
  1111. if (CrcVerifyDigest(nextHeaderCRC, buffer.Items, (UInt32)nextHeaderSize))
  1112. {
  1113. while (1)
  1114. {
  1115. UInt64 type;
  1116. sd.Data = buffer.Items;
  1117. sd.Size = buffer.Capacity;
  1118. res = SzReadID(&sd, &type);
  1119. if (res != SZ_OK)
  1120. break;
  1121. if (type == k7zIdHeader)
  1122. {
  1123. res = SzReadHeader(&sd, db, allocMain, allocTemp);
  1124. break;
  1125. }
  1126. if (type != k7zIdEncodedHeader)
  1127. {
  1128. res = SZE_ARCHIVE_ERROR;
  1129. break;
  1130. }
  1131. {
  1132. CSzByteBuffer outBuffer;
  1133. res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
  1134. db->ArchiveInfo.StartPositionAfterHeader,
  1135. allocTemp);
  1136. if (res != SZ_OK)
  1137. {
  1138. SzByteBufferFree(&outBuffer, allocTemp->Free);
  1139. break;
  1140. }
  1141. SzByteBufferFree(&buffer, allocTemp->Free);
  1142. buffer.Items = outBuffer.Items;
  1143. buffer.Capacity = outBuffer.Capacity;
  1144. }
  1145. }
  1146. }
  1147. }
  1148. SzByteBufferFree(&buffer, allocTemp->Free);
  1149. return res;
  1150. }
  1151. SZ_RESULT SzArchiveOpen(
  1152. ISzInStream *inStream,
  1153. CArchiveDatabaseEx *db,
  1154. ISzAlloc *allocMain,
  1155. ISzAlloc *allocTemp)
  1156. {
  1157. SZ_RESULT res = SzArchiveOpen2(inStream, db, allocMain, allocTemp);
  1158. if (res != SZ_OK)
  1159. SzArDbExFree(db, allocMain->Free);
  1160. return res;
  1161. }