Example #1
0
/*
 * Extract and verify the header of a resource fork.
 */
/*static*/ bool
ReformatResourceFork::ReadHeader(const uint8_t* srcBuf, long srcLen,
    long* pFileVersion, long* pFileToMap, long* pFileMapSize,
    bool* pLittleEndian)
{
    if (srcLen < 128) {
        LOGI("ReformatResource: invalid len %d", srcLen);
        return false;
    }

    *pFileVersion = Get32LE(srcBuf);
    if (*pFileVersion == 0)
        *pLittleEndian = true;
    else
        *pLittleEndian = false;

    *pFileVersion = Get32(srcBuf, *pLittleEndian);
    *pFileToMap = Get32(srcBuf+4, *pLittleEndian);
    *pFileMapSize = Get32(srcBuf+8, *pLittleEndian);

    if (*pFileVersion != 0)
        return false;
    if (*pFileMapSize <= 0 || *pFileMapSize >= srcLen ||
        *pFileToMap <= 0 || *pFileToMap >= srcLen)
    {
        return false;
    }

    return true;
}
Example #2
0
/*
 * Print the contents of the text blocks.
 *
 * We're assured that the text block format is correct because we had to
 * skip through them earlier.  We don't really need to worry about running
 * off the end due to a bad file.
 */
const uint8_t* ReformatAWGS_WP::FindTextBlock(const Chunk* pChunk, int blockNum)
{
    const uint8_t* blockPtr = pChunk->textBlocks;
    uint32_t blockSize;

    while (blockNum--) {
        blockSize = Get32LE(blockPtr);
        blockPtr += 4 + blockSize;
    }

    return blockPtr;
}
Example #3
0
/*
 * Skip past a series of text blocks.
 *
 * Returns "true" on success, "false" on failure.
 */
bool ReformatAWGS_WP::SkipTextBlocks(const uint8_t** pSrcBuf,
    long* pSrcLen, int textBlockCount)
{
    uint32_t blockSize;
    const uint8_t* srcBuf = *pSrcBuf;
    long srcLen = *pSrcLen;

    LOGI("Scanning %d text blocks", textBlockCount);

    if (srcLen < 4)
        return false;

    while (textBlockCount--) {
        blockSize = Get32LE(srcBuf);
        srcBuf += 4;
        srcLen -= 4;

        LOGI("+++  blockSize=%lu srcLen=%ld", blockSize, srcLen);
        if ((long) blockSize < kMinTextBlockSize) {
            LOGI("Block size too small (%d - %d)",
                blockSize, Get16LE(srcBuf));
            return false;
        }
        if ((long) blockSize > srcLen) {
            LOGI("Ran off the end in doc text blocks");
            return false;
        }
        if (Get16LE(srcBuf) != blockSize || Get16LE(srcBuf+2) != blockSize) {
            LOGI("AWGS WARNING: inconsistent block size values (%ld vs %d/%d)",
                blockSize, Get16LE(srcBuf), Get16LE(srcBuf+2));
            /* okay to ignore it, so long as everything else works out */
        }
        srcBuf += blockSize;
        srcLen -= blockSize;
    }

    *pSrcBuf = srcBuf;
    *pSrcLen = srcLen;

    return true;
}
Example #4
0
/*
 * Output a single chunk.  We do this by walking down the saveArray.
 */
void ReformatAWGS_WP::PrintChunk(const Chunk* pChunk)
{
    const int kDefaultStatusBits = kAWGSJustifyLeft | kAWGSSingleSpace;
    SaveArrayEntry sae;
    const uint8_t* saveArray;
    int saCount;
    const uint8_t* blockPtr;
    long blockLen;
    const uint8_t* pRuler;
    uint16_t rulerStatusBits;

    saveArray = pChunk->saveArray;
    saCount = pChunk->saveArrayCount;
    for ( ; saCount > 0; saCount--, saveArray += kSaveArrayEntryLen) {
        UnpackSaveArrayEntry(saveArray, &sae);

        /*
         * Page-break paragraphs have no real data and an invalid value
         * in the "rulerNum" field.  So we just throw out a page break
         * here and call it a day.
         */
        if (sae.attributes == 0x0001) {
            /* this is a page-break paragraph */
            RTFSetColor(kColorMediumBlue);
            RTFSetFont(kFontCourierNew);
            RTFSetFontSize(10);
            BufPrintf("<page-break>");
            RTFSetColor(kColorNone);
            RTFNewPara();
            RTFPageBreak();     // only supported by Word
            continue;
        }

        if (sae.rulerNum < pChunk->numRulers) {
            pRuler = pChunk->rulers + sae.rulerNum * kRulerEntryLen;
            rulerStatusBits = Get16LE(pRuler + 2);
        } else {
            LOGI("AWGS_WP GLITCH: invalid ruler index %d", sae.rulerNum);
            rulerStatusBits = kDefaultStatusBits;
        }

        if (rulerStatusBits & kAWGSJustifyFull)
            RTFParaJustify();
        else if (rulerStatusBits & kAWGSJustifyRight)
            RTFParaRight();
        else if (rulerStatusBits & kAWGSJustifyCenter)
            RTFParaCenter();
        else if (rulerStatusBits & kAWGSJustifyLeft)
            RTFParaLeft();
        RTFSetPara();

        /*
         * Find the text block that holds this paragraph.  We could speed
         * this up by creating an array of entries rather than walking the
         * list every time.  However, the block count tends to be fairly
         * small (e.g. 7 for a 16K doc).
         */
        blockPtr = FindTextBlock(pChunk, sae.textBlock);
        if (blockPtr == NULL) {
            LOGI("AWGS_WP bad textBlock %d", sae.textBlock);
            return;
        }
        blockLen = (long) Get32LE(blockPtr);
        if (blockLen <= 0 || blockLen > 65535) {
            LOGI("AWGS_WP invalid block len %d", blockLen);
            return;
        }
        blockPtr += 4;

        if (sae.offset >= blockLen) {
            LOGI("AWGS_WP bad offset: %d, blockLen=%ld",
                sae.offset, blockLen);
            return;
        }
        PrintParagraph(blockPtr + sae.offset, blockLen - sae.offset);
    }
}