Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1839 lines
46 KiB

  1. /* 7zArcIn.c -- 7z Input functions
  2. 2014-06-16 : Igor Pavlov : Public domain */
  3. #include "Precomp.h"
  4. #include <string.h>
  5. #include "7z.h"
  6. #include "7zBuf.h"
  7. #include "7zCrc.h"
  8. #include "CpuArch.h"
  9. #define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \
  10. if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; }
  11. #define k7zMajorVersion 0
  12. enum EIdEnum
  13. {
  14. k7zIdEnd,
  15. k7zIdHeader,
  16. k7zIdArchiveProperties,
  17. k7zIdAdditionalStreamsInfo,
  18. k7zIdMainStreamsInfo,
  19. k7zIdFilesInfo,
  20. k7zIdPackInfo,
  21. k7zIdUnpackInfo,
  22. k7zIdSubStreamsInfo,
  23. k7zIdSize,
  24. k7zIdCRC,
  25. k7zIdFolder,
  26. k7zIdCodersUnpackSize,
  27. k7zIdNumUnpackStream,
  28. k7zIdEmptyStream,
  29. k7zIdEmptyFile,
  30. k7zIdAnti,
  31. k7zIdName,
  32. k7zIdCTime,
  33. k7zIdATime,
  34. k7zIdMTime,
  35. k7zIdWinAttrib,
  36. k7zIdComment,
  37. k7zIdEncodedHeader,
  38. k7zIdStartPos,
  39. k7zIdDummy
  40. // k7zNtSecure,
  41. // k7zParent,
  42. // k7zIsReal
  43. };
  44. Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
  45. #define NUM_FOLDER_CODERS_MAX 32
  46. #define NUM_CODER_STREAMS_MAX 32
  47. /*
  48. static int SzFolder_FindBindPairForInStream(const CSzFolder *p, UInt32 inStreamIndex)
  49. {
  50. UInt32 i;
  51. for (i = 0; i < p->NumBindPairs; i++)
  52. if (p->BindPairs[i].InIndex == inStreamIndex)
  53. return i;
  54. return -1;
  55. }
  56. */
  57. #define SzBitUi32s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; }
  58. static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
  59. {
  60. MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
  61. MY_ALLOC(UInt32, p->Vals, num, alloc);
  62. return SZ_OK;
  63. }
  64. void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)
  65. {
  66. IAlloc_Free(alloc, p->Defs); p->Defs = 0;
  67. IAlloc_Free(alloc, p->Vals); p->Vals = 0;
  68. }
  69. #define SzBitUi64s_Init(p) { (p)->Defs = 0; (p)->Vals = 0; }
  70. void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)
  71. {
  72. IAlloc_Free(alloc, p->Defs); p->Defs = 0;
  73. IAlloc_Free(alloc, p->Vals); p->Vals = 0;
  74. }
  75. static void SzAr_Init(CSzAr *p)
  76. {
  77. p->NumPackStreams = 0;
  78. p->NumFolders = 0;
  79. p->PackPositions = 0;
  80. SzBitUi32s_Init(&p->FolderCRCs);
  81. // p->Folders = 0;
  82. p->FoCodersOffsets = 0;
  83. p->FoSizesOffsets = 0;
  84. p->FoStartPackStreamIndex = 0;
  85. p->CodersData = 0;
  86. // p->CoderUnpackSizes = 0;
  87. p->UnpackSizesData = 0;
  88. }
  89. static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
  90. {
  91. IAlloc_Free(alloc, p->UnpackSizesData);
  92. IAlloc_Free(alloc, p->CodersData);
  93. // IAlloc_Free(alloc, p->CoderUnpackSizes);
  94. IAlloc_Free(alloc, p->PackPositions);
  95. // IAlloc_Free(alloc, p->Folders);
  96. IAlloc_Free(alloc, p->FoCodersOffsets);
  97. IAlloc_Free(alloc, p->FoSizesOffsets);
  98. IAlloc_Free(alloc, p->FoStartPackStreamIndex);
  99. SzBitUi32s_Free(&p->FolderCRCs, alloc);
  100. SzAr_Init(p);
  101. }
  102. void SzArEx_Init(CSzArEx *p)
  103. {
  104. SzAr_Init(&p->db);
  105. p->NumFiles = 0;
  106. p->dataPos = 0;
  107. // p->Files = 0;
  108. p->UnpackPositions = 0;
  109. // p->IsEmptyFiles = 0;
  110. p->IsDirs = 0;
  111. // p->FolderStartPackStreamIndex = 0;
  112. // p->PackStreamStartPositions = 0;
  113. p->FolderStartFileIndex = 0;
  114. p->FileIndexToFolderIndexMap = 0;
  115. p->FileNameOffsets = 0;
  116. p->FileNames = 0;
  117. SzBitUi32s_Init(&p->CRCs);
  118. SzBitUi32s_Init(&p->Attribs);
  119. // SzBitUi32s_Init(&p->Parents);
  120. SzBitUi64s_Init(&p->MTime);
  121. SzBitUi64s_Init(&p->CTime);
  122. }
  123. void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
  124. {
  125. // IAlloc_Free(alloc, p->FolderStartPackStreamIndex);
  126. // IAlloc_Free(alloc, p->PackStreamStartPositions);
  127. IAlloc_Free(alloc, p->FolderStartFileIndex);
  128. IAlloc_Free(alloc, p->FileIndexToFolderIndexMap);
  129. IAlloc_Free(alloc, p->FileNameOffsets);
  130. IAlloc_Free(alloc, p->FileNames);
  131. SzBitUi64s_Free(&p->CTime, alloc);
  132. SzBitUi64s_Free(&p->MTime, alloc);
  133. SzBitUi32s_Free(&p->CRCs, alloc);
  134. // SzBitUi32s_Free(&p->Parents, alloc);
  135. SzBitUi32s_Free(&p->Attribs, alloc);
  136. IAlloc_Free(alloc, p->IsDirs);
  137. // IAlloc_Free(alloc, p->IsEmptyFiles);
  138. IAlloc_Free(alloc, p->UnpackPositions);
  139. // IAlloc_Free(alloc, p->Files);
  140. SzAr_Free(&p->db, alloc);
  141. SzArEx_Init(p);
  142. }
  143. static int TestSignatureCandidate(Byte *testBytes)
  144. {
  145. size_t i;
  146. for (i = 0; i < k7zSignatureSize; i++)
  147. if (testBytes[i] != k7zSignature[i])
  148. return 0;
  149. return 1;
  150. }
  151. #define SzData_Clear(p) { (p)->Data = 0; (p)->Size = 0; }
  152. static SRes SzReadByte(CSzData *sd, Byte *b)
  153. {
  154. if (sd->Size == 0)
  155. return SZ_ERROR_ARCHIVE;
  156. sd->Size--;
  157. *b = *sd->Data++;
  158. return SZ_OK;
  159. }
  160. #define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++;
  161. #define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest)
  162. #define SZ_READ_BYTE_2(dest) if (sd.Size == 0) return SZ_ERROR_ARCHIVE; sd.Size--; dest = *sd.Data++;
  163. #define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); }
  164. #define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); }
  165. #define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \
  166. dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4);
  167. static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
  168. {
  169. Byte firstByte, mask;
  170. unsigned i;
  171. UInt32 v;
  172. SZ_READ_BYTE(firstByte);
  173. if ((firstByte & 0x80) == 0)
  174. {
  175. *value = firstByte;
  176. return SZ_OK;
  177. }
  178. SZ_READ_BYTE(v);
  179. if ((firstByte & 0x40) == 0)
  180. {
  181. *value = (((UInt32)firstByte & 0x3F) << 8) | v;
  182. return SZ_OK;
  183. }
  184. SZ_READ_BYTE(mask);
  185. *value = v | ((UInt32)mask << 8);
  186. mask = 0x20;
  187. for (i = 2; i < 8; i++)
  188. {
  189. Byte b;
  190. if ((firstByte & mask) == 0)
  191. {
  192. UInt64 highPart = firstByte & (mask - 1);
  193. *value |= (highPart << (8 * i));
  194. return SZ_OK;
  195. }
  196. SZ_READ_BYTE(b);
  197. *value |= ((UInt64)b << (8 * i));
  198. mask >>= 1;
  199. }
  200. return SZ_OK;
  201. }
  202. /*
  203. static MY_NO_INLINE const Byte *SzReadNumbers(const Byte *data, const Byte *dataLim, UInt64 *values, UInt32 num)
  204. {
  205. for (; num != 0; num--)
  206. {
  207. Byte firstByte;
  208. Byte mask;
  209. unsigned i;
  210. UInt32 v;
  211. UInt64 value;
  212. if (data == dataLim)
  213. return NULL;
  214. firstByte = *data++;
  215. if ((firstByte & 0x80) == 0)
  216. {
  217. *values++ = firstByte;
  218. continue;
  219. }
  220. if (data == dataLim)
  221. return NULL;
  222. v = *data++;
  223. if ((firstByte & 0x40) == 0)
  224. {
  225. *values++ = (((UInt32)firstByte & 0x3F) << 8) | v;
  226. continue;
  227. }
  228. if (data == dataLim)
  229. return NULL;
  230. value = v | ((UInt32)*data++ << 8);
  231. mask = 0x20;
  232. for (i = 2; i < 8; i++)
  233. {
  234. if ((firstByte & mask) == 0)
  235. {
  236. UInt64 highPart = firstByte & (mask - 1);
  237. value |= (highPart << (8 * i));
  238. break;
  239. }
  240. if (data == dataLim)
  241. return NULL;
  242. value |= ((UInt64)*data++ << (8 * i));
  243. mask >>= 1;
  244. }
  245. *values++ = value;
  246. }
  247. return data;
  248. }
  249. */
  250. static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value)
  251. {
  252. Byte firstByte;
  253. UInt64 value64;
  254. if (sd->Size == 0)
  255. return SZ_ERROR_ARCHIVE;
  256. firstByte = *sd->Data;
  257. if ((firstByte & 0x80) == 0)
  258. {
  259. *value = firstByte;
  260. sd->Data++;
  261. sd->Size--;
  262. return SZ_OK;
  263. }
  264. RINOK(ReadNumber(sd, &value64));
  265. if (value64 >= (UInt32)0x80000000 - 1)
  266. return SZ_ERROR_UNSUPPORTED;
  267. if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 4)))
  268. return SZ_ERROR_UNSUPPORTED;
  269. *value = (UInt32)value64;
  270. return SZ_OK;
  271. }
  272. #define ReadID(sd, value) ReadNumber(sd, value)
  273. static SRes SkipData(CSzData *sd)
  274. {
  275. UInt64 size;
  276. RINOK(ReadNumber(sd, &size));
  277. if (size > sd->Size)
  278. return SZ_ERROR_ARCHIVE;
  279. SKIP_DATA(sd, size);
  280. return SZ_OK;
  281. }
  282. static SRes WaitId(CSzData *sd, UInt64 id)
  283. {
  284. for (;;)
  285. {
  286. UInt64 type;
  287. RINOK(ReadID(sd, &type));
  288. if (type == id)
  289. return SZ_OK;
  290. if (type == k7zIdEnd)
  291. return SZ_ERROR_ARCHIVE;
  292. RINOK(SkipData(sd));
  293. }
  294. }
  295. static SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v)
  296. {
  297. UInt32 numBytes = (numItems + 7) >> 3;
  298. if (numBytes > sd->Size)
  299. return SZ_ERROR_ARCHIVE;
  300. *v = sd->Data;
  301. SKIP_DATA(sd, numBytes);
  302. return SZ_OK;
  303. }
  304. static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
  305. {
  306. Byte b = 0;
  307. unsigned m = 0;
  308. UInt32 sum = 0;
  309. for (; numItems != 0; numItems--)
  310. {
  311. if (m == 0)
  312. {
  313. b = *bits++;
  314. m = 8;
  315. }
  316. m--;
  317. sum += ((b >> m) & 1);
  318. }
  319. return sum ;
  320. }
  321. static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)
  322. {
  323. Byte allAreDefined;
  324. UInt32 i;
  325. Byte *v2;
  326. UInt32 numBytes = (numItems + 7) >> 3;
  327. RINOK(SzReadByte(sd, &allAreDefined));
  328. if (allAreDefined == 0)
  329. {
  330. if (numBytes > sd->Size)
  331. return SZ_ERROR_ARCHIVE;
  332. MY_ALLOC(Byte, *v, numBytes, alloc);
  333. memcpy(*v, sd->Data, numBytes);
  334. SKIP_DATA(sd, numBytes);
  335. return SZ_OK;
  336. }
  337. MY_ALLOC(Byte, *v, numBytes, alloc);
  338. v2 = *v;
  339. for (i = 0; i < numBytes; i++)
  340. v2[i] = 0xFF;
  341. {
  342. unsigned numBits = (unsigned)numItems & 7;
  343. if (numBits != 0)
  344. v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));
  345. }
  346. return SZ_OK;
  347. }
  348. static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
  349. {
  350. UInt32 i;
  351. CSzData sd;
  352. UInt32 *vals;
  353. const Byte *defs;
  354. MY_ALLOC(UInt32, crcs->Vals, numItems, alloc);
  355. sd = *sd2;
  356. defs = crcs->Defs;
  357. vals = crcs->Vals;
  358. for (i = 0; i < numItems; i++)
  359. if (SzBitArray_Check(defs, i))
  360. {
  361. SZ_READ_32(vals[i]);
  362. }
  363. else
  364. vals[i] = 0;
  365. *sd2 = sd;
  366. return SZ_OK;
  367. }
  368. static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
  369. {
  370. SzBitUi32s_Free(crcs, alloc);
  371. RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc));
  372. return ReadUi32s(sd, numItems, crcs, alloc);
  373. }
  374. static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
  375. {
  376. Byte allAreDefined;
  377. UInt32 numDefined = numItems;
  378. RINOK(SzReadByte(sd, &allAreDefined));
  379. if (!allAreDefined)
  380. {
  381. size_t numBytes = (numItems + 7) >> 3;
  382. if (numBytes > sd->Size)
  383. return SZ_ERROR_ARCHIVE;
  384. numDefined = CountDefinedBits(sd->Data, numItems);
  385. SKIP_DATA(sd, numBytes);
  386. }
  387. if (numDefined > (sd->Size >> 2))
  388. return SZ_ERROR_ARCHIVE;
  389. SKIP_DATA(sd, (size_t)numDefined * 4);
  390. return SZ_OK;
  391. }
  392. static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc)
  393. {
  394. RINOK(SzReadNumber32(sd, &p->NumPackStreams));
  395. RINOK(WaitId(sd, k7zIdSize));
  396. MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc);
  397. {
  398. UInt64 sum = 0;
  399. UInt32 i;
  400. UInt32 numPackStreams = p->NumPackStreams;
  401. for (i = 0; i < numPackStreams; i++)
  402. {
  403. UInt64 packSize;
  404. p->PackPositions[i] = sum;
  405. RINOK(ReadNumber(sd, &packSize));
  406. sum += packSize;
  407. if (sum < packSize)
  408. return SZ_ERROR_ARCHIVE;
  409. }
  410. p->PackPositions[i] = sum;
  411. }
  412. for (;;)
  413. {
  414. UInt64 type;
  415. RINOK(ReadID(sd, &type));
  416. if (type == k7zIdEnd)
  417. return SZ_OK;
  418. if (type == k7zIdCRC)
  419. {
  420. /* CRC of packed streams is unused now */
  421. RINOK(SkipBitUi32s(sd, p->NumPackStreams));
  422. continue;
  423. }
  424. RINOK(SkipData(sd));
  425. }
  426. }
  427. /*
  428. static SRes SzReadSwitch(CSzData *sd)
  429. {
  430. Byte external;
  431. RINOK(SzReadByte(sd, &external));
  432. return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
  433. }
  434. */
  435. #define SZ_NUM_IN_STREAMS_IN_FOLDER_MAX 16
  436. SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes)
  437. {
  438. UInt32 numCoders, numBindPairs, numPackStreams, i;
  439. UInt32 numInStreams = 0, numOutStreams = 0;
  440. const Byte *dataStart = sd->Data;
  441. Byte inStreamUsed[SZ_NUM_IN_STREAMS_IN_FOLDER_MAX];
  442. RINOK(SzReadNumber32(sd, &numCoders));
  443. if (numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX)
  444. return SZ_ERROR_UNSUPPORTED;
  445. f->NumCoders = numCoders;
  446. for (i = 0; i < numCoders; i++)
  447. {
  448. Byte mainByte;
  449. CSzCoderInfo *coder = f->Coders + i;
  450. unsigned idSize, j;
  451. UInt64 id;
  452. RINOK(SzReadByte(sd, &mainByte));
  453. if ((mainByte & 0xC0) != 0)
  454. return SZ_ERROR_UNSUPPORTED;
  455. idSize = (unsigned)(mainByte & 0xF);
  456. if (idSize > sizeof(id))
  457. return SZ_ERROR_UNSUPPORTED;
  458. if (idSize > sd->Size)
  459. return SZ_ERROR_ARCHIVE;
  460. id = 0;
  461. for (j = 0; j < idSize; j++)
  462. {
  463. id = ((id << 8) | *sd->Data);
  464. sd->Data++;
  465. sd->Size--;
  466. }
  467. if (id > (UInt32)0xFFFFFFFF)
  468. return SZ_ERROR_UNSUPPORTED;
  469. coder->MethodID = (UInt32)id;
  470. coder->NumInStreams = 1;
  471. coder->NumOutStreams = 1;
  472. coder->PropsOffset = 0;
  473. coder->PropsSize = 0;
  474. if ((mainByte & 0x10) != 0)
  475. {
  476. UInt32 numStreams;
  477. RINOK(SzReadNumber32(sd, &numStreams));
  478. if (numStreams > NUM_CODER_STREAMS_MAX)
  479. return SZ_ERROR_UNSUPPORTED;
  480. coder->NumInStreams = (Byte)numStreams;
  481. RINOK(SzReadNumber32(sd, &numStreams));
  482. if (numStreams > NUM_CODER_STREAMS_MAX)
  483. return SZ_ERROR_UNSUPPORTED;
  484. coder->NumOutStreams = (Byte)numStreams;
  485. }
  486. if ((mainByte & 0x20) != 0)
  487. {
  488. UInt32 propsSize = 0;
  489. RINOK(SzReadNumber32(sd, &propsSize));
  490. if (propsSize >= 0x40)
  491. return SZ_ERROR_UNSUPPORTED;
  492. if (propsSize > sd->Size)
  493. return SZ_ERROR_ARCHIVE;
  494. coder->PropsOffset = sd->Data - dataStart;
  495. coder->PropsSize = (Byte)propsSize;
  496. sd->Data += (size_t)propsSize;
  497. sd->Size -= (size_t)propsSize;
  498. }
  499. numInStreams += coder->NumInStreams;
  500. numOutStreams += coder->NumOutStreams;
  501. }
  502. if (numOutStreams == 0)
  503. return SZ_ERROR_UNSUPPORTED;
  504. f->NumBindPairs = numBindPairs = numOutStreams - 1;
  505. if (numInStreams < numBindPairs)
  506. return SZ_ERROR_ARCHIVE;
  507. if (numInStreams > SZ_NUM_IN_STREAMS_IN_FOLDER_MAX)
  508. return SZ_ERROR_UNSUPPORTED;
  509. f->MainOutStream = 0;
  510. f->NumPackStreams = numPackStreams = numInStreams - numBindPairs;
  511. if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
  512. return SZ_ERROR_UNSUPPORTED;
  513. for (i = 0; i < numInStreams; i++)
  514. inStreamUsed[i] = False;
  515. if (numBindPairs != 0)
  516. {
  517. Byte outStreamUsed[SZ_NUM_CODERS_OUT_STREAMS_IN_FOLDER_MAX];
  518. if (numBindPairs > SZ_NUM_BINDS_IN_FOLDER_MAX)
  519. return SZ_ERROR_UNSUPPORTED;
  520. for (i = 0; i < numOutStreams; i++)
  521. outStreamUsed[i] = False;
  522. for (i = 0; i < numBindPairs; i++)
  523. {
  524. CSzBindPair *bp = f->BindPairs + i;
  525. RINOK(SzReadNumber32(sd, &bp->InIndex));
  526. if (bp->InIndex >= numInStreams)
  527. return SZ_ERROR_ARCHIVE;
  528. inStreamUsed[bp->InIndex] = True;
  529. RINOK(SzReadNumber32(sd, &bp->OutIndex));
  530. if (bp->OutIndex >= numInStreams)
  531. return SZ_ERROR_ARCHIVE;
  532. outStreamUsed[bp->OutIndex] = True;
  533. }
  534. for (i = 0; i < numOutStreams; i++)
  535. if (!outStreamUsed[i])
  536. {
  537. f->MainOutStream = i;
  538. break;
  539. }
  540. if (i == numOutStreams)
  541. return SZ_ERROR_ARCHIVE;
  542. }
  543. if (numPackStreams == 1)
  544. {
  545. for (i = 0; i < numInStreams; i++)
  546. if (!inStreamUsed[i])
  547. break;
  548. if (i == numInStreams)
  549. return SZ_ERROR_ARCHIVE;
  550. f->PackStreams[0] = i;
  551. }
  552. else
  553. for (i = 0; i < numPackStreams; i++)
  554. {
  555. RINOK(SzReadNumber32(sd, f->PackStreams + i));
  556. }
  557. for (i = 0; i < numOutStreams; i++)
  558. {
  559. RINOK(ReadNumber(sdSizes, f->CodersUnpackSizes + i));
  560. }
  561. return SZ_OK;
  562. }
  563. static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
  564. {
  565. CSzData sd;
  566. sd = *sd2;
  567. for (; num != 0; num--)
  568. {
  569. Byte firstByte, mask;
  570. unsigned i;
  571. SZ_READ_BYTE_2(firstByte);
  572. if ((firstByte & 0x80) == 0)
  573. continue;
  574. if ((firstByte & 0x40) == 0)
  575. {
  576. if (sd.Size == 0)
  577. return SZ_ERROR_ARCHIVE;
  578. sd.Size--;
  579. sd.Data++;
  580. continue;
  581. }
  582. mask = 0x20;
  583. for (i = 2; i < 8 && (firstByte & mask) != 0; i++)
  584. mask >>= 1;
  585. if (i > sd.Size)
  586. return SZ_ERROR_ARCHIVE;
  587. SKIP_DATA2(sd, i);
  588. }
  589. *sd2 = sd;
  590. return SZ_OK;
  591. }
  592. #define k_InStreamUsed_MAX 64
  593. #define k_OutStreamUsed_MAX 64
  594. static SRes ReadUnpackInfo(CSzAr *p,
  595. CSzData *sd2,
  596. UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
  597. ISzAlloc *alloc)
  598. {
  599. CSzData sd;
  600. Byte inStreamUsed[k_InStreamUsed_MAX];
  601. Byte outStreamUsed[k_OutStreamUsed_MAX];
  602. UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex;
  603. const Byte *startBufPtr;
  604. Byte external;
  605. RINOK(WaitId(sd2, k7zIdFolder));
  606. RINOK(SzReadNumber32(sd2, &numFolders));
  607. if (p->NumFolders > numFoldersMax)
  608. return SZ_ERROR_UNSUPPORTED;
  609. p->NumFolders = numFolders;
  610. SZ_READ_BYTE_SD(sd2, external);
  611. if (external == 0)
  612. sd = *sd2;
  613. else
  614. {
  615. UInt32 index;
  616. SzReadNumber32(sd2, &index);
  617. if (index >= numTempBufs)
  618. return SZ_ERROR_ARCHIVE;
  619. sd.Data = tempBufs[index].data;
  620. sd.Size = tempBufs[index].size;
  621. }
  622. MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc);
  623. MY_ALLOC(size_t, p->FoSizesOffsets, (size_t)numFolders + 1, alloc);
  624. MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc);
  625. startBufPtr = sd.Data;
  626. packStreamIndex = 0;
  627. numCodersOutStreams = 0;
  628. for (fo = 0; fo < numFolders; fo++)
  629. {
  630. UInt32 numCoders, ci, numInStreams = 0, numOutStreams = 0;
  631. p->FoCodersOffsets[fo] = sd.Data - startBufPtr;
  632. RINOK(SzReadNumber32(&sd, &numCoders));
  633. if (numCoders > NUM_FOLDER_CODERS_MAX)
  634. return SZ_ERROR_UNSUPPORTED;
  635. for (ci = 0; ci < numCoders; ci++)
  636. {
  637. Byte mainByte;
  638. unsigned idSize;
  639. UInt32 coderInStreams, coderOutStreams;
  640. SZ_READ_BYTE_2(mainByte);
  641. if ((mainByte & 0xC0) != 0)
  642. return SZ_ERROR_UNSUPPORTED;
  643. idSize = (mainByte & 0xF);
  644. if (idSize > 8)
  645. return SZ_ERROR_UNSUPPORTED;
  646. if (idSize > sd.Size)
  647. return SZ_ERROR_ARCHIVE;
  648. SKIP_DATA2(sd, idSize);
  649. coderInStreams = 1;
  650. coderOutStreams = 1;
  651. if ((mainByte & 0x10) != 0)
  652. {
  653. RINOK(SzReadNumber32(&sd, &coderInStreams));
  654. RINOK(SzReadNumber32(&sd, &coderOutStreams));
  655. if (coderInStreams > NUM_CODER_STREAMS_MAX ||
  656. coderOutStreams > NUM_CODER_STREAMS_MAX)
  657. return SZ_ERROR_UNSUPPORTED;
  658. }
  659. numInStreams += coderInStreams;
  660. numOutStreams += coderOutStreams;
  661. if ((mainByte & 0x20) != 0)
  662. {
  663. UInt32 propsSize;
  664. RINOK(SzReadNumber32(&sd, &propsSize));
  665. if (propsSize > sd.Size)
  666. return SZ_ERROR_ARCHIVE;
  667. SKIP_DATA2(sd, propsSize);
  668. }
  669. }
  670. {
  671. UInt32 indexOfMainStream = 0;
  672. UInt32 numPackStreams = 1;
  673. if (numOutStreams != 1 || numInStreams != 1)
  674. {
  675. UInt32 i;
  676. UInt32 numBindPairs = numOutStreams - 1;
  677. if (numOutStreams == 0 || numInStreams < numBindPairs)
  678. return SZ_ERROR_ARCHIVE;
  679. if (numInStreams > k_InStreamUsed_MAX ||
  680. numOutStreams > k_OutStreamUsed_MAX)
  681. return SZ_ERROR_UNSUPPORTED;
  682. for (i = 0; i < numInStreams; i++)
  683. inStreamUsed[i] = False;
  684. for (i = 0; i < numOutStreams; i++)
  685. outStreamUsed[i] = False;
  686. for (i = 0; i < numBindPairs; i++)
  687. {
  688. UInt32 index;
  689. RINOK(SzReadNumber32(&sd, &index));
  690. if (index >= numInStreams || inStreamUsed[index])
  691. return SZ_ERROR_ARCHIVE;
  692. inStreamUsed[index] = True;
  693. RINOK(SzReadNumber32(&sd, &index));
  694. if (index >= numInStreams || outStreamUsed[index])
  695. return SZ_ERROR_ARCHIVE;
  696. outStreamUsed[index] = True;
  697. }
  698. numPackStreams = numInStreams - numBindPairs;
  699. if (numPackStreams != 1)
  700. for (i = 0; i < numPackStreams; i++)
  701. {
  702. UInt32 temp;
  703. RINOK(SzReadNumber32(&sd, &temp));
  704. if (temp >= numInStreams)
  705. return SZ_ERROR_ARCHIVE;
  706. }
  707. for (i = 0; i < numOutStreams; i++)
  708. if (!outStreamUsed[i])
  709. {
  710. indexOfMainStream = i;
  711. break;
  712. }
  713. if (i == numOutStreams)
  714. return SZ_ERROR_ARCHIVE;
  715. }
  716. p->FoStartPackStreamIndex[fo] = packStreamIndex;
  717. p->FoSizesOffsets[fo] = (numOutStreams << 8) | indexOfMainStream;
  718. numCodersOutStreams += numOutStreams;
  719. if (numCodersOutStreams < numOutStreams)
  720. return SZ_ERROR_UNSUPPORTED;
  721. packStreamIndex += numPackStreams;
  722. if (packStreamIndex < numPackStreams)
  723. return SZ_ERROR_UNSUPPORTED;
  724. if (packStreamIndex > p->NumPackStreams)
  725. return SZ_ERROR_ARCHIVE;
  726. }
  727. }
  728. {
  729. size_t dataSize = sd.Data - startBufPtr;
  730. p->FoStartPackStreamIndex[fo] = packStreamIndex;
  731. p->FoCodersOffsets[fo] = dataSize;
  732. MY_ALLOC(Byte, p->CodersData, dataSize, alloc);
  733. memcpy(p->CodersData, startBufPtr, dataSize);
  734. }
  735. if (external != 0)
  736. {
  737. if (sd.Size != 0)
  738. return SZ_ERROR_ARCHIVE;
  739. sd = *sd2;
  740. }
  741. RINOK(WaitId(&sd, k7zIdCodersUnpackSize));
  742. // MY_ALLOC(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
  743. {
  744. size_t dataSize = sd.Size;
  745. /*
  746. UInt32 i;
  747. for (i = 0; i < numCodersOutStreams; i++)
  748. {
  749. RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i));
  750. }
  751. */
  752. RINOK(SkipNumbers(&sd, numCodersOutStreams));
  753. dataSize -= sd.Size;
  754. MY_ALLOC(Byte, p->UnpackSizesData, dataSize, alloc);
  755. memcpy(p->UnpackSizesData, sd.Data - dataSize, dataSize);
  756. p->UnpackSizesDataSize = dataSize;
  757. /*
  758. const Byte *data = SzReadNumbers(sd.Data, sd.Data + sd.Size, p->CoderUnpackSizes, numCodersOutStreams);
  759. if (data == NULL)
  760. return SZ_ERROR_ARCHIVE;
  761. sd.Size = sd.Data + sd.Size - data;
  762. sd.Data = data;
  763. */
  764. }
  765. for (;;)
  766. {
  767. UInt64 type;
  768. RINOK(ReadID(&sd, &type));
  769. if (type == k7zIdEnd)
  770. {
  771. *sd2 = sd;
  772. return SZ_OK;
  773. }
  774. if (type == k7zIdCRC)
  775. {
  776. RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc));
  777. continue;
  778. }
  779. RINOK(SkipData(&sd));
  780. }
  781. }
  782. typedef struct
  783. {
  784. UInt32 NumTotalSubStreams;
  785. UInt32 NumSubDigests;
  786. CSzData sdNumSubStreams;
  787. CSzData sdSizes;
  788. CSzData sdCRCs;
  789. } CSubStreamInfo;
  790. #define SzUi32IndexMax (((UInt32)1 << 31) - 2)
  791. static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
  792. {
  793. UInt64 type = 0;
  794. UInt32 i;
  795. UInt32 numSubDigests = 0;
  796. UInt32 numFolders = p->NumFolders;
  797. UInt32 numUnpackStreams = numFolders;
  798. UInt32 numUnpackSizesInData = 0;
  799. for (;;)
  800. {
  801. RINOK(ReadID(sd, &type));
  802. if (type == k7zIdNumUnpackStream)
  803. {
  804. ssi->sdNumSubStreams.Data = sd->Data;
  805. numUnpackStreams = 0;
  806. numSubDigests = 0;
  807. for (i = 0; i < numFolders; i++)
  808. {
  809. UInt32 numStreams;
  810. RINOK(SzReadNumber32(sd, &numStreams));
  811. if (numUnpackStreams > numUnpackStreams + numStreams)
  812. return SZ_ERROR_UNSUPPORTED;
  813. numUnpackStreams += numStreams;
  814. if (numStreams != 0)
  815. numUnpackSizesInData += (numStreams - 1);
  816. if (numStreams != 1 || !SzBitWithVals_Check(&p->FolderCRCs, i))
  817. numSubDigests += numStreams;
  818. }
  819. ssi->sdNumSubStreams.Size = sd->Data - ssi->sdNumSubStreams.Data;
  820. continue;
  821. }
  822. if (type == k7zIdCRC || type == k7zIdSize || type == k7zIdEnd)
  823. break;
  824. RINOK(SkipData(sd));
  825. }
  826. if (!ssi->sdNumSubStreams.Data)
  827. {
  828. numSubDigests = numFolders;
  829. if (p->FolderCRCs.Defs)
  830. numSubDigests = numFolders - CountDefinedBits(p->FolderCRCs.Defs, numFolders);
  831. }
  832. ssi->NumTotalSubStreams = numUnpackStreams;
  833. ssi->NumSubDigests = numSubDigests;
  834. if (type == k7zIdSize)
  835. {
  836. ssi->sdSizes.Data = sd->Data;
  837. RINOK(SkipNumbers(sd, numUnpackSizesInData));
  838. ssi->sdSizes.Size = sd->Data - ssi->sdSizes.Data;
  839. RINOK(ReadID(sd, &type));
  840. }
  841. for (;;)
  842. {
  843. if (type == k7zIdEnd)
  844. return SZ_OK;
  845. if (type == k7zIdCRC)
  846. {
  847. ssi->sdCRCs.Data = sd->Data;
  848. RINOK(SkipBitUi32s(sd, numSubDigests));
  849. ssi->sdCRCs.Size = sd->Data - ssi->sdCRCs.Data;
  850. }
  851. else
  852. {
  853. RINOK(SkipData(sd));
  854. }
  855. RINOK(ReadID(sd, &type));
  856. }
  857. }
  858. static SRes SzReadStreamsInfo(CSzAr *p,
  859. CSzData *sd,
  860. UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
  861. UInt64 *dataOffset,
  862. CSubStreamInfo *ssi,
  863. ISzAlloc *alloc)
  864. {
  865. UInt64 type;
  866. SzData_Clear(&ssi->sdSizes);
  867. SzData_Clear(&ssi->sdCRCs);
  868. SzData_Clear(&ssi->sdNumSubStreams);
  869. *dataOffset = 0;
  870. RINOK(ReadID(sd, &type));
  871. if (type == k7zIdPackInfo)
  872. {
  873. RINOK(ReadNumber(sd, dataOffset));
  874. RINOK(ReadPackInfo(p, sd, alloc));
  875. RINOK(ReadID(sd, &type));
  876. }
  877. if (type == k7zIdUnpackInfo)
  878. {
  879. RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc));
  880. RINOK(ReadID(sd, &type));
  881. }
  882. if (type == k7zIdSubStreamsInfo)
  883. {
  884. RINOK(ReadSubStreamsInfo(p, sd, ssi));
  885. RINOK(ReadID(sd, &type));
  886. }
  887. else
  888. {
  889. ssi->NumTotalSubStreams = p->NumFolders;
  890. // ssi->NumSubDigests = 0;
  891. }
  892. return (type == k7zIdEnd ? SZ_OK : SZ_ERROR_UNSUPPORTED);
  893. }
  894. static SRes SzReadAndDecodePackedStreams(
  895. ILookInStream *inStream,
  896. CSzData *sd,
  897. CBuf *tempBufs,
  898. UInt32 numFoldersMax,
  899. UInt64 baseOffset,
  900. CSzAr *p,
  901. ISzAlloc *allocTemp)
  902. {
  903. UInt64 dataStartPos;
  904. UInt32 fo;
  905. CSubStreamInfo ssi;
  906. CSzData sdCodersUnpSizes;
  907. RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp));
  908. dataStartPos += baseOffset;
  909. if (p->NumFolders == 0)
  910. return SZ_ERROR_ARCHIVE;
  911. sdCodersUnpSizes.Data = p->UnpackSizesData;
  912. sdCodersUnpSizes.Size = p->UnpackSizesDataSize;
  913. for (fo = 0; fo < p->NumFolders; fo++)
  914. Buf_Init(tempBufs + fo);
  915. for (fo = 0; fo < p->NumFolders; fo++)
  916. {
  917. CBuf *tempBuf = tempBufs + fo;
  918. // folder = p->Folders;
  919. // unpackSize = SzAr_GetFolderUnpackSize(p, 0);
  920. UInt32 mix = (UInt32)p->FoSizesOffsets[fo];
  921. UInt32 mainIndex = mix & 0xFF;
  922. UInt32 numOutStreams = mix >> 8;
  923. UInt32 si;
  924. UInt64 unpackSize = 0;
  925. p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
  926. for (si = 0; si < numOutStreams; si++)
  927. {
  928. UInt64 curSize;
  929. RINOK(ReadNumber(&sdCodersUnpSizes, &curSize));
  930. if (si == mainIndex)
  931. {
  932. unpackSize = curSize;
  933. break;
  934. }
  935. }
  936. if (si == numOutStreams)
  937. return SZ_ERROR_FAIL;
  938. if ((size_t)unpackSize != unpackSize)
  939. return SZ_ERROR_MEM;
  940. if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))
  941. return SZ_ERROR_MEM;
  942. }
  943. p->FoSizesOffsets[fo] = sdCodersUnpSizes.Data - p->UnpackSizesData;
  944. for (fo = 0; fo < p->NumFolders; fo++)
  945. {
  946. const CBuf *tempBuf = tempBufs + fo;
  947. RINOK(LookInStream_SeekTo(inStream, dataStartPos));
  948. RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp));
  949. if (SzBitWithVals_Check(&p->FolderCRCs, fo))
  950. if (CrcCalc(tempBuf->data, tempBuf->size) != p->FolderCRCs.Vals[fo])
  951. return SZ_ERROR_CRC;
  952. }
  953. return SZ_OK;
  954. }
  955. static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets)
  956. {
  957. size_t pos = 0;
  958. *offsets++ = 0;
  959. if (numFiles == 0)
  960. return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE;
  961. if (data[size - 2] != 0 || data[size - 1] != 0)
  962. return SZ_ERROR_ARCHIVE;
  963. do
  964. {
  965. const Byte *p;
  966. if (pos == size)
  967. return SZ_ERROR_ARCHIVE;
  968. for (p = data + pos;
  969. #ifdef _WIN32
  970. *(const UInt16 *)p != 0
  971. #else
  972. p[0] != 0 || p[1] != 0
  973. #endif
  974. ; p += 2);
  975. pos = p - data + 2;
  976. *offsets++ = (pos >> 1);
  977. }
  978. while (--numFiles);
  979. return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
  980. }
  981. static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
  982. CSzData *sd2,
  983. const CBuf *tempBufs, UInt32 numTempBufs,
  984. ISzAlloc *alloc)
  985. {
  986. CSzData sd;
  987. UInt32 i;
  988. CNtfsFileTime *vals;
  989. Byte *defs;
  990. Byte external;
  991. RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));
  992. RINOK(SzReadByte(sd2, &external));
  993. if (external == 0)
  994. sd = *sd2;
  995. else
  996. {
  997. UInt32 index;
  998. SzReadNumber32(sd2, &index);
  999. if (index >= numTempBufs)
  1000. return SZ_ERROR_ARCHIVE;
  1001. sd.Data = tempBufs[index].data;
  1002. sd.Size = tempBufs[index].size;
  1003. }
  1004. MY_ALLOC(CNtfsFileTime, p->Vals, num, alloc);
  1005. vals = p->Vals;
  1006. defs = p->Defs;
  1007. for (i = 0; i < num; i++)
  1008. if (SzBitArray_Check(defs, i))
  1009. {
  1010. if (sd.Size < 8)
  1011. return SZ_ERROR_ARCHIVE;
  1012. vals[i].Low = GetUi32(sd.Data);
  1013. vals[i].High = GetUi32(sd.Data + 4);
  1014. SKIP_DATA2(sd, 8);
  1015. }
  1016. else
  1017. vals[i].High = vals[i].Low = 0;
  1018. if (external == 0)
  1019. *sd2 = sd;
  1020. return SZ_OK;
  1021. }
  1022. #define NUM_ADDITIONAL_STREAMS_MAX 8
  1023. static SRes SzReadHeader2(
  1024. CSzArEx *p, /* allocMain */
  1025. CSzData *sd,
  1026. // Byte **emptyStreamVector, /* allocTemp */
  1027. // Byte **emptyFileVector, /* allocTemp */
  1028. // Byte **lwtVector, /* allocTemp */
  1029. ILookInStream *inStream,
  1030. CBuf *tempBufs,
  1031. UInt32 *numTempBufs,
  1032. ISzAlloc *allocMain,
  1033. ISzAlloc *allocTemp
  1034. )
  1035. {
  1036. UInt64 type;
  1037. UInt32 numFiles = 0;
  1038. UInt32 numEmptyStreams = 0;
  1039. UInt32 i;
  1040. CSubStreamInfo ssi;
  1041. const Byte *emptyStreams = 0;
  1042. const Byte *emptyFiles = 0;
  1043. SzData_Clear(&ssi.sdSizes);
  1044. SzData_Clear(&ssi.sdCRCs);
  1045. SzData_Clear(&ssi.sdNumSubStreams);
  1046. ssi.NumSubDigests = 0;
  1047. ssi.NumTotalSubStreams = 0;
  1048. RINOK(ReadID(sd, &type));
  1049. if (type == k7zIdArchiveProperties)
  1050. {
  1051. for (;;)
  1052. {
  1053. UInt64 type;
  1054. RINOK(ReadID(sd, &type));
  1055. if (type == k7zIdEnd)
  1056. break;
  1057. RINOK(SkipData(sd));
  1058. }
  1059. RINOK(ReadID(sd, &type));
  1060. }
  1061. // if (type == k7zIdAdditionalStreamsInfo) return SZ_ERROR_UNSUPPORTED;
  1062. if (type == k7zIdAdditionalStreamsInfo)
  1063. {
  1064. CSzAr tempAr;
  1065. SRes res;
  1066. UInt32 numTempFolders;
  1067. SzAr_Init(&tempAr);
  1068. res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX,
  1069. p->startPosAfterHeader, &tempAr, allocTemp);
  1070. numTempFolders = tempAr.NumFolders;
  1071. SzAr_Free(&tempAr, allocTemp);
  1072. if (res != SZ_OK)
  1073. return res;
  1074. *numTempBufs = numTempFolders;
  1075. RINOK(ReadID(sd, &type));
  1076. }
  1077. if (type == k7zIdMainStreamsInfo)
  1078. {
  1079. RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs,
  1080. &p->dataPos, &ssi, allocMain));
  1081. p->dataPos += p->startPosAfterHeader;
  1082. RINOK(ReadID(sd, &type));
  1083. }
  1084. if (type == k7zIdEnd)
  1085. {
  1086. // *sd2 = sd;
  1087. return SZ_OK;
  1088. }
  1089. if (type != k7zIdFilesInfo)
  1090. return SZ_ERROR_ARCHIVE;
  1091. RINOK(SzReadNumber32(sd, &numFiles));
  1092. p->NumFiles = numFiles;
  1093. for (;;)
  1094. {
  1095. UInt64 type;
  1096. UInt64 size;
  1097. RINOK(ReadID(sd, &type));
  1098. if (type == k7zIdEnd)
  1099. break;
  1100. RINOK(ReadNumber(sd, &size));
  1101. if (size > sd->Size)
  1102. return SZ_ERROR_ARCHIVE;
  1103. if ((UInt64)(int)type != type)
  1104. {
  1105. SKIP_DATA(sd, size);
  1106. }
  1107. else switch((int)type)
  1108. {
  1109. case k7zIdName:
  1110. {
  1111. size_t namesSize;
  1112. const Byte *namesData;
  1113. Byte external;
  1114. SZ_READ_BYTE(external);
  1115. if (external == 0)
  1116. {
  1117. namesSize = (size_t)size - 1;
  1118. namesData = sd->Data;
  1119. }
  1120. else
  1121. {
  1122. UInt32 index;
  1123. SzReadNumber32(sd, &index);
  1124. if (index >= *numTempBufs)
  1125. return SZ_ERROR_ARCHIVE;
  1126. namesData = (tempBufs)[index].data;
  1127. namesSize = (tempBufs)[index].size;
  1128. }
  1129. if ((namesSize & 1) != 0)
  1130. return SZ_ERROR_ARCHIVE;
  1131. MY_ALLOC(Byte, p->FileNames, namesSize, allocMain);
  1132. MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
  1133. memcpy(p->FileNames, namesData, namesSize);
  1134. RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets))
  1135. if (external == 0)
  1136. {
  1137. SKIP_DATA(sd, namesSize);
  1138. }
  1139. break;
  1140. }
  1141. case k7zIdEmptyStream:
  1142. {
  1143. RINOK(RememberBitVector(sd, numFiles, &emptyStreams));
  1144. numEmptyStreams = CountDefinedBits(emptyStreams, numFiles);
  1145. break;
  1146. }
  1147. case k7zIdEmptyFile:
  1148. {
  1149. RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles));
  1150. break;
  1151. }
  1152. case k7zIdWinAttrib:
  1153. {
  1154. Byte external;
  1155. CSzData sdSwitch;
  1156. CSzData *sdPtr;
  1157. SzBitUi32s_Free(&p->Attribs, allocMain);
  1158. RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain));
  1159. SZ_READ_BYTE(external);
  1160. if (external == 0)
  1161. sdPtr = sd;
  1162. else
  1163. {
  1164. UInt32 index;
  1165. SzReadNumber32(sd, &index);
  1166. if (index >= *numTempBufs)
  1167. return SZ_ERROR_ARCHIVE;
  1168. sdSwitch.Data = (tempBufs)[index].data;
  1169. sdSwitch.Size = (tempBufs)[index].size;
  1170. sdPtr = &sdSwitch;
  1171. }
  1172. RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain));
  1173. break;
  1174. }
  1175. /*
  1176. case k7zParent:
  1177. {
  1178. SzBitUi32s_Free(&p->Parents, allocMain);
  1179. RINOK(ReadBitVector(sd, numFiles, &p->Parents.Defs, allocMain));
  1180. RINOK(SzReadSwitch(sd));
  1181. RINOK(ReadUi32s(sd, numFiles, &p->Parents, allocMain));
  1182. break;
  1183. }
  1184. */
  1185. case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break;
  1186. case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break;
  1187. default:
  1188. {
  1189. SKIP_DATA(sd, size);
  1190. }
  1191. }
  1192. }
  1193. if (numFiles - numEmptyStreams != ssi.NumTotalSubStreams)
  1194. return SZ_ERROR_ARCHIVE;
  1195. for (;;)
  1196. {
  1197. UInt64 type;
  1198. RINOK(ReadID(sd, &type));
  1199. if (type == k7zIdEnd)
  1200. break;
  1201. RINOK(SkipData(sd));
  1202. }
  1203. {
  1204. UInt32 emptyFileIndex = 0;
  1205. UInt32 folderIndex = 0;
  1206. UInt32 indexInFolder = 0;
  1207. UInt64 unpackPos = 0;
  1208. const Byte *digestsDefs = 0;
  1209. const Byte *digestsVals = 0;
  1210. UInt32 digestsValsIndex = 0;
  1211. UInt32 digestIndex;
  1212. Byte allDigestsDefined = 0;
  1213. UInt32 curNumSubStreams = (UInt32)(Int32)-1;
  1214. Byte isDirMask = 0;
  1215. Byte crcMask = 0;
  1216. Byte mask = 0x80;
  1217. // size_t unpSizesOffset = 0;
  1218. CSzData sdCodersUnpSizes;
  1219. sdCodersUnpSizes.Data = p->db.UnpackSizesData;
  1220. sdCodersUnpSizes.Size = p->db.UnpackSizesDataSize;
  1221. MY_ALLOC(UInt32, p->FolderStartFileIndex, p->db.NumFolders + 1, allocMain);
  1222. MY_ALLOC(UInt32, p->FileIndexToFolderIndexMap, p->NumFiles, allocMain);
  1223. MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain);
  1224. MY_ALLOC(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);
  1225. RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain));
  1226. if (ssi.sdCRCs.Size != 0)
  1227. {
  1228. RINOK(SzReadByte(&ssi.sdCRCs, &allDigestsDefined));
  1229. if (allDigestsDefined)
  1230. digestsVals = ssi.sdCRCs.Data;
  1231. else
  1232. {
  1233. size_t numBytes = (ssi.NumSubDigests + 7) >> 3;
  1234. digestsDefs = ssi.sdCRCs.Data;
  1235. digestsVals = digestsDefs + numBytes;
  1236. }
  1237. }
  1238. digestIndex = 0;
  1239. for (i = 0; i < numFiles; i++, mask >>= 1)
  1240. {
  1241. if (mask == 0)
  1242. {
  1243. UInt32 byteIndex = (i - 1) >> 3;
  1244. p->IsDirs[byteIndex] = isDirMask;
  1245. p->CRCs.Defs[byteIndex] = crcMask;
  1246. isDirMask = 0;
  1247. crcMask = 0;
  1248. mask = 0x80;
  1249. }
  1250. p->UnpackPositions[i] = unpackPos;
  1251. p->CRCs.Vals[i] = 0;
  1252. // p->CRCs.Defs[i] = 0;
  1253. if (emptyStreams && SzBitArray_Check(emptyStreams , i))
  1254. {
  1255. if (!emptyFiles || !SzBitArray_Check(emptyFiles, emptyFileIndex))
  1256. isDirMask |= mask;
  1257. emptyFileIndex++;
  1258. if (indexInFolder == 0)
  1259. {
  1260. p->FileIndexToFolderIndexMap[i] = (UInt32)-1;
  1261. continue;
  1262. }
  1263. }
  1264. if (indexInFolder == 0)
  1265. {
  1266. /*
  1267. v3.13 incorrectly worked with empty folders
  1268. v4.07: Loop for skipping empty folders
  1269. */
  1270. for (;;)
  1271. {
  1272. if (folderIndex >= p->db.NumFolders)
  1273. return SZ_ERROR_ARCHIVE;
  1274. p->FolderStartFileIndex[folderIndex] = i;
  1275. if (curNumSubStreams == (UInt32)(Int32)-1);
  1276. {
  1277. curNumSubStreams = 1;
  1278. if (ssi.sdNumSubStreams.Data != 0)
  1279. {
  1280. RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &curNumSubStreams));
  1281. }
  1282. }
  1283. if (curNumSubStreams != 0)
  1284. break;
  1285. curNumSubStreams = (UInt32)(Int32)-1;
  1286. folderIndex++; // check it
  1287. }
  1288. }
  1289. p->FileIndexToFolderIndexMap[i] = folderIndex;
  1290. if (emptyStreams && SzBitArray_Check(emptyStreams , i))
  1291. continue;
  1292. indexInFolder++;
  1293. if (indexInFolder >= curNumSubStreams)
  1294. {
  1295. UInt64 folderUnpackSize = 0;
  1296. UInt64 startFolderUnpackPos;
  1297. {
  1298. UInt32 mix = (UInt32)p->db.FoSizesOffsets[folderIndex];
  1299. UInt32 mainIndex = mix & 0xFF;
  1300. UInt32 numOutStreams = mix >> 8;
  1301. UInt32 si;
  1302. p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData;
  1303. for (si = 0; si < numOutStreams; si++)
  1304. {
  1305. UInt64 curSize;
  1306. RINOK(ReadNumber(&sdCodersUnpSizes, &curSize));
  1307. if (si == mainIndex)
  1308. {
  1309. folderUnpackSize = curSize;
  1310. break;
  1311. }
  1312. }
  1313. if (si == numOutStreams)
  1314. return SZ_ERROR_FAIL;
  1315. }
  1316. // UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
  1317. startFolderUnpackPos = p->UnpackPositions[p->FolderStartFileIndex[folderIndex]];
  1318. if (folderUnpackSize < unpackPos - startFolderUnpackPos)
  1319. return SZ_ERROR_ARCHIVE;
  1320. unpackPos = startFolderUnpackPos + folderUnpackSize;
  1321. if (curNumSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i))
  1322. {
  1323. p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex];
  1324. crcMask |= mask;
  1325. }
  1326. else if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))
  1327. {
  1328. p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);
  1329. digestsValsIndex++;
  1330. crcMask |= mask;
  1331. }
  1332. folderIndex++;
  1333. indexInFolder = 0;
  1334. }
  1335. else
  1336. {
  1337. UInt64 v;
  1338. RINOK(ReadNumber(&ssi.sdSizes, &v));
  1339. unpackPos += v;
  1340. if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))
  1341. {
  1342. p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);
  1343. digestsValsIndex++;
  1344. crcMask |= mask;
  1345. }
  1346. }
  1347. }
  1348. if (mask != 0x80)
  1349. {
  1350. UInt32 byteIndex = (i - 1) >> 3;
  1351. p->IsDirs[byteIndex] = isDirMask;
  1352. p->CRCs.Defs[byteIndex] = crcMask;
  1353. }
  1354. p->UnpackPositions[i] = unpackPos;
  1355. p->FolderStartFileIndex[folderIndex] = i;
  1356. p->db.FoSizesOffsets[folderIndex] = sdCodersUnpSizes.Data - p->db.UnpackSizesData;
  1357. }
  1358. return SZ_OK;
  1359. }
  1360. static SRes SzReadHeader(
  1361. CSzArEx *p,
  1362. CSzData *sd,
  1363. ILookInStream *inStream,
  1364. ISzAlloc *allocMain
  1365. ,ISzAlloc *allocTemp
  1366. )
  1367. {
  1368. // Byte *emptyStreamVector = 0;
  1369. // Byte *emptyFileVector = 0;
  1370. // Byte *lwtVector = 0;
  1371. UInt32 i;
  1372. UInt32 numTempBufs = 0;
  1373. SRes res;
  1374. CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX];
  1375. for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
  1376. Buf_Init(tempBufs + i);
  1377. // SzBitUi32s_Init(&digests);
  1378. res = SzReadHeader2(p, sd,
  1379. // &emptyStreamVector,
  1380. // &emptyFileVector,
  1381. // &lwtVector,
  1382. inStream,
  1383. tempBufs, &numTempBufs,
  1384. allocMain, allocTemp
  1385. );
  1386. for (i = 0; i < numTempBufs; i++)
  1387. Buf_Free(tempBufs + i, allocTemp);
  1388. // IAlloc_Free(allocTemp, emptyStreamVector);
  1389. // IAlloc_Free(allocTemp, emptyFileVector);
  1390. // IAlloc_Free(allocTemp, lwtVector);
  1391. RINOK(res);
  1392. {
  1393. if (sd->Size != 0)
  1394. return SZ_ERROR_FAIL;
  1395. }
  1396. return res;
  1397. }
  1398. /*
  1399. static UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)
  1400. {
  1401. const CSzFolder2 *f = p->Folders + folderIndex;
  1402. // return p->CoderUnpackSizes[f->StartCoderUnpackSizesIndex + f->IndexOfMainOutStream];
  1403. UInt32 si;
  1404. CSzData sdCodersUnpSizes;
  1405. sdCodersUnpSizes.Data = p->UnpackSizesData + f->UnpackSizeDataOffset;
  1406. sdCodersUnpSizes.Size = p->UnpackSizesDataSize - f->UnpackSizeDataOffset;
  1407. for (si = 0; si < numOutStreams; si++)
  1408. {
  1409. UInt64 curSize;
  1410. ReadNumber(&sdCodersUnpSizes, &curSize);
  1411. if (si == mainIndex)
  1412. return curSize;
  1413. }
  1414. return 0;
  1415. }
  1416. */
  1417. static SRes SzArEx_Open2(
  1418. CSzArEx *p,
  1419. ILookInStream *inStream,
  1420. ISzAlloc *allocMain,
  1421. ISzAlloc *allocTemp)
  1422. {
  1423. Byte header[k7zStartHeaderSize];
  1424. Int64 startArcPos;
  1425. UInt64 nextHeaderOffset, nextHeaderSize;
  1426. size_t nextHeaderSizeT;
  1427. UInt32 nextHeaderCRC;
  1428. CBuf buf;
  1429. SRes res;
  1430. startArcPos = 0;
  1431. RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
  1432. RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
  1433. if (!TestSignatureCandidate(header))
  1434. return SZ_ERROR_NO_ARCHIVE;
  1435. if (header[6] != k7zMajorVersion)
  1436. return SZ_ERROR_UNSUPPORTED;
  1437. nextHeaderOffset = GetUi64(header + 12);
  1438. nextHeaderSize = GetUi64(header + 20);
  1439. nextHeaderCRC = GetUi32(header + 28);
  1440. p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
  1441. if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
  1442. return SZ_ERROR_CRC;
  1443. nextHeaderSizeT = (size_t)nextHeaderSize;
  1444. if (nextHeaderSizeT != nextHeaderSize)
  1445. return SZ_ERROR_MEM;
  1446. if (nextHeaderSizeT == 0)
  1447. return SZ_OK;
  1448. if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
  1449. nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
  1450. return SZ_ERROR_NO_ARCHIVE;
  1451. {
  1452. Int64 pos = 0;
  1453. RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
  1454. if ((UInt64)pos < startArcPos + nextHeaderOffset ||
  1455. (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
  1456. (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
  1457. return SZ_ERROR_INPUT_EOF;
  1458. }
  1459. RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
  1460. if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp))
  1461. return SZ_ERROR_MEM;
  1462. res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT);
  1463. if (res == SZ_OK)
  1464. {
  1465. res = SZ_ERROR_ARCHIVE;
  1466. if (CrcCalc(buf.data, nextHeaderSizeT) == nextHeaderCRC)
  1467. {
  1468. CSzData sd;
  1469. UInt64 type;
  1470. sd.Data = buf.data;
  1471. sd.Size = buf.size;
  1472. res = ReadID(&sd, &type);
  1473. if (res == SZ_OK && type == k7zIdEncodedHeader)
  1474. {
  1475. CSzAr tempAr;
  1476. CBuf tempBuf;
  1477. Buf_Init(&tempBuf);
  1478. SzAr_Init(&tempAr);
  1479. res = SzReadAndDecodePackedStreams(inStream, &sd, &tempBuf, 1, p->startPosAfterHeader, &tempAr, allocTemp);
  1480. SzAr_Free(&tempAr, allocTemp);
  1481. if (res != SZ_OK)
  1482. {
  1483. Buf_Free(&tempBuf, allocTemp);
  1484. }
  1485. else
  1486. {
  1487. Buf_Free(&buf, allocTemp);
  1488. buf.data = tempBuf.data;
  1489. buf.size = tempBuf.size;
  1490. sd.Data = buf.data;
  1491. sd.Size = buf.size;
  1492. res = ReadID(&sd, &type);
  1493. }
  1494. }
  1495. if (res == SZ_OK)
  1496. {
  1497. if (type == k7zIdHeader)
  1498. {
  1499. CSzData sd2;
  1500. int ttt;
  1501. for (ttt = 0; ttt < 1; ttt++)
  1502. // for (ttt = 0; ttt < 40000; ttt++)
  1503. {
  1504. SzArEx_Free(p, allocMain);
  1505. sd2 = sd;
  1506. res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp
  1507. );
  1508. if (res != SZ_OK)
  1509. break;
  1510. }
  1511. // res = SzReadHeader(p, &sd, allocMain, allocTemp);
  1512. }
  1513. else
  1514. res = SZ_ERROR_UNSUPPORTED;
  1515. }
  1516. }
  1517. }
  1518. Buf_Free(&buf, allocTemp);
  1519. return res;
  1520. }
  1521. // #include <stdio.h>
  1522. SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
  1523. ISzAlloc *allocMain, ISzAlloc *allocTemp)
  1524. {
  1525. SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
  1526. if (res != SZ_OK)
  1527. SzArEx_Free(p, allocMain);
  1528. // printf ("\nrrr=%d\n", rrr);
  1529. return res;
  1530. }
  1531. SRes SzArEx_Extract(
  1532. const CSzArEx *p,
  1533. ILookInStream *inStream,
  1534. UInt32 fileIndex,
  1535. UInt32 *blockIndex,
  1536. Byte **tempBuf,
  1537. size_t *outBufferSize,
  1538. size_t *offset,
  1539. size_t *outSizeProcessed,
  1540. ISzAlloc *allocMain,
  1541. ISzAlloc *allocTemp)
  1542. {
  1543. UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
  1544. SRes res = SZ_OK;
  1545. *offset = 0;
  1546. *outSizeProcessed = 0;
  1547. if (folderIndex == (UInt32)-1)
  1548. {
  1549. IAlloc_Free(allocMain, *tempBuf);
  1550. *blockIndex = folderIndex;
  1551. *tempBuf = 0;
  1552. *outBufferSize = 0;
  1553. return SZ_OK;
  1554. }
  1555. if (*tempBuf == 0 || *blockIndex != folderIndex)
  1556. {
  1557. // UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
  1558. UInt64 unpackSizeSpec =
  1559. p->UnpackPositions[p->FolderStartFileIndex[folderIndex + 1]] -
  1560. p->UnpackPositions[p->FolderStartFileIndex[folderIndex]];
  1561. size_t unpackSize = (size_t)unpackSizeSpec;
  1562. if (unpackSize != unpackSizeSpec)
  1563. return SZ_ERROR_MEM;
  1564. *blockIndex = folderIndex;
  1565. IAlloc_Free(allocMain, *tempBuf);
  1566. *tempBuf = 0;
  1567. // RINOK(LookInStream_SeekTo(inStream, startOffset));
  1568. if (res == SZ_OK)
  1569. {
  1570. *outBufferSize = unpackSize;
  1571. if (unpackSize != 0)
  1572. {
  1573. *tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
  1574. if (*tempBuf == 0)
  1575. res = SZ_ERROR_MEM;
  1576. }
  1577. if (res == SZ_OK)
  1578. {
  1579. res = SzAr_DecodeFolder(&p->db, folderIndex,
  1580. inStream,
  1581. p->dataPos,
  1582. *tempBuf, unpackSize, allocTemp);
  1583. if (res == SZ_OK)
  1584. {
  1585. if (SzBitWithVals_Check(&p->db.FolderCRCs, folderIndex))
  1586. {
  1587. if (CrcCalc(*tempBuf, unpackSize) != p->db.FolderCRCs.Vals[folderIndex])
  1588. res = SZ_ERROR_CRC;
  1589. }
  1590. }
  1591. }
  1592. }
  1593. }
  1594. if (res == SZ_OK)
  1595. {
  1596. UInt64 unpackPos = p->UnpackPositions[fileIndex];
  1597. *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderStartFileIndex[folderIndex]]);
  1598. *outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);
  1599. if (*offset + *outSizeProcessed > *outBufferSize)
  1600. return SZ_ERROR_FAIL;
  1601. if (SzBitWithVals_Check(&p->CRCs, fileIndex) && CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex])
  1602. res = SZ_ERROR_CRC;
  1603. }
  1604. return res;
  1605. }
  1606. size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
  1607. {
  1608. size_t offs = p->FileNameOffsets[fileIndex];
  1609. size_t len = p->FileNameOffsets[fileIndex + 1] - offs;
  1610. if (dest != 0)
  1611. {
  1612. size_t i;
  1613. const Byte *src = p->FileNames + offs * 2;
  1614. for (i = 0; i < len; i++)
  1615. dest[i] = GetUi16(src + i * 2);
  1616. }
  1617. return len;
  1618. }
  1619. /*
  1620. size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex)
  1621. {
  1622. size_t len;
  1623. if (!p->FileNameOffsets)
  1624. return 1;
  1625. len = 0;
  1626. for (;;)
  1627. {
  1628. UInt32 parent = (UInt32)(Int32)-1;
  1629. len += p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
  1630. if SzBitWithVals_Check(&p->Parents, fileIndex)
  1631. parent = p->Parents.Vals[fileIndex];
  1632. if (parent == (UInt32)(Int32)-1)
  1633. return len;
  1634. fileIndex = parent;
  1635. }
  1636. }
  1637. UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
  1638. {
  1639. Bool needSlash;
  1640. if (!p->FileNameOffsets)
  1641. {
  1642. *(--dest) = 0;
  1643. return dest;
  1644. }
  1645. needSlash = False;
  1646. for (;;)
  1647. {
  1648. UInt32 parent = (UInt32)(Int32)-1;
  1649. size_t curLen = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
  1650. SzArEx_GetFileNameUtf16(p, fileIndex, dest - curLen);
  1651. if (needSlash)
  1652. *(dest - 1) = '/';
  1653. needSlash = True;
  1654. dest -= curLen;
  1655. if SzBitWithVals_Check(&p->Parents, fileIndex)
  1656. parent = p->Parents.Vals[fileIndex];
  1657. if (parent == (UInt32)(Int32)-1)
  1658. return dest;
  1659. fileIndex = parent;
  1660. }
  1661. }
  1662. */