Fix bug 74424

LoadFromMemory memory is copied
MergePages memory is either taken or freed
This commit is contained in:
Svetlana Kulikova
2025-06-02 12:45:35 +03:00
parent 00a82a7693
commit 10e6664313
12 changed files with 78 additions and 63 deletions

View File

@ -289,10 +289,20 @@ public:
return ((CPdfFile*)m_pFile)->SplitPages(arrPageIndex, nLength, data, size);
return NULL;
}
bool MergePages(BYTE* data, LONG size, int nMaxID, const std::string& sPrefixForm)
bool MergePages(BYTE* data, LONG size, int nMaxID, const std::string& sPrefixForm, bool bCopy = false)
{
if (m_nType == 0)
{
// Память из CDrawingFileEmbed освобождается сразу после вызова функции, поэтому копируем
if (bCopy)
{
BYTE* pCopy = (BYTE*)malloc(size);
memcpy(pCopy, data, size);
data = pCopy;
}
// Захватывает полученную память, будет освобождена либо в деструкторе MemStream, либо free в случае неудачи
return ((CPdfFile*)m_pFile)->MergePages(data, size, nMaxID, sPrefixForm);
}
return false;
}
bool UnmergePages()

View File

@ -195,7 +195,7 @@ JSSmart<CJSValue> CDrawingFileEmbed::MergePages(JSSmart<CJSValue> data, JSSmart<
int maxID = nMaxID->toInt32();
std::string prefix = sPrefixForm->toStringA();
CJSDataBuffer buffer = dataPtr->getData();
result = m_pFile->MergePages(buffer.Data, (LONG)buffer.Len, maxID, prefix);
result = m_pFile->MergePages(buffer.Data, (LONG)buffer.Len, maxID, prefix, true);
if (buffer.IsExternalize)
buffer.Free();
}

View File

@ -40,7 +40,7 @@ var UpdateFontsSource = {
function CFile()
{
this.nativeFile = 0;
this.stream = [];
this.stream = -1;
this.stream_size = 0;
this.type = -1;
this.pages = [];
@ -128,17 +128,17 @@ CFile.prototype["close"] = function()
this.pages = [];
this.info = null;
this.StartID = null;
for (let i = 0; i < this.stream.length; i++)
this._free(this.stream[i]);
this.stream = [];
if (this.stream > 0)
this._free(this.stream);
this.stream = -1;
self.drawingFile = null;
};
CFile.prototype["getFileBinary"] = function()
{
if (this.stream.length == 0)
if (0 >= this.stream)
return "";
return new Uint8Array(Module["HEAP8"].buffer, this.stream[0], this.stream_size);
return new Uint8Array(Module["HEAP8"].buffer, this.stream, this.stream_size);
};
CFile.prototype["isNeedPassword"] = function()

View File

@ -101,9 +101,8 @@ CFile.prototype._openFile = function(buffer, password)
{
let data = new Uint8Array(buffer);
this.stream_size = data.length;
let stream = Module["_malloc"](this.stream_size);
Module["HEAP8"].set(data, stream);
this.stream.push(stream);
this.stream = Module["_malloc"](this.stream_size);
Module["HEAP8"].set(data, this.stream);
}
let passwordPtr = 0;
@ -114,7 +113,7 @@ CFile.prototype._openFile = function(buffer, password)
Module["HEAP8"].set(passwordBuf, passwordPtr);
}
this.nativeFile = Module["_Open"](this.stream[0], this.stream_size, passwordPtr);
this.nativeFile = Module["_Open"](this.stream, this.stream_size, passwordPtr);
if (passwordPtr)
Module["_free"](passwordPtr);
@ -128,7 +127,7 @@ CFile.prototype._closeFile = function()
CFile.prototype._getType = function()
{
return Module["_GetType"](this.stream[0], this.stream_size);
return Module["_GetType"](this.nativeFile);
};
CFile.prototype._getError = function()
@ -180,10 +179,7 @@ CFile.prototype._MergePages = function(buffer, maxID, prefixForm)
}
let bRes = Module["_MergePages"](this.nativeFile, stream2, data.length, maxID, prefixPtr);
if (bRes == 1)
this.stream.push(stream2);
else
Module["_free"](stream2);
stream2 = 0; // Success or not, stream2 is either taken or freed
if (prefixPtr)
Module["_free"](prefixPtr);
@ -193,13 +189,7 @@ CFile.prototype._MergePages = function(buffer, maxID, prefixForm)
CFile.prototype._UndoMergePages = function()
{
let bRes = Module["_UnmergePages"](this.nativeFile);
if (bRes == 1)
{
let str = this.stream.pop();
Module["_free"](str);
}
return bRes == 1;
return Module["_UnmergePages"](this.nativeFile) == 1;
};
// FONTS

View File

@ -68,25 +68,6 @@ WASM_EXPORT int IsFontBinaryExist(char* path)
return 0;
}
WASM_EXPORT int GetType(BYTE* data, LONG size)
{
// 0 - PDF
// 1 - DJVU
// 2 - XPS
LONG nHeaderSearchSize = 1024;
LONG nSize = size < nHeaderSearchSize ? size : nHeaderSearchSize;
char* pData = (char*)data;
for (int i = 0; i < nSize - 5; ++i)
{
int nPDF = strncmp(&pData[i], "%PDF-", 5);
if (!nPDF)
return 0;
}
if ( (8 <= size) && (0x41 == data[0] && 0x54 == data[1] && 0x26 == data[2] && 0x54 == data[3] &&
0x46 == data[4] && 0x4f == data[5] && 0x52 == data[6] && 0x4d == data[7]))
return 1;
return 2;
}
WASM_EXPORT CDrawingFile* Open(BYTE* data, LONG size, const char* password)
{
if (!g_applicationFonts)
@ -102,6 +83,13 @@ WASM_EXPORT CDrawingFile* Open(BYTE* data, LONG size, const char* password)
pFile->OpenFile(data, size, sPassword);
return pFile;
}
WASM_EXPORT int GetType(CDrawingFile* pFile)
{
// 0 - PDF
// 1 - DJVU
// 2 - XPS
return pFile->GetType();
}
WASM_EXPORT int GetErrorCode(CDrawingFile* pFile)
{
if (!pFile)

View File

@ -1022,10 +1022,10 @@ int main(int argc, char* argv[])
}
}
RELEASEARRAYOBJECTS(pFileData);
// SPLIT & MERGE
BYTE* pSplitPages = NULL;
BYTE* pFileMerge = NULL;
if (false)
if (true)
{
int nBufferLen = NULL;
BYTE* pBuffer = NULL;
@ -1036,12 +1036,19 @@ int main(int argc, char* argv[])
BYTE* pSplitPages = SplitPages(pGrFile, arrPages.data(), arrPages.size(), pBuffer, nBufferLen);
int nLength = READ_INT(pSplitPages);
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/split1.pdf"))
oFile.WriteFile(pSplitPages + 4, nLength - 4);
oFile.CloseFile();
if (nLength > 4)
{
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/split1.pdf"))
oFile.WriteFile(pSplitPages + 4, nLength - 4);
oFile.CloseFile();
MergePages(pGrFile, pSplitPages + 4, nLength - 4, 0, "merge1");
BYTE* pMallocData = (BYTE*)malloc(nLength - 4);
memcpy(pMallocData, pSplitPages + 4, nLength - 4);
MergePages(pGrFile, pMallocData, nLength - 4, 0, "merge1");
}
RELEASEARRAYOBJECTS(pSplitPages);
}
RELEASEARRAYOBJECTS(pBuffer);
@ -1051,12 +1058,19 @@ int main(int argc, char* argv[])
BYTE* pSplitPages = SplitPages(pGrFile, arrPages.data(), arrPages.size(), pBuffer, nBufferLen);
int nLength = READ_INT(pSplitPages);
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/split2.pdf"))
oFile.WriteFile(pSplitPages + 4, nLength - 4);
oFile.CloseFile();
if (nLength > 4)
{
NSFile::CFileBinary oFile;
if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/split2.pdf"))
oFile.WriteFile(pSplitPages + 4, nLength - 4);
oFile.CloseFile();
MergePages(pGrFile, pSplitPages + 4, nLength - 4, 0, "merge2");
BYTE* pMallocData = (BYTE*)malloc(nLength - 4);
memcpy(pMallocData, pSplitPages + 4, nLength - 4);
MergePages(pGrFile, pMallocData, nLength - 4, 0, "merge2");
}
RELEASEARRAYOBJECTS(pSplitPages);
}
RELEASEARRAYOBJECTS(pBuffer);
}
@ -2053,9 +2067,6 @@ int main(int argc, char* argv[])
}
Close(pGrFile);
RELEASEARRAYOBJECTS(pFileData);
RELEASEARRAYOBJECTS(pSplitPages);
RELEASEARRAYOBJECTS(pFileMerge);
RELEASEARRAYOBJECTS(pCMapData);
return 0;