7zIn.c 31 KB

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