From 68ea0b5875566c887693aa744a01869a7dcd2761 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Tue, 15 Aug 2023 18:25:33 +0300 Subject: [PATCH] Fix crash with 2+ emf inside wmf --- DesktopEditor/common/StringBuilder.cpp | 120 +++++----- .../raster/Metafile/Common/MetaFileUtils.h | 10 +- .../Metafile/Wmf/WmfParser/CWmfParserBase.cpp | 13 +- DesktopEditor/raster/Metafile/Wmf/WmfTypes.h | 120 +++++----- DesktopEditor/xml/include/xmlwriter.h | 10 +- DesktopEditor/xml/src/xmlwriter.cpp | 224 +++++++++--------- 6 files changed, 257 insertions(+), 240 deletions(-) diff --git a/DesktopEditor/common/StringBuilder.cpp b/DesktopEditor/common/StringBuilder.cpp index 2238aa8fd3..2a8d1b4ed7 100644 --- a/DesktopEditor/common/StringBuilder.cpp +++ b/DesktopEditor/common/StringBuilder.cpp @@ -78,9 +78,9 @@ namespace NSStringUtils { while ((m_lSizeCur + nSize) > m_lSize) { - if (m_lSize > 10485760/*10 * 1024 * 1024*/) + if (m_lSize > 10485760/*10 * 1024 * 1024*/) { - m_lSize += (std::max)((int)nSize * 10, 1048576/*1024 * 1024*/); + m_lSize += (std::max)((int)nSize * 10, 1048576/*1024 * 1024*/); } else { @@ -218,9 +218,9 @@ namespace NSStringUtils { while ((m_lSizeCur + nSize) > m_lSize) { - if (m_lSize > 10485760/*10 * 1024 * 1024*/) + if (m_lSize > 10485760/*10 * 1024 * 1024*/) { - m_lSize += (std::max)((int)nSize * 10, 1048576/*1024 * 1024*/); + m_lSize += (std::max)((int)nSize * 10, 1048576/*1024 * 1024*/); } else { @@ -252,17 +252,17 @@ namespace NSStringUtils ClearNoAttack(); WriteString(bsText); - for (size_t i = 0; i < m_lSizeCur; ++i) + for (size_t i = 0; i < m_lSizeCur; ++i) { if (WCHAR(8233) == m_pData[i]) m_pData[i] = WCHAR(' '); } } - void CStringBuilder::operator+=(const std::wstring& oTemp) - { - WriteString(oTemp.c_str(), oTemp.length()); - } + void CStringBuilder::operator+=(const std::wstring& oTemp) + { + WriteString(oTemp.c_str(), oTemp.length()); + } void CStringBuilder::WriteStringNoSafe(const wchar_t* pString, size_t nLen) { @@ -604,17 +604,17 @@ namespace NSStringUtils std::wstring str(m_pData, (int)m_lSizeCur); return str; } - std::wstring CStringBuilder::GetSubData(const size_t& start, const size_t& count) - { - if (start >= m_lSizeCur) - return L""; + std::wstring CStringBuilder::GetSubData(const size_t& start, const size_t& count) + { + if (start >= m_lSizeCur) + return L""; - size_t nCountMax = m_lSizeCur - start; - if (count != std::wstring::npos && count <= nCountMax) - nCountMax = count; + size_t nCountMax = m_lSizeCur - start; + if (count != std::wstring::npos && count <= nCountMax) + nCountMax = count; - return std::wstring(m_pData + start, nCountMax); - } + return std::wstring(m_pData + start, nCountMax); + } wchar_t* CStringBuilder::GetBuffer() { @@ -676,14 +676,14 @@ namespace NSStringUtils { if (0 == val) { - *m_pDataCur++ = (wchar_t)'0'; + *m_pDataCur++ = (wchar_t)'0'; ++m_lSizeCur; return; } if (val < 0) { val = -val; - *m_pDataCur++ = (wchar_t)'-'; + *m_pDataCur++ = (wchar_t)'-'; ++m_lSizeCur; } @@ -698,7 +698,7 @@ namespace NSStringUtils oval = 1; while (val > 0) { - m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); + m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); ++oval; val /= 10; } @@ -711,14 +711,14 @@ namespace NSStringUtils { if (0 == val) { - *m_pDataCur++ = (wchar_t)'0'; + *m_pDataCur++ = (wchar_t)'0'; ++m_lSizeCur; return; } if (val < 0) { val = -val; - *m_pDataCur++ = (wchar_t)'-'; + *m_pDataCur++ = (wchar_t)'-'; ++m_lSizeCur; } @@ -735,9 +735,9 @@ namespace NSStringUtils if (0 != nLastS) { ++len; - m_pDataCur[len - oval] = (wchar_t)('0' + nLastS); + m_pDataCur[len - oval] = (wchar_t)('0' + nLastS); ++oval; - m_pDataCur[len - oval] = (wchar_t)('.'); + m_pDataCur[len - oval] = (wchar_t)('.'); ++oval; val /= 10; } @@ -749,7 +749,7 @@ namespace NSStringUtils while (val > 0) { - m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); + m_pDataCur[len - oval] = (wchar_t)('0' + (val % 10)); ++oval; val /= 10; } @@ -852,14 +852,14 @@ namespace NSStringUtils WriteHexByteNoSafe((value >> 8) & 0xFF); WriteHexByteNoSafe(value & 0xFF); } - void CStringBuilder::WriteHexInt4(const unsigned int& value) - { - AddSize(8); - WriteHexByteNoSafe((value >> 24) & 0xFF); - WriteHexByteNoSafe((value >> 16) & 0xFF); - WriteHexByteNoSafe((value >> 8) & 0xFF); - WriteHexByteNoSafe(value & 0xFF); - } + void CStringBuilder::WriteHexInt4(const unsigned int& value) + { + AddSize(8); + WriteHexByteNoSafe((value >> 24) & 0xFF); + WriteHexByteNoSafe((value >> 16) & 0xFF); + WriteHexByteNoSafe((value >> 8) & 0xFF); + WriteHexByteNoSafe(value & 0xFF); + } void CStringBuilder::WriteHexColor3(const unsigned char& r, const unsigned char& g, const unsigned char& b) { AddSize(7); @@ -874,16 +874,16 @@ namespace NSStringUtils AddSize(7); *m_pDataCur++ = (wchar_t)'#'; ++m_lSizeCur; - WriteHexByteNoSafe(value & 0xFF); - WriteHexByteNoSafe((value >> 8) & 0xFF); - WriteHexByteNoSafe((value >> 16) & 0xFF); + WriteHexByteNoSafe(value & 0xFF); + WriteHexByteNoSafe((value >> 8) & 0xFF); + WriteHexByteNoSafe((value >> 16) & 0xFF); } - void CStringBuilder::Skip(int nSkip) - { - m_pDataCur += nSkip; - m_lSizeCur += nSkip; - } + void CStringBuilder::Skip(int nSkip) + { + m_pDataCur += nSkip; + m_lSizeCur += nSkip; + } void CStringBuilder::StartNode(const std::wstring& name) { WriteString(g_bstr_nodeopen); @@ -1121,22 +1121,22 @@ namespace NSStringUtils return 0; } - void string_replace(std::wstring& text, const std::wstring& replaceFrom, const std::wstring& replaceTo) - { - size_t posn = 0; - while (std::wstring::npos != (posn = text.find(replaceFrom, posn))) - { - text.replace(posn, replaceFrom.length(), replaceTo); - posn += replaceTo.length(); - } - } - void string_replaceA(std::string& text, const std::string& replaceFrom, const std::string& replaceTo) - { - size_t posn = 0; - while (std::string::npos != (posn = text.find(replaceFrom, posn))) - { - text.replace(posn, replaceFrom.length(), replaceTo); - posn += replaceTo.length(); - } - } + void string_replace(std::wstring& text, const std::wstring& replaceFrom, const std::wstring& replaceTo) + { + size_t posn = 0; + while (std::wstring::npos != (posn = text.find(replaceFrom, posn))) + { + text.replace(posn, replaceFrom.length(), replaceTo); + posn += replaceTo.length(); + } + } + void string_replaceA(std::string& text, const std::string& replaceFrom, const std::string& replaceTo) + { + size_t posn = 0; + while (std::string::npos != (posn = text.find(replaceFrom, posn))) + { + text.replace(posn, replaceFrom.length(), replaceTo); + posn += replaceTo.length(); + } + } } diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h index 99d5bf9c84..c234f5a3cb 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileUtils.h @@ -103,7 +103,7 @@ namespace MetaFile { pBuffer = pBuf; pCur = pBuf; - pEnd = pBuf + unSize + 1; + pEnd = pBuf + unSize; }; BYTE* GetCurPtr() { @@ -112,7 +112,7 @@ namespace MetaFile unsigned char ReadUChar() { - if (pCur + 1 >= pEnd) + if (pCur >= pEnd) return 0; unsigned char unResult = pCur[0]; @@ -121,7 +121,7 @@ namespace MetaFile }; unsigned short ReadUShort() { - if (pCur + 2 >= pEnd) + if (pCur + 1 >= pEnd) return 0; unsigned short ushResult = (pCur[0]) | ((pCur[1]) << 8); @@ -130,7 +130,7 @@ namespace MetaFile }; unsigned int ReadULong() { - if (pCur + 4 >= pEnd) + if (pCur + 3 >= pEnd) return 0; unsigned int unResult = (unsigned int)((pCur[0] << 0) | ((pCur[1]) << 8) | ((pCur[2]) << 16) | ((pCur[3]) << 24)); @@ -139,7 +139,7 @@ namespace MetaFile }; double ReadDouble() { - if (pCur + 4 >= pEnd) + if (pCur + 3 >= pEnd) return 0; float output; diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp index b49811f672..dbbdd99769 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp +++ b/DesktopEditor/raster/Metafile/Wmf/WmfParser/CWmfParserBase.cpp @@ -1706,9 +1706,12 @@ namespace MetaFile if (m_oEscapeBuffer.Empty()) m_oEscapeBuffer.SetSize(unEnhancedMetafileDataSize); - m_oStream.ReadBytes(m_oEscapeBuffer.GetCurPtr(), unCurrentRecordSize); + unsigned int nEscapeRecordSize = m_oEscapeBuffer.GetTileSize(); + if (nEscapeRecordSize > unCurrentRecordSize) + nEscapeRecordSize = unCurrentRecordSize; - m_oEscapeBuffer.IncreasePosition(unCurrentRecordSize); + m_oStream.ReadBytes(m_oEscapeBuffer.GetCurPtr(), nEscapeRecordSize); + m_oEscapeBuffer.IncreasePosition(nEscapeRecordSize); if (0 == unRemainingBytes) { @@ -1719,10 +1722,14 @@ namespace MetaFile oEmfParser.Scan(); if (oEmfParser.CheckError()) + { + m_oEscapeBuffer.Clear(); return; + } if (NULL == m_pInterpretator) { + m_oEscapeBuffer.Clear(); return HANDLE_META_EOF(); } else if (InterpretatorType::Render == m_pInterpretator->GetType()) @@ -1762,6 +1769,8 @@ namespace MetaFile HANDLE_META_EOF(); } + + m_oEscapeBuffer.Clear(); } } // TODO: Реализовать diff --git a/DesktopEditor/raster/Metafile/Wmf/WmfTypes.h b/DesktopEditor/raster/Metafile/Wmf/WmfTypes.h index a7baa1109f..7580d9de10 100644 --- a/DesktopEditor/raster/Metafile/Wmf/WmfTypes.h +++ b/DesktopEditor/raster/Metafile/Wmf/WmfTypes.h @@ -385,68 +385,72 @@ namespace MetaFile }; class CWmfEscapeBuffer { - public: - CWmfEscapeBuffer() : m_pBytes(NULL), m_unSize(0), m_unPosition(0) {}; - ~CWmfEscapeBuffer() + public: + CWmfEscapeBuffer() : m_pBytes(NULL), m_unSize(0), m_unPosition(0) {}; + ~CWmfEscapeBuffer() + { + Clear(); + } + + bool Empty() const + { + return 0 == m_unSize; + } + + void SetSize(unsigned int unSize) + { + Clear(); + m_unSize = unSize; + m_pBytes = new unsigned char[m_unSize]; + }; + + void IncreasePosition(unsigned int unValue) + { + m_unPosition += unValue; + + if (m_unPosition > m_unSize) + m_unPosition = m_unSize; + } + + unsigned char* GetBuffer() const + { + return m_pBytes; + } + + unsigned char* GetCurPtr() const + { + if (NULL == m_pBytes || 0 == m_unSize) + return NULL; + + return m_pBytes + m_unPosition; + } + + unsigned int GetSize() const + { + return m_unSize; + } + + unsigned int GetTileSize() const + { + return m_unSize - m_unPosition; + } + + void Clear() + { + if (NULL != m_pBytes) { - Clear(); + delete m_pBytes; + m_pBytes = NULL; } - bool Empty() const - { - return 0 == m_unSize; - } + m_unSize = 0; + m_unPosition = 0; + } - void SetSize(unsigned int unSize) - { - Clear(); - m_unSize = unSize; - m_pBytes = new unsigned char[m_unSize]; - }; - - void IncreasePosition(unsigned int unValue) - { - m_unPosition += unValue; - - if (m_unPosition > m_unSize) - m_unPosition = m_unSize; - } - - unsigned char* GetBuffer() const - { - return m_pBytes; - } - - unsigned char* GetCurPtr() const - { - if (NULL == m_pBytes || 0 == m_unSize) - return NULL; - - return m_pBytes + m_unPosition; - } - - unsigned int GetSize() const - { - return m_unSize; - } - - private: - - void Clear() - { - if (NULL != m_pBytes) - { - delete m_pBytes; - m_pBytes = NULL; - } - - m_unSize = 0; - m_unPosition = 0; - } - - unsigned char* m_pBytes; - unsigned int m_unSize; - unsigned int m_unPosition; + private: + unsigned char* m_pBytes; + unsigned int m_unSize; + unsigned int m_unPosition; }; } diff --git a/DesktopEditor/xml/include/xmlwriter.h b/DesktopEditor/xml/include/xmlwriter.h index 13334ec1ed..0518b67176 100644 --- a/DesktopEditor/xml/include/xmlwriter.h +++ b/DesktopEditor/xml/include/xmlwriter.h @@ -38,7 +38,7 @@ #include #ifdef _MSC_VER - #pragma warning (disable: 4100 4189) +#pragma warning (disable: 4100 4189) #endif #include "../../common/StringBuilder.h" @@ -52,13 +52,13 @@ namespace XmlUtils class KERNEL_DECL CXmlWriter { private: - class Impl; - std::shared_ptr impl_; - + class Impl; + std::shared_ptr impl_; + public: CXmlWriter(); - ~CXmlWriter(); + ~CXmlWriter(); std::wstring GetXmlString(); void SetXmlString(const std::wstring& strValue); diff --git a/DesktopEditor/xml/src/xmlwriter.cpp b/DesktopEditor/xml/src/xmlwriter.cpp index bd4205faed..8f7605c6ee 100644 --- a/DesktopEditor/xml/src/xmlwriter.cpp +++ b/DesktopEditor/xml/src/xmlwriter.cpp @@ -34,122 +34,126 @@ namespace XmlUtils { - class CXmlWriter::Impl - { - public: - std::wstring m_str; - }; + class CXmlWriter::Impl + { + public: + NSStringUtils::CStringBuilder m_str; + }; - CXmlWriter::CXmlWriter() : impl_(NULL) - { - impl_ = std::make_shared(); - } - CXmlWriter::~CXmlWriter() - { - } + CXmlWriter::CXmlWriter() : impl_(NULL) + { + impl_ = std::make_shared(); + } + CXmlWriter::~CXmlWriter() + { + } - std::wstring CXmlWriter::GetXmlString() - { - if (impl_) return impl_->m_str; - else return L""; - } - void CXmlWriter::SetXmlString(const std::wstring& strValue) - { - if (impl_) impl_->m_str = strValue; - } + std::wstring CXmlWriter::GetXmlString() + { + if (impl_) return impl_->m_str.GetData(); + else return L""; + } + void CXmlWriter::SetXmlString(const std::wstring& strValue) + { + if (impl_) + { + impl_->m_str.Clear(); + impl_->m_str.WriteString(strValue); + } + } - bool CXmlWriter::SaveToFile(const std::wstring& strFilePath/*, bool bEncodingToUTF8 = false*/) - { - if (impl_) - return NSFile::CFileBinary::SaveToFile(strFilePath, impl_->m_str); - else - return false; - } - void CXmlWriter::WriteString(const std::wstring& strValue) - { - if (impl_) impl_->m_str += strValue; - } - void CXmlWriter::WriteInteger(int Value) - { - if (impl_) impl_->m_str += std::to_wstring(Value); - } - void CXmlWriter::WriteDouble(double Value) - { - if (impl_) impl_->m_str += std::to_wstring(Value); - } - void CXmlWriter::WriteBoolean(bool Value) - { - if (!impl_) return; + bool CXmlWriter::SaveToFile(const std::wstring& strFilePath/*, bool bEncodingToUTF8 = false*/) + { + if (impl_) + return NSFile::CFileBinary::SaveToFile(strFilePath, impl_->m_str.GetData()); + else + return false; + } + void CXmlWriter::WriteString(const std::wstring& strValue) + { + if (impl_) impl_->m_str += strValue; + } + void CXmlWriter::WriteInteger(int Value) + { + if (impl_) impl_->m_str += std::to_wstring(Value); + } + void CXmlWriter::WriteDouble(double Value) + { + if (impl_) impl_->m_str += std::to_wstring(Value); + } + void CXmlWriter::WriteBoolean(bool Value) + { + if (!impl_) return; - if (Value) - impl_->m_str += (L"true"); - else - impl_->m_str += (L"false"); - } - void CXmlWriter::WriteNodeBegin(const std::wstring& strNodeName, bool bAttributed) - { - if (!impl_) return; + if (Value) + impl_->m_str += (L"true"); + else + impl_->m_str += (L"false"); + } + void CXmlWriter::WriteNodeBegin(const std::wstring& strNodeName, bool bAttributed) + { + if (!impl_) return; - impl_->m_str += (L"<") + strNodeName; + impl_->m_str += (L"<") + strNodeName; - if (!bAttributed) - impl_->m_str += (L">"); - } - void CXmlWriter::WriteNodeEnd(const std::wstring& strNodeName, bool bEmptyNode, bool bEndNode) - { - if (!impl_) return; + if (!bAttributed) + impl_->m_str += (L">"); + } + void CXmlWriter::WriteNodeEnd(const std::wstring& strNodeName, bool bEmptyNode, bool bEndNode) + { + if (!impl_) return; - if (bEmptyNode) - { - if (bEndNode) - impl_->m_str += (L" />"); - else - impl_->m_str += (L">"); - } - else - impl_->m_str += (L""); - } - void CXmlWriter::WriteNode(const std::wstring& strNodeName, const std::wstring& strNodeValue) - { - if (!impl_) return; + if (bEmptyNode) + { + if (bEndNode) + impl_->m_str += (L" />"); + else + impl_->m_str += (L">"); + } + else + impl_->m_str += (L""); + } + void CXmlWriter::WriteNode(const std::wstring& strNodeName, const std::wstring& strNodeValue) + { + if (!impl_) return; - if (strNodeValue.empty()) - impl_->m_str += L"<" + strNodeName + L"/>"; - else - impl_->m_str += L"<" + strNodeName + L">" + strNodeValue + L""; - } - void CXmlWriter::WriteNode(const std::wstring& strNodeName, int nValue, const std::wstring& strTextBeforeValue, const std::wstring& strTextAfterValue) - { - WriteNodeBegin(strNodeName); - WriteString(strTextBeforeValue); - WriteInteger(nValue); - WriteString(strTextAfterValue); - WriteNodeEnd(strNodeName); - } - void CXmlWriter::WriteNode(const std::wstring& strNodeName, double dValue) - { - WriteNodeBegin(strNodeName); - WriteDouble(dValue); - WriteNodeEnd(strNodeName); - } - void CXmlWriter::WriteAttribute(const std::wstring& strAttributeName, const std::wstring& strAttributeValue) - { - if (impl_) impl_->m_str += L" " + strAttributeName + L"=\"" + strAttributeValue + L"\""; - } - void CXmlWriter::WriteAttribute(const std::wstring& strAttributeName, int nValue, const std::wstring& strTextBeforeValue, const std::wstring& strTextAfterValue) - { - WriteString(L" " + strAttributeName + L"="); - WriteString(L"\""); - WriteString(strTextBeforeValue); - WriteInteger(nValue); - WriteString(strTextAfterValue); - WriteString(L"\""); - } - void CXmlWriter::WriteAttribute(const std::wstring& strAttributeName, double dValue) - { - WriteString(L" " + strAttributeName + L"="); - WriteString(L"\""); - WriteDouble(dValue); - WriteString(L"\""); - } + if (strNodeValue.empty()) + impl_->m_str += L"<" + strNodeName + L"/>"; + else + impl_->m_str += L"<" + strNodeName + L">" + strNodeValue + L""; + } + void CXmlWriter::WriteNode(const std::wstring& strNodeName, int nValue, const std::wstring& strTextBeforeValue, const std::wstring& strTextAfterValue) + { + WriteNodeBegin(strNodeName); + WriteString(strTextBeforeValue); + WriteInteger(nValue); + WriteString(strTextAfterValue); + WriteNodeEnd(strNodeName); + } + void CXmlWriter::WriteNode(const std::wstring& strNodeName, double dValue) + { + WriteNodeBegin(strNodeName); + WriteDouble(dValue); + WriteNodeEnd(strNodeName); + } + void CXmlWriter::WriteAttribute(const std::wstring& strAttributeName, const std::wstring& strAttributeValue) + { + if (impl_) impl_->m_str += L" " + strAttributeName + L"=\"" + strAttributeValue + L"\""; + } + void CXmlWriter::WriteAttribute(const std::wstring& strAttributeName, int nValue, const std::wstring& strTextBeforeValue, const std::wstring& strTextAfterValue) + { + WriteString(L" " + strAttributeName + L"="); + WriteString(L"\""); + WriteString(strTextBeforeValue); + WriteInteger(nValue); + WriteString(strTextAfterValue); + WriteString(L"\""); + } + void CXmlWriter::WriteAttribute(const std::wstring& strAttributeName, double dValue) + { + WriteString(L" " + strAttributeName + L"="); + WriteString(L"\""); + WriteDouble(dValue); + WriteString(L"\""); + } }