Ejemplo n.º 1
0
unsigned char *ChmDoc::GetData(const char *fileName, size_t *lenOut)
{
    ScopedMem<char> fileNameTmp;
    if (!str::StartsWith(fileName, "/")) {
        fileNameTmp.Set(str::Join("/", fileName));
        fileName = fileNameTmp;
    } else if (str::StartsWith(fileName, "///")) {
        fileName += 2;
    }

    struct chmUnitInfo info;
    int res = chm_resolve_object(chmHandle, fileName, &info);
    if (CHM_RESOLVE_SUCCESS != res && str::FindChar(fileName, '\\')) {
        // Microsoft's HTML Help CHM viewer tolerates backslashes in URLs
        fileNameTmp.SetCopy(fileName);
        str::TransChars(fileNameTmp, "\\", "/");
        fileName = fileNameTmp;
        res = chm_resolve_object(chmHandle, fileName, &info);
    }
    if (CHM_RESOLVE_SUCCESS != res)
        return nullptr;
    size_t len = (size_t)info.length;
    if (len > 128 * 1024 * 1024) {
        // don't allow anything above 128 MB
        return nullptr;
    }

    // +1 for 0 terminator for C string compatibility
    ScopedMem<unsigned char> data((unsigned char *)malloc(len + 1));
    if (!data)
        return nullptr;
    if (!chm_retrieve_object(chmHandle, &info, data.Get(), 0, len))
        return nullptr;
    data[len] = '\0';

    if (lenOut)
        *lenOut = len;
    return data.StealData();
}