finddata.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * finddata.c
  3. * Copyright (C) 2000-2002 A.J. van Os; Released under GPL
  4. *
  5. * Description:
  6. * Find the blocks that contain the data of MS Word files
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include "antiword.h"
  11. /*
  12. * bAddDataBlocks - Add the blocks to the data block list
  13. *
  14. * Returns TRUE when successful, otherwise FALSE
  15. */
  16. BOOL
  17. bAddDataBlocks(ULONG ulDataPosFirst, ULONG ulTotalLength,
  18. ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen)
  19. {
  20. data_block_type tDataBlock;
  21. ULONG ulDataPos, ulOffset, ulIndex;
  22. long lToGo;
  23. BOOL bSuccess;
  24. fail(ulTotalLength > (ULONG)LONG_MAX);
  25. fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
  26. fail(aulBBD == NULL);
  27. NO_DBG_HEX(ulDataPosFirst);
  28. NO_DBG_DEC(ulTotalLength);
  29. lToGo = (long)ulTotalLength;
  30. ulDataPos = ulDataPosFirst;
  31. ulOffset = ulDataPosFirst;
  32. for (ulIndex = ulStartBlock;
  33. ulIndex != END_OF_CHAIN && lToGo > 0;
  34. ulIndex = aulBBD[ulIndex]) {
  35. if (ulIndex == UNUSED_BLOCK || ulIndex >= (ULONG)tBBDLen) {
  36. DBG_DEC(ulIndex);
  37. DBG_DEC(tBBDLen);
  38. return FALSE;
  39. }
  40. if (ulOffset >= BIG_BLOCK_SIZE) {
  41. ulOffset -= BIG_BLOCK_SIZE;
  42. continue;
  43. }
  44. tDataBlock.ulFileOffset =
  45. (ulIndex + 1) * BIG_BLOCK_SIZE + ulOffset;
  46. tDataBlock.ulDataPos = ulDataPos;
  47. tDataBlock.ulLength = min(BIG_BLOCK_SIZE - ulOffset,
  48. (ULONG)lToGo);
  49. fail(tDataBlock.ulLength > BIG_BLOCK_SIZE);
  50. ulOffset = 0;
  51. if (!bAdd2DataBlockList(&tDataBlock)) {
  52. DBG_HEX(tDataBlock.ulFileOffset);
  53. DBG_HEX(tDataBlock.ulDataPos);
  54. DBG_DEC(tDataBlock.ulLength);
  55. return FALSE;
  56. }
  57. ulDataPos += tDataBlock.ulLength;
  58. lToGo -= (long)tDataBlock.ulLength;
  59. }
  60. bSuccess = lToGo == 0 ||
  61. (ulTotalLength == (ULONG)LONG_MAX && ulIndex == END_OF_CHAIN);
  62. DBG_DEC_C(!bSuccess, lToGo);
  63. DBG_DEC_C(!bSuccess, ulTotalLength);
  64. DBG_DEC_C(!bSuccess, ulIndex);
  65. return bSuccess;
  66. } /* end of bAddDataBlocks */
  67. /*
  68. * bGet6DocumentData - make a list of the data blocks of Word 6/7 files
  69. *
  70. * Code for "fast saved" files.
  71. *
  72. * Returns TRUE when successful, otherwise FALSE
  73. */
  74. BOOL
  75. bGet6DocumentData(FILE *pFile, ULONG ulStartBlock,
  76. const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
  77. {
  78. UCHAR *aucBuffer;
  79. ULONG ulBeginTextInfo, ulOffset, ulTotLength;
  80. size_t tTextInfoLen;
  81. int iIndex, iOff, iType, iLen, iPieces;
  82. DBG_MSG("bGet6DocumentData");
  83. fail(pFile == NULL);
  84. fail(aulBBD == NULL);
  85. fail(aucHeader == NULL);
  86. ulBeginTextInfo = ulGetLong(0x160, aucHeader);
  87. DBG_HEX(ulBeginTextInfo);
  88. tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader);
  89. DBG_DEC(tTextInfoLen);
  90. aucBuffer = xmalloc(tTextInfoLen);
  91. if (!bReadBuffer(pFile, ulStartBlock,
  92. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  93. aucBuffer, ulBeginTextInfo, tTextInfoLen)) {
  94. aucBuffer = xfree(aucBuffer);
  95. return FALSE;
  96. }
  97. NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen);
  98. iOff = 0;
  99. while (iOff < (int)tTextInfoLen) {
  100. iType = (int)ucGetByte(iOff, aucBuffer);
  101. iOff++;
  102. if (iType == 0) {
  103. iOff++;
  104. continue;
  105. }
  106. iLen = (int)usGetWord(iOff, aucBuffer);
  107. iOff += 2;
  108. if (iType == 1) {
  109. iOff += iLen;
  110. continue;
  111. }
  112. if (iType != 2) {
  113. werr(0, "Unknown type of 'fastsaved' format");
  114. aucBuffer = xfree(aucBuffer);
  115. return FALSE;
  116. }
  117. /* Type 2 */
  118. NO_DBG_DEC(iLen);
  119. iOff += 2;
  120. iPieces = (iLen - 4) / 12;
  121. DBG_DEC(iPieces);
  122. for (iIndex = 0; iIndex < iPieces; iIndex++) {
  123. ulOffset = ulGetLong(
  124. iOff + (iPieces + 1) * 4 + iIndex * 8 + 2,
  125. aucBuffer);
  126. ulTotLength = ulGetLong(iOff + (iIndex + 1) * 4,
  127. aucBuffer) -
  128. ulGetLong(iOff + iIndex * 4,
  129. aucBuffer);
  130. if (!bAddDataBlocks(ulOffset, ulTotLength,
  131. ulStartBlock,
  132. aulBBD, tBBDLen)) {
  133. aucBuffer = xfree(aucBuffer);
  134. return FALSE;
  135. }
  136. }
  137. break;
  138. }
  139. aucBuffer = xfree(aucBuffer);
  140. return TRUE;
  141. } /* end of bGet6DocumentData */