From a3878b3770f6477bdd49409657843047d6ac9456 Mon Sep 17 00:00:00 2001 From: Prokhorov Kirill Date: Tue, 4 Mar 2025 16:34:29 +0300 Subject: [PATCH 01/23] Fix bug 72950 --- DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h b/DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h index 50b4e28494..1365926a27 100644 --- a/DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h +++ b/DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h @@ -207,9 +207,9 @@ namespace agg } p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift)); - p[Order::R] = (value_type)((alpha * cr + a * r - ((a * r * alpha + base_mask) >> base_shift)) / p[Order::A]); - p[Order::G] = (value_type)((alpha * cg + a * g - ((a * g * alpha + base_mask) >> base_shift)) / p[Order::A]); - p[Order::B] = (value_type)((alpha * cb + a * b - ((a * b * alpha + base_mask) >> base_shift)) / p[Order::A]); + if (r != cr) p[Order::R] = (value_type)((alpha * cr + a * r - ((a * r * alpha + base_mask) >> base_shift)) / p[Order::A]); + if (g != cg) p[Order::G] = (value_type)((alpha * cg + a * g - ((a * g * alpha + base_mask) >> base_shift)) / p[Order::A]); + if (b != cb) p[Order::B] = (value_type)((alpha * cb + a * b - ((a * b * alpha + base_mask) >> base_shift)) / p[Order::A]); } static AGG_INLINE void blend_pix_subpix(value_type* p, From ba9d3bcda5786f7c6b20c581900059d3ee20fc55 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 4 Mar 2025 19:46:43 +0300 Subject: [PATCH 02/23] Fix pdf properties exists --- PdfFile/PdfEditor.cpp | 5 +---- PdfFile/test/test.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 055d309137..ed34386b31 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -963,10 +963,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) { Object oRes; char* chKey2 = oTemp.dictGetKey(nIndex); - if (strcmp("Font", chKey2) == 0 || strcmp("ExtGState", chKey2) == 0 || strcmp("XObject", chKey2) == 0 || strcmp("Shading", chKey2) == 0 || strcmp("Pattern", chKey2) == 0) - oTemp.dictGetVal(nIndex, &oRes); - else - oTemp.dictGetValNF(nIndex, &oRes); + oTemp.dictGetVal(nIndex, &oRes); DictToCDictObject(&oRes, pDict, false, chKey2); oRes.free(); } diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 49e36f3bc8..8dbdcec31a 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -372,7 +372,7 @@ TEST_F(CPdfFileTest, EditPdf) TEST_F(CPdfFileTest, EditPdfFromBase64) { - //GTEST_SKIP(); + GTEST_SKIP(); NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); @@ -417,14 +417,14 @@ TEST_F(CPdfFileTest, EditPdfFromBase64) TEST_F(CPdfFileTest, EditPdfFromBin) { - GTEST_SKIP(); + // GTEST_SKIP(); LoadFromFile(); ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); // чтение бинарника NSFile::CFileBinary oFile; - ASSERT_TRUE(oFile.OpenFile(NSFile::GetProcessDirectory() + L"/changes0.json")); + ASSERT_TRUE(oFile.OpenFile(NSFile::GetProcessDirectory() + L"/changes.bin")); DWORD dwFileSize = oFile.GetFileSize(); BYTE* pFileContent = new BYTE[dwFileSize]; @@ -440,7 +440,7 @@ TEST_F(CPdfFileTest, EditPdfFromBin) CConvertFromBinParams* pParams = new CConvertFromBinParams(); pParams->m_sMediaDirectory = NSFile::GetProcessDirectory(); - pdfFile->AddToPdfFromBinary(pFileContent, dwReaded, pParams); + pdfFile->AddToPdfFromBinary(pFileContent + 4, dwReaded - 4, pParams); RELEASEOBJECT(pParams); RELEASEARRAYOBJECTS(pFileContent); From d2ea9521b5d5becba5ddfecb4f28834f7053082f Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Wed, 5 Mar 2025 18:59:59 +0300 Subject: [PATCH 03/23] Add support license --- .../doctrenderer/addon/docbuilder_addon.h | 5 +-- .../doctrenderer/app_builder/main.cpp | 36 +++++++++++++++++++ .../docbuilder.python/src/docbuilder.py | 6 ++++ DesktopEditor/doctrenderer/docbuilder_p.h | 4 +-- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/doctrenderer/addon/docbuilder_addon.h b/DesktopEditor/doctrenderer/addon/docbuilder_addon.h index 7e5bf747ad..ae9b5f8445 100644 --- a/DesktopEditor/doctrenderer/addon/docbuilder_addon.h +++ b/DesktopEditor/doctrenderer/addon/docbuilder_addon.h @@ -33,6 +33,7 @@ #define DOC_BUILDER_ADDON_PRIVATE #include +#include "../docbuilder.h" namespace NSDoctRenderer { @@ -46,11 +47,11 @@ namespace NSDoctRenderer m_sWorkDirectory = sWorkDir; } public: - std::wstring GetX2tSaveAddon() + std::wstring GetX2tSaveAddon(NSDoctRenderer::CDocBuilder* builder, const int& filetype) { return L""; } - int GetX2tPreSaveError() + int GetX2tPreSaveError(NSDoctRenderer::CDocBuilder* builder, const int& filetype) { return 0; } diff --git a/DesktopEditor/doctrenderer/app_builder/main.cpp b/DesktopEditor/doctrenderer/app_builder/main.cpp index 0507c86a16..2b3a2ffe12 100644 --- a/DesktopEditor/doctrenderer/app_builder/main.cpp +++ b/DesktopEditor/doctrenderer/app_builder/main.cpp @@ -33,6 +33,7 @@ #include "./../common_deploy.h" #include "../docbuilder.h" #include "../../common/File.h" +#include "../../common/SystemUtils.h" #ifdef LINUX #include "../../../DesktopEditor/common/File.h" @@ -78,6 +79,13 @@ void parse_args(NSDoctRenderer::CDocBuilder* builder, int argc, char *argv[]) } } +bool CheckLicense(const std::wstring& sSrc, const std::wstring& sDst) +{ + NSFile::CFileBinary::Remove(sDst); + NSFile::CFileBinary::Copy(sSrc, sDst); + return NSFile::CFileBinary::Exists(sDst); +} + #ifdef WIN32 int wmain(int argc, wchar_t *argv[]) #else @@ -89,6 +97,7 @@ int main(int argc, char *argv[]) bool bIsHelp = false; bool bIsFonts = false; + bool bIsLicense = false; for (int i = 0; i < argc; ++i) { #ifdef WIN32 @@ -121,6 +130,33 @@ int main(int argc, char *argv[]) { bIsFonts = true; } + else if (sParam == "-register") + { + bIsLicense = true; + } + else + { + if (bIsLicense) + { + std::wstring sLicensePathSrc = UTF8_TO_U(sParam); + if (!NSFile::CFileBinary::Exists(sLicensePathSrc)) + return 1; + + std::wstring sLicensePath = NSSystemUtils::GetEnvVariable(L"ONLYOFFICE_BUILDER_LICENSE"); + if (CheckLicense(sLicensePathSrc, sLicensePath)) + return 0; + + sLicensePath = NSFile::GetProcessDirectory() + L"/license.xml"; + if (CheckLicense(sLicensePathSrc, sLicensePath)) + return 0; + + sLicensePath = NSSystemUtils::GetAppDataDir() + L"/docbuilder/license.xml"; + if (CheckLicense(sLicensePathSrc, sLicensePath)) + return 0; + + return 1; + } + } } if (bIsFonts) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index ac06615386..e7973c4cab 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -612,4 +612,10 @@ builder_path = os.path.dirname(os.path.realpath(__file__)) _loadLibrary(builder_path) CDocBuilder.Initialize(builder_path) +def registerLibrary(license_path): + docbuilder_bin = os.path.dirname(os.path.realpath(__file__)) + os.pathsep + "docbuilder" + if ("windows" == platform.system().lower()): + docbuilder_bin += ".exe" + return subprocess.call([docbuilder_bin, license_path], stderr=subprocess.STDOUT, shell=True) + atexit.register(CDocBuilder.Dispose) diff --git a/DesktopEditor/doctrenderer/docbuilder_p.h b/DesktopEditor/doctrenderer/docbuilder_p.h index 6603297f22..d0d18f612b 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.h +++ b/DesktopEditor/doctrenderer/docbuilder_p.h @@ -1003,7 +1003,7 @@ namespace NSDoctRenderer CDocBuilderAddon oSaveAddon(m_sX2tPath); - int nPreSaveError = oSaveAddon.GetX2tPreSaveError(); + int nPreSaveError = oSaveAddon.GetX2tPreSaveError(m_pParent, m_nFileType); if (0 != nPreSaveError) return nPreSaveError; @@ -1090,7 +1090,7 @@ namespace NSDoctRenderer if (!sOptions.empty()) oBuilder.WriteString(UTF8_TO_U(sOptions)); - oBuilder.WriteString(oSaveAddon.GetX2tSaveAddon()); + oBuilder.WriteString(oSaveAddon.GetX2tSaveAddon(m_pParent, m_nFileType)); oBuilder.WriteString(L""); From e9852e812f7a1f30502c52e99eee6034ff813623 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Wed, 5 Mar 2025 19:13:38 +0300 Subject: [PATCH 04/23] Turn on ligatures for arabic & syriac scripts --- DesktopEditor/fontengine/TextShaper.cpp | 7 +++++++ DesktopEditor/fontengine/js/cpp/text.cpp | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/DesktopEditor/fontengine/TextShaper.cpp b/DesktopEditor/fontengine/TextShaper.cpp index 4e509d5cc8..6efcb547ed 100644 --- a/DesktopEditor/fontengine/TextShaper.cpp +++ b/DesktopEditor/fontengine/TextShaper.cpp @@ -693,6 +693,13 @@ namespace NSShaper g_userfeatures_init = true; } + // Turn on ligatures on arabic script + if (nScript == HB_SCRIPT_ARABIC || + nScript == HB_SCRIPT_SYRIAC) + { + nFeatures |= 1; + } + // font hb_font_t* pFont; if (NULL == font) diff --git a/DesktopEditor/fontengine/js/cpp/text.cpp b/DesktopEditor/fontengine/js/cpp/text.cpp index 9857242738..63503a3dea 100644 --- a/DesktopEditor/fontengine/js/cpp/text.cpp +++ b/DesktopEditor/fontengine/js/cpp/text.cpp @@ -594,6 +594,13 @@ WASM_EXPORT unsigned char* ASC_HB_ShapeText(FT_Face pFace, hb_font_t* pFont, cha g_userfeatures_init = true; } + // Turn on ligatures on arabic script + if (nScript == HB_SCRIPT_ARABIC || + nScript == HB_SCRIPT_SYRIAC) + { + nFeatures |= 1; + } + // font if (NULL == pFont) { From 6aa68f1c8141517c73495ad0134347cd7c92a4bb Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Thu, 6 Mar 2025 15:56:30 +0300 Subject: [PATCH 05/23] Add GetPropertyInt method --- DesktopEditor/doctrenderer/docbuilder.h | 7 +++++++ DesktopEditor/doctrenderer/docbuilder_p.cpp | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/DesktopEditor/doctrenderer/docbuilder.h b/DesktopEditor/doctrenderer/docbuilder.h index 5580500cbf..bb0ac82202 100644 --- a/DesktopEditor/doctrenderer/docbuilder.h +++ b/DesktopEditor/doctrenderer/docbuilder.h @@ -475,6 +475,13 @@ namespace NSDoctRenderer */ void SetPropertyW(const wchar_t* param, const wchar_t* value); + /** + * GetProperty method. + * @param param The parameter name in the Unicode format, the value is always --argument. + * @return int value for property + */ + int GetPropertyInt(const wchar_t* param); + /** * Writes data to the log file. It is used for logs in JS code. * @param path The path to the file where all the logs will be written. diff --git a/DesktopEditor/doctrenderer/docbuilder_p.cpp b/DesktopEditor/doctrenderer/docbuilder_p.cpp index adb3c60f56..d1c7d73e63 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.cpp +++ b/DesktopEditor/doctrenderer/docbuilder_p.cpp @@ -1596,6 +1596,15 @@ namespace NSDoctRenderer return this->SetProperty(sA.c_str(), value); } + int CDocBuilder::GetPropertyInt(const wchar_t* param) + { + std::wstring sParam = std::wstring(param); + std::string sParamA = U_TO_UTF8(sParam); + if ("--save-use-only-names" == sParamA) + return m_pInternal->m_bIsServerSafeVersion ? 1 : 0; + return -1; + } + void CDocBuilder::Initialize(const wchar_t* directory) { std::wstring sDirectory = L""; From 43becd1cdb290621599de2b8c26335d95d40e1c3 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 7 Mar 2025 11:03:20 +0300 Subject: [PATCH 06/23] Fix registerLibrary method --- .../doctrenderer/docbuilder.python/src/docbuilder.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index e7973c4cab..a09d1f4afd 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -2,6 +2,7 @@ import ctypes import os import platform import atexit +import subprocess OBJECT_HANDLE = ctypes.c_void_p STRING_HANDLE = ctypes.c_void_p @@ -608,14 +609,14 @@ class FileTypes: PNG = _IMAGE_MASK + 0x0005 BMP = _IMAGE_MASK + 0x0008 -builder_path = os.path.dirname(os.path.realpath(__file__)) +builder_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib') _loadLibrary(builder_path) CDocBuilder.Initialize(builder_path) def registerLibrary(license_path): - docbuilder_bin = os.path.dirname(os.path.realpath(__file__)) + os.pathsep + "docbuilder" + docbuilder_bin = os.path.dirname(os.path.realpath(__file__)) + "/lib/docbuilder" if ("windows" == platform.system().lower()): docbuilder_bin += ".exe" - return subprocess.call([docbuilder_bin, license_path], stderr=subprocess.STDOUT, shell=True) + return subprocess.call([docbuilder_bin, "-register", license_path], stderr=subprocess.STDOUT, shell=True) atexit.register(CDocBuilder.Dispose) From ac2562f83e718a00743873c21fe116253ad32caf Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 10 Mar 2025 14:32:00 +0600 Subject: [PATCH 07/23] fix bug #73466 --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index a0f84fefce..6bb8be4261 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2912,6 +2912,8 @@ namespace OOX XLSB::XLWideString str; if(m_oValue.IsInit()) str = m_oValue->m_sText; + else + str = L""; *CellRecord << str; } else From 80ed0318b60d9039896295f1350e180a928819f5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 11 Mar 2025 18:34:32 +0600 Subject: [PATCH 08/23] fix bug #73433 --- .../Format/Logic/Biff_records/FileSharing.h | 2 +- OOXML/XlsxFormat/Workbook/Workbook.cpp | 14 +++++++-- OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 19 ++++++++---- OOXML/XlsxFormat/Workbook/WorkbookPr.h | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 27 ++++++++++------ .../Worksheets/WorksheetChildOther.cpp | 31 ++++++++++++++----- 6 files changed, 69 insertions(+), 26 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h index 080f5a6d5d..0da5c89195 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h @@ -56,7 +56,7 @@ public: static const ElementType type = typeFileSharing; Boolean fReadOnlyRec; - unsigned short wResPassNum; + unsigned short wResPassNum = 0; std::wstring wResPass; _UINT16 iNoResPass; XLUnicodeString stUNUsername; diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 38179fbd5e..e02ba8919d 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -427,8 +427,18 @@ namespace OOX workBookStream->m_FRTWORKBOOK = m_oExtLst->toBinWorkBook(); if (m_oFileSharing.IsInit()) - workBookStream->m_BrtFileSharing = m_oFileSharing->toBin(); - + { + auto sharingVector = m_oFileSharing->toBin(); + if(sharingVector.size() == 2) + { + workBookStream->m_BrtFileSharingIso = sharingVector.at(0); + workBookStream->m_BrtFileSharing = sharingVector.at(1); + } + else if(sharingVector.size() == 1) + { + workBookStream->m_BrtFileSharing = sharingVector.at(0); + } + } return workBookStream; } void CWorkbook::read(const CPath& oPath) diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 0b71a56d26..729b85fdad 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -428,13 +428,13 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } - XLS::BaseObjectPtr CFileSharing::toBin() + std::vector CFileSharing::toBin() { - XLS::BaseObjectPtr objectPtr; + std::vector objectVector; if(m_oSpinCount.IsInit() || m_oAlgorithmName.IsInit() || m_oHashValue.IsInit()) { auto ptr(new XLSB::FileSharingIso); - objectPtr = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr = XLS::BaseObjectPtr{ptr}; if (m_oReadOnlyRecommended.IsInit()) ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); @@ -472,12 +472,18 @@ namespace OOX bytes1, len1); } ptr->ipdPasswordData.rgbSalt.cbLength = len1; + auto ptr1(new XLSB::FileSharing); + ptr1->wResPass = L""; + ptr1->fReadOnlyRec = ptr->fReadOnlyRec; + ptr1->stUserName = ptr->stUserName; + objectVector.push_back(objectPtr); + objectVector.push_back(XLS::BaseObjectPtr{ptr1}); } else { auto ptr(new XLSB::FileSharing); - objectPtr = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr = XLS::BaseObjectPtr{ptr}; if (m_oReadOnlyRecommended.IsInit()) ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); else @@ -490,8 +496,9 @@ namespace OOX ptr->wResPass = m_oPassword.get(); else ptr->wResPass = L""; + objectVector.push_back(objectPtr); } - return objectPtr; + return objectVector; } void CFileSharing::fromBin(XLS::BaseObjectPtr& obj) { diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.h b/OOXML/XlsxFormat/Workbook/WorkbookPr.h index 3f32c987bf..77de4016ec 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.h +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.h @@ -148,7 +148,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); - XLS::BaseObjectPtr toBin(); + std::vector toBin(); virtual EElementType getType() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 6bb8be4261..073a508084 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1130,7 +1130,7 @@ namespace OOX } namespace SharedFormulasRef { - std::unique_ptr> sharedRefsLocations; + std::unique_ptr> sharedRefsLocations; std::unique_ptr>> ArrayRefsLocations; } void CFormula::fromBin(XLS::StreamCacheReaderPtr& reader, XLS::CFRecordPtr& record) @@ -1157,9 +1157,10 @@ namespace OOX rowRef = static_cast(BinFmla.rgce.sequence.begin()->get())->rowXlsb; ColumnRef = static_cast(BinFmla.rgcb.getPtgs().back().get())->col; if(!SharedFormulasRef::sharedRefsLocations) - SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::vector); - SharedFormulasRef::sharedRefsLocations->push_back(XLS::CellRef(rowRef, ColumnRef, true, true)); + SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::map<_UINT32, XLS::CellRef>); m_oSi = (unsigned int)SharedFormulasRef::sharedRefsLocations->size() - 1; + SharedFormulasRef::sharedRefsLocations->emplace(m_oSi->GetValue(), XLS::CellRef(rowRef, ColumnRef, true, true)); + } } auto fmlaRecord = reader->getNextRecord(XLSB::rt_ShrFmla); @@ -2926,7 +2927,7 @@ namespace OOX case SimpleTypes::Spreadsheet::celltypeInlineStr: case SimpleTypes::Spreadsheet::celltypeStr: { - if(m_oValue.IsInit() || m_oRichText.IsInit()) + if(m_oValue.IsInit() || m_oRichText.IsInit() || m_oFormula.IsInit()) { if(!m_oFormula.IsInit()) CellRecord = writer->getNextRecord(XLSB::rt_CellSt); @@ -2936,8 +2937,10 @@ namespace OOX XLSB::XLWideString str; if(m_oValue.IsInit()) str = m_oValue->m_sText; - else + else if(m_oRichText.IsInit()) str = m_oRichText->ToString(); + else + str = L""; *CellRecord << str; } else @@ -2958,15 +2961,19 @@ namespace OOX else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared) { if(!SharedFormulasRef::sharedRefsLocations) - SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::vector); + SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::map<_UINT32, XLS::CellRef>); if(!m_oFormula->m_sText.empty()) { ExtraRecord = writer->getNextRecord(XLSB::rt_ShrFmla); - SharedFormulasRef::sharedRefsLocations->push_back(CellReference); + if(!m_oFormula->m_oSi.IsInit()) + m_oFormula->m_oSi = (_UINT32)SharedFormulasRef::sharedRefsLocations->size(); + SharedFormulasRef::sharedRefsLocations->emplace(m_oFormula->m_oSi->GetValue(), CellReference); + SharedFmlaRef = &CellReference; } - if(m_oFormula->m_oSi.IsInit() && m_oFormula->m_oSi->GetValue() < SharedFormulasRef::sharedRefsLocations->size()) + if(m_oFormula->m_oSi.IsInit() && SharedFormulasRef::sharedRefsLocations->find(m_oFormula->m_oSi->GetValue()) != SharedFormulasRef::sharedRefsLocations->end()) { - SharedFmlaRef = &SharedFormulasRef::sharedRefsLocations->at(m_oFormula->m_oSi->GetValue()); + if(m_oFormula->m_sText.empty()) + SharedFmlaRef = &SharedFormulasRef::sharedRefsLocations->at(m_oFormula->m_oSi->GetValue()); XLS::CellParsedFormula BinFmla(false); //пишем флаги для формулы @@ -4727,6 +4734,8 @@ namespace OOX } if(SharedFormulasRef::sharedRefsLocations) SharedFormulasRef::sharedRefsLocations.reset(); + if(SharedFormulasRef::ArrayRefsLocations) + SharedFormulasRef::ArrayRefsLocations.reset(); } XLS::BaseObjectPtr CSheetData::toBin() { diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 2a01c9e9d5..1de30226d1 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -2812,32 +2812,49 @@ namespace OOX if(m_oOddHeader.IsInit()) dataString = m_oOddHeader->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; if(m_oOddFooter.IsInit()) dataString = m_oOddFooter->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; + if(m_oEvenHeader.IsInit()) dataString = m_oEvenHeader->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; if(m_oEvenFooter.IsInit()) dataString = m_oEvenFooter->m_sText; else - dataString = L""; - *begin << dataString; + dataString.setSize(0xFFFFFFFF); + *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; + if(m_oFirstHeader.IsInit()) dataString = m_oFirstHeader->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; if(m_oFirstFooter.IsInit()) dataString = m_oFirstFooter->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; } writer->storeNextRecord(begin); From c0222c03db36897453b7290ae6a446b5bfdecd0c Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 11 Mar 2025 17:32:14 +0300 Subject: [PATCH 09/23] Fix bug #73485 --- Common/3dParty/html/fetch.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Common/3dParty/html/fetch.py b/Common/3dParty/html/fetch.py index 4a0d3f5068..4107bfc2d1 100644 --- a/Common/3dParty/html/fetch.py +++ b/Common/3dParty/html/fetch.py @@ -25,3 +25,5 @@ if not base.is_dir("katana-parser"): base.replaceInFileUtf8(base_directory + "/katana-parser/src/tokenizer.c", "static inline bool2 katana_is_html_space(char c);", "static inline bool katana_is_html_space(char c);") base.replaceInFileUtf8(base_directory + "/katana-parser/src/parser.c", "katanaget_text(parser->scanner)", "/*katanaget_text(parser->scanner)*/\"error\"") base.replaceInFileUtf8(base_directory + "/katana-parser/src/parser.c", "#define KATANA_PARSER_STRING(literal) (KatanaParserString){", "#define KATANA_PARSER_STRING(literal) {") + # katana may not be able to handle an empty string correctly in some cases (bug#73485) + base.replaceInFileUtf8(base_directory + "/katana-parser/src/foundation.c", "size_t len = strlen(str);", "if (NULL == str)\n return;\n size_t len = strlen(str);") From 20a4bcf7083633073ec22635425b181dcafa8d64 Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 11 Mar 2025 17:32:45 +0300 Subject: [PATCH 10/23] Fix bug #73486 --- Common/3dParty/html/htmltoxhtml.h | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 3fdf63a5d1..68a505e59b 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -19,7 +19,6 @@ static std::string nonbreaking_inline = "|a|abbr|acronym|b|bdo|big|cite|code|df static std::string empty_tags = "|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|"; static std::string preserve_whitespace = "|pre|textarea|script|style|"; static std::string special_handling = "|html|body|"; -static std::string no_entity_sub = ""; //"|style|"; static std::string treat_like_inline = "|p|"; static std::vector html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6", @@ -436,9 +435,25 @@ static void substitute_xml_entities_into_text(std::string& text) replace_all(text, ">", ">"); } +// After running through Gumbo, the values of type "" are replaced with the corresponding code '0x01' +// Since the attribute value does not use control characters (value <= 0x1F), +// then just delete them, otherwise XmlUtils::CXmlLiteReader crashes on them. +// bug#73486 +static void remove_control_symbols(std::string& text) +{ + std::string::iterator itFound = std::find_if(text.begin(), text.end(), [](char chValue){ return chValue <= 0x1F; }); + + while (itFound != text.end()) + { + itFound = text.erase(itFound); + itFound = std::find_if(itFound, text.end(), [](char chValue){ return chValue <= 0x1F; }); + } +} + // Заменяет сущности " в text static void substitute_xml_entities_into_attributes(std::string& text) { + remove_control_symbols(text); substitute_xml_entities_into_text(text); replace_all(text, "\"", """); } @@ -486,7 +501,7 @@ static void build_doctype(GumboNode* node, NSStringUtils::CStringBuilderA& oBuil } } -static void build_attributes(const GumboVector* attribs, bool no_entities, NSStringUtils::CStringBuilderA& atts) +static void build_attributes(const GumboVector* attribs, NSStringUtils::CStringBuilderA& atts) { std::vector arrRepeat; for (size_t i = 0; i < attribs->length; ++i) @@ -532,8 +547,7 @@ static void build_attributes(const GumboVector* attribs, bool no_entities, NSStr std::string qs ="\""; atts.WriteString("="); atts.WriteString(qs); - if(!no_entities) - substitute_xml_entities_into_attributes(sVal); + substitute_xml_entities_into_attributes(sVal); atts.WriteString(sVal); atts.WriteString(qs); } @@ -542,7 +556,6 @@ static void build_attributes(const GumboVector* attribs, bool no_entities, NSStr static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents, bool bCheckValidNode) { std::string key = "|" + get_tag_name(node) + "|"; - bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos; bool keep_whitespace = preserve_whitespace.find(key) != std::string::npos; bool is_inline = nonbreaking_inline.find(key) != std::string::npos; bool is_like_inline = treat_like_inline.find(key) != std::string::npos; @@ -556,8 +569,7 @@ static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA if (child->type == GUMBO_NODE_TEXT) { std::string val(child->v.text.text); - if(!no_entity_substitution) - substitute_xml_entities_into_text(val); + substitute_xml_entities_into_text(val); // Избавление от FF size_t found = val.find_first_of("\014"); @@ -613,7 +625,6 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde std::string closeTag = ""; std::string key = "|" + tagname + "|"; bool is_empty_tag = empty_tags.find(key) != std::string::npos; - bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos; // determine closing tag type if (is_empty_tag) @@ -626,7 +637,7 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde // build attr string const GumboVector* attribs = &node->v.element.attributes; - build_attributes(attribs, no_entity_substitution, oBuilder); + build_attributes(attribs, oBuilder); oBuilder.WriteString(close + ">"); // prettyprint your contents From 6e9500a6e71dbb692b94e040e83c2e9758a24592 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 12 Mar 2025 16:18:35 +0300 Subject: [PATCH 11/23] Fix bug 73493 --- PdfFile/SrcReader/RendererOutputDev.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 4109ae0b24..d6e9ec2e9d 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -474,6 +474,13 @@ namespace PdfReader void RendererOutputDev::restoreState(GfxState* pGState) { RELEASEINTERFACE(m_pSoftMask); + if (m_sStates.empty()) + { // Несбалансированный q/Q - сломанный файл + updateAll(pGState); + UpdateAllClip(pGState); + return; + } + m_pSoftMask = m_sStates.back().pSoftMask; if (c_nGrRenderer == m_lRendererType) { From 89d965283b1fb58380b7602a70b51ed109a35ebe Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 12 Mar 2025 16:23:09 +0300 Subject: [PATCH 12/23] Fix command with empty states --- PdfFile/SrcReader/RendererOutputDev.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index d6e9ec2e9d..a6fced6987 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -2175,7 +2175,7 @@ namespace PdfReader } void RendererOutputDev::clip(GfxState* pGState) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || m_sStates.empty()) return; if (!m_sStates.back().pClip) @@ -2186,7 +2186,7 @@ namespace PdfReader } void RendererOutputDev::eoClip(GfxState* pGState) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || m_sStates.empty()) return; if (!m_sStates.back().pClip) @@ -2197,7 +2197,7 @@ namespace PdfReader } void RendererOutputDev::clipToStrokePath(GfxState* pGState) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || m_sStates.empty()) return; if (!m_sStates.back().pClip) @@ -2251,7 +2251,7 @@ namespace PdfReader } void RendererOutputDev::endTextObject(GfxState* pGState) { - if (m_sStates.back().pTextClip && 4 <= pGState->getRender()) + if (!m_sStates.empty() && m_sStates.back().pTextClip && 4 <= pGState->getRender()) { AddTextClip(pGState, &m_sStates.back()); updateFont(pGState); @@ -2591,9 +2591,13 @@ namespace PdfReader m_pRenderer->get_FontSize(&dTempFontSize); m_pRenderer->get_FontStyle(&lTempFontStyle); // tmpchange - if (!m_sStates.back().pTextClip) - m_sStates.back().pTextClip = new GfxTextClip(); - m_sStates.back().pTextClip->ClipToText(wsTempFontName, wsTempFontPath, dTempFontSize, (int)lTempFontStyle, arrMatrix, wsClipText, dShiftX, /*-fabs(pFont->getFontBBox()[3]) * dTfs + */ dShiftY, 0, 0, 0); + if (!m_sStates.empty()) + { + if (!m_sStates.back().pTextClip) + m_sStates.back().pTextClip = new GfxTextClip(); + m_sStates.back().pTextClip->ClipToText(wsTempFontName, wsTempFontPath, dTempFontSize, (int)lTempFontStyle, arrMatrix, wsClipText, dShiftX, /*-fabs(pFont->getFontBBox()[3]) * dTfs + */ dShiftY, 0, 0, 0); + + } } m_pRenderer->put_FontSize(dOldSize); From c9e3c3452f4f420739d2365fac711a7205bb0f8e Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 12 Mar 2025 17:24:35 +0300 Subject: [PATCH 13/23] fix bug #73500 --- OOXML/Binary/Document/BinWriter/BinWriters.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinWriters.cpp index 85aeee134f..8c6dc07ebe 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinWriters.cpp @@ -5110,16 +5110,16 @@ void BinaryDocumentTableWriter::WriteMathRunContent(OOX::Logic::CMRun* pMRun) int nBreakType = -1; switch (pBr->m_oType.GetValue()) { - case SimpleTypes::brtypeColumn: nBreakType = c_oSerRunType::columnbreak; break; - case SimpleTypes::brtypePage: nBreakType = c_oSerRunType::pagebreak; break; + case SimpleTypes::brtypeColumn: nBreakType = c_oSer_OMathContentType::columnbreak; break; + case SimpleTypes::brtypePage: nBreakType = c_oSer_OMathContentType::pagebreak; break; case SimpleTypes::brtypeTextWrapping: { switch (pBr->m_oClear.GetValue()) { - case SimpleTypes::brclearAll: nBreakType = c_oSerRunType::linebreakClearAll; break; - case SimpleTypes::brclearLeft: nBreakType = c_oSerRunType::linebreakClearLeft; break; - case SimpleTypes::brclearRight: nBreakType = c_oSerRunType::linebreakClearRight; break; - default: nBreakType = c_oSerRunType::linebreak; break; + //case SimpleTypes::brclearAll: nBreakType = c_oSer_OMathContentType::linebreakClearAll; break; + //case SimpleTypes::brclearLeft: nBreakType = c_oSer_OMathContentType::linebreakClearLeft; break; + //case SimpleTypes::brclearRight: nBreakType = c_oSer_OMathContentType::linebreakClearRight; break; + default: nBreakType = c_oSer_OMathContentType::linebreak; break; } }break; From 6e6a71e46dcf2ce29eb1c13daf27783c9dbde0ec Mon Sep 17 00:00:00 2001 From: Green Date: Wed, 12 Mar 2025 18:01:36 +0300 Subject: [PATCH 14/23] Fix bug #73496 --- DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp index 5ae466d3c1..8fa6c9560b 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp @@ -645,6 +645,9 @@ namespace MetaFile //TODO::реализовать при встрече } + if (BrushDataTransform & unBrushDataFlags) + m_oStream.Skip(24); + if (BrushDataPresetColors & unBrushDataFlags) { unsigned int unPositionCount; From 3b67e4ee0ceb598d606b77b9af3879f2368dee37 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Thu, 13 Mar 2025 10:55:16 +0300 Subject: [PATCH 15/23] fix bug #73494 --- MsBinaryFile/PptFile/PPTXWriter/Converter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp index 943564f3c6..baa6bb3eb4 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp @@ -619,6 +619,7 @@ namespace PPT WriteSlides(); WriteNotes(); + m_pShapeWriter->SetRelsGenerator(NULL); } // todo reforming and refactoring! @@ -1544,6 +1545,8 @@ namespace PPT oRels.StartSlide(nLayout, pSlide->m_lNotesID); } + + m_pShapeWriter->SetRelsGenerator(&oRels); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"m_arNotes[nIndexNotes]; oRels.StartNotes(pNotes->m_lSlideID, m_pDocument->m_pNotesMaster != NULL); + + m_pShapeWriter->SetRelsGenerator(&oRels); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L" Date: Thu, 13 Mar 2025 13:57:18 +0600 Subject: [PATCH 16/23] fux bug #73517 --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 073a508084..9a710afbef 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1205,12 +1205,12 @@ namespace OOX auto ColumnPart = static_cast(BinFmla.rgcb.getPtgs().back().get()); if(!SharedFormulasRef::sharedRefsLocations) return; - for(auto i = 0; i size(); i++) + for(const auto& location : *SharedFormulasRef::sharedRefsLocations) { - if(SharedFormulasRef::sharedRefsLocations->at(i).row == rowPart->rowXlsb && - SharedFormulasRef::sharedRefsLocations->at(i).column == ColumnPart->col) + if(location.second.row == rowPart->rowXlsb && + location.second.column == ColumnPart->col) { - m_oSi = i; + m_oSi = location.first; m_oT = SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared; } } From a8d8f44cefd735d16e8ebf706c1ae33f0a6e6e6b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 7 Mar 2025 17:28:54 +0600 Subject: [PATCH 17/23] fix bug #73437 (cherry picked from commit 9cde3dc699d0215e4d0bca9a04d9739a0104a396) --- .../Logic/Biff_structures/StringPtgParser.cpp | 3 -- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 3 ++ OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 2 +- OOXML/XlsbFormat/Biff12_records/BeginSXPI.h | 10 ++-- OOXML/XlsxFormat/Pivot/Pivots.cpp | 53 +++++++++++++------ 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index b6c345b5cc..fa24bcb4b8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -317,9 +317,6 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R [&](XLS::GlobalWorkbookInfo::_xti i) { return i.iSup == ixti; }); - if(pos->itabFirst == pos->itabLast) - rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_VALUE, rgce.getLocation()))); - else rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation()))); } else if(SyntaxPtg::extract_PtgRefErr(it, itEnd)) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 3767dbebdd..6b6534fb16 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -2663,6 +2663,9 @@ void BinaryWorkbookTableWriter::WritePivotCache(OOX::Spreadsheet::CWorkbook& wor { nCurPos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::cache); NSStringUtils::CStringBuilder writer; + writer.WriteString(L""); + if(pivotCacheFile->m_oPivotCashDefinition->m_oRid.IsInit()) + pivotCacheFile->m_oPivotCashDefinition->m_oRid.reset(); pivotCacheFile->m_oPivotCashDefinition->toXML(writer); auto wstringData = writer.GetData(); m_oBcw.m_oStream.WriteStringUtf8(wstringData); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 05a02799c8..f2b4fa8c9c 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -3493,7 +3493,7 @@ int BinaryWorkbookTableReader::ReadPivotCaches(BYTE type, long length, void* poR NSCommon::smart_ptr pFileRecords(oPivotCachesTemp.pRecords); srIdRecords = pDefinitionFile->Add(pFileRecords).ToString(); } - pDefinitionFile->setData(oPivotCachesTemp.pDefinitionData, oPivotCachesTemp.nDefinitionLength, L""); + pDefinitionFile->setData(oPivotCachesTemp.pDefinitionData, oPivotCachesTemp.nDefinitionLength, srIdRecords); NSCommon::smart_ptr pFile(pDefinitionFile); OOX::RId rIdDefinition = m_oWorkbook.Add(pFile); diff --git a/OOXML/XlsbFormat/Biff12_records/BeginSXPI.h b/OOXML/XlsbFormat/Biff12_records/BeginSXPI.h index f2c6ab120d..cb384c31e9 100644 --- a/OOXML/XlsbFormat/Biff12_records/BeginSXPI.h +++ b/OOXML/XlsbFormat/Biff12_records/BeginSXPI.h @@ -51,11 +51,11 @@ namespace XLSB void readFields(XLS::CFRecord& record) override; void writeFields(XLS::CFRecord& record) override; - _INT32 isxvd; - _UINT32 isxvi; - _INT32 isxth; - bool fUnique; - bool fDisplay; + _INT32 isxvd = 0; + _UINT32 isxvi = 0x001000FE; + _INT32 isxth = -1; + bool fUnique = false; + bool fDisplay = false; XLWideString irstUnique; XLWideString irstDisplay; }; diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 2f5530cb29..b484f94540 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -1885,13 +1885,15 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oHier.IsInit()) ptr->isxth = m_oHier.get(); if(m_oName.IsInit()) + { ptr->irstUnique = m_oName.get(); - else - ptr->irstUnique = 0xFFFFFFFF; + ptr->fUnique = true; + } if(m_oCap.IsInit()) + { ptr->irstDisplay = m_oCap.get(); - else - ptr->irstDisplay = 0xFFFFFFFF; + ptr->fDisplay = true; + } return objectPtr; } void CPageField::fromBin(XLS::BaseObjectPtr& obj) @@ -4172,7 +4174,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L"GetValue()); WritingStringNullableAttrInt(L"mappingCount", m_oMappingCount, m_oMappingCount->GetValue()); WritingStringNullableAttrInt(L"numFmtId", m_oNumFmtId, m_oNumFmtId->GetValue()); + WritingStringNullableAttrBool2(L"databaseField", m_oDatabaseField); if(!m_oSharedItems.IsInit() && !m_oFieldGroup.IsInit()) { writer.WriteString(L"/>"); @@ -4406,22 +4408,29 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" void CSharedItems::toXML(NSStringUtils::CStringBuilder& writer) const { writer.WriteString(L"ToString()); WritingStringNullableAttrString(L"maxDate", m_oMaxDate, m_oMaxDate->ToString()); - writer.WriteString(L">"); - + if(!m_arrItems.empty()) + { + WritingStringAttrInt(L"count", (int)m_arrItems.size()); + } + WritingStringNullableAttrBool2(L"longText", m_oLongText); + if(m_arrItems.empty()) + { + writer.WriteString(L"/>"); + return; + } + writer.WriteString(L">"); for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -5127,7 +5136,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" //------------------------------------ void CRangeGroupingProperties::toXML(NSStringUtils::CStringBuilder& writer) const { - writer.WriteString(L"ToString()); WritingStringNullableAttrBool2(L"autoStart", m_oAutoStart); WritingStringNullableAttrBool2(L"autoEnd", m_oAutoEnd); @@ -5835,6 +5844,11 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } WritingStringNullableAttrBool2(L"f", m_oCalculated); WritingStringNullableAttrBool2(L"u", m_oUnused); + if(m_arrItems.empty()) + { + writer.WriteString(L"/>"); + return; + } writer.WriteString(L">"); for ( size_t i = 0; i < m_arrItems.size(); ++i) @@ -5967,6 +5981,11 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } WritingStringNullableAttrBool2(L"f", m_oCalculated); WritingStringNullableAttrBool2(L"u", m_oUnused); + if(m_arrItems.empty()) + { + writer.WriteString(L"/>"); + return; + } writer.WriteString(L">"); for ( size_t i = 0; i < m_arrItems.size(); ++i) @@ -6864,8 +6883,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" void CFieldGroupProperties::toXML(NSStringUtils::CStringBuilder& writer) const { writer.WriteString(L"GetValue()); WritingStringNullableAttrInt(L"par", m_oPar, m_oPar->GetValue()); + WritingStringNullableAttrInt(L"base", m_oBase, m_oBase->GetValue()); writer.WriteString(L">"); if(m_oDiscretePr.IsInit()) From 2652fb4e65d187720f139e61c308435e3980c26a Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 14 Mar 2025 11:19:14 +0300 Subject: [PATCH 18/23] Fix bug 73507 --- DesktopEditor/fontengine/TextShaper.cpp | 2 +- DesktopEditor/fontengine/TextShaper_p.h | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/DesktopEditor/fontengine/TextShaper.cpp b/DesktopEditor/fontengine/TextShaper.cpp index 6efcb547ed..0b2025e5f8 100644 --- a/DesktopEditor/fontengine/TextShaper.cpp +++ b/DesktopEditor/fontengine/TextShaper.cpp @@ -451,7 +451,7 @@ namespace NSShaper CheckUnicodeFaceName(face, family_name, family_name_len); unsigned int nLen1 = (unsigned int)family_name_len; - unsigned int nLen2 = (unsigned int)strlen(face->style_name); + unsigned int nLen2 = (unsigned int)((face->style_name != NULL) ? strlen(face->style_name) : 0); unsigned int nLen = 28 + nLen1 + 1 + nLen2 + 1 + 1 + (int)face->num_fixed_sizes; diff --git a/DesktopEditor/fontengine/TextShaper_p.h b/DesktopEditor/fontengine/TextShaper_p.h index 27ec01cdf9..3c8f0933f1 100644 --- a/DesktopEditor/fontengine/TextShaper_p.h +++ b/DesktopEditor/fontengine/TextShaper_p.h @@ -94,11 +94,14 @@ void CheckUnicodeFaceName(FT_Face pFace, int*& UName, unsigned int& ULen) bool isBadASCII = false; unsigned int face_name_len = 0; - while ('\0' != face_name[face_name_len]) + if (NULL != face_name) { - if ('?' == face_name[face_name_len]) - isBadASCII = true; - ++face_name_len; + while ('\0' != face_name[face_name_len]) + { + if ('?' == face_name[face_name_len]) + isBadASCII = true; + ++face_name_len; + } } if (face_name_len > 6 && From 1346f56d673572e2db8ca9d926dc1f26f3a3149b Mon Sep 17 00:00:00 2001 From: Green Date: Fri, 14 Mar 2025 17:00:37 +0300 Subject: [PATCH 19/23] Fix bug #73487 --- HwpFile/HwpDoc/Common/XMLNode.h | 1 + HwpFile/HwpDoc/Common/XMLReader.cpp | 47 +++++++++++++------ .../HWPElements/HWPRecordBorderFill.cpp | 9 +--- .../HwpDoc/HWPElements/HWPRecordBullet.cpp | 12 ++++- 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/HwpFile/HwpDoc/Common/XMLNode.h b/HwpFile/HwpDoc/Common/XMLNode.h index 4070946113..518ea10488 100644 --- a/HwpFile/HwpDoc/Common/XMLNode.h +++ b/HwpFile/HwpDoc/Common/XMLNode.h @@ -19,6 +19,7 @@ public: }; int ConvertWidthToHWP(const std::wstring& wsValue); +int ConvertHexToInt(const std::string& wsValue, const int& _default = 0x00000000); } #endif // XMLNODEH_H diff --git a/HwpFile/HwpDoc/Common/XMLReader.cpp b/HwpFile/HwpDoc/Common/XMLReader.cpp index 8b022f95b5..82d133855b 100644 --- a/HwpFile/HwpDoc/Common/XMLReader.cpp +++ b/HwpFile/HwpDoc/Common/XMLReader.cpp @@ -17,20 +17,7 @@ bool CXMLNode::GetAttributeBool(const std::wstring& wsName) int CXMLNode::GetAttributeColor(const std::wstring& wsName, const int& _default) { - std::wstring sColor = XmlUtils::CXmlNode::GetAttribute(wsName); - - if (L"none" != sColor) - { - if (L'#' == sColor.front()) - sColor.erase(0, 1); - - if (sColor.length() < 6) - return _default; - - return std::stoi(sColor.substr(0, 6), nullptr, 16); - } - - return _default; + return ConvertHexToInt(XmlUtils::CXmlNode::GetAttributeA(wsName), _default); } CXMLNode CXMLNode::GetChild(const std::wstring& wsName) @@ -98,4 +85,36 @@ int ConvertWidthToHWP(const std::wstring& wsValue) return 0; } + +int ConvertHexToInt(const std::string& wsValue, const int& _default) +{ + if (wsValue.empty() || "none" == wsValue) + return _default; + + std::string::const_iterator itStart = wsValue.cbegin(); + + if ('#' == *itStart) + ++itStart; + + if (wsValue.cend() - itStart < 6) + return _default; + + itStart = wsValue.cend() - 6; + + int nResult = 0; + + while (itStart != wsValue.cend()) + { + if ('0' <= *itStart && *itStart <= '9') + nResult = (nResult << 4) | (*itStart++ - '0'); + else if ('A' <= *itStart && *itStart <= 'F') + nResult = (nResult << 4) | (*itStart++ - 'A' + 10); + else if ('a' <= *itStart && *itStart <= 'f') + nResult = (nResult << 4) | (*itStart++ - 'a' + 10); + else + return _default; + } + + return nResult; +} } diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp index 2569ee8618..503586237b 100644 --- a/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp @@ -62,12 +62,7 @@ EColorFillPattern GetColorFillPattern(int nPattern) void TBorder::ReadFromNode(CXMLNode& oNode) { m_eStyle = GetLineStyle2(oNode.GetAttribute(L"type")); - - HWP_STRING sColor = std::regex_replace(oNode.GetAttribute(L"color"), std::wregex(L"^#([0-9A-Fa-f]+)$"), L"$1"); - - if (L"none" != sColor) - m_nColor = std::stoi(sColor, 0, 16); - + m_nColor = oNode.GetAttributeColor(L"color"); m_chWidth = (HWP_BYTE)ConvertWidthToHWP(oNode.GetAttribute(L"width")); } @@ -199,7 +194,7 @@ void CFill::ReadGradation(CXMLNode& oNode) m_arColors.resize(arChilds.size()); for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex) - m_arColors[unIndex] = std::stoi(std::regex_replace(arChilds[unIndex].GetText(), std::wregex(L"\\D"), L""), 0, 16); + m_arColors[unIndex] = ConvertHexToInt(arChilds[unIndex].GetTextA()); } void CFill::ReadImgBrush(CXMLNode& oNode) diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp index 877ebae315..91ee5db3a3 100644 --- a/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp @@ -48,8 +48,16 @@ CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, int nTagNum, int nLeve CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) : CHWPRecord(EHWPTag::HWPTAG_BULLET, 0, 0), m_pParent(&oDocInfo) { - m_chBulletChar = oNode.GetAttribute(L"char").at(0); - m_chCheckBulletChar = oNode.GetAttribute(L"checkedChar").at(0); + std::wstring wsAttributeValue = oNode.GetAttribute(L"char"); + + if (!wsAttributeValue.empty()) + m_chBulletChar = wsAttributeValue.at(0); + + wsAttributeValue = oNode.GetAttribute(L"checkedChar"); + + if (!wsAttributeValue.empty()) + m_chCheckBulletChar = wsAttributeValue.at(0); + m_nBulletImage = oNode.GetAttributeInt(L"useImage"); for (CXMLNode& oChild : oNode.GetChilds()) From 6fe0f2828e9b796b90d0b850dad624f9845ba697 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 14 Mar 2025 21:53:47 +0600 Subject: [PATCH 20/23] Fix bug #73467 --- OOXML/Common/SimpleTypes_Spreadsheet.cpp | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.cpp b/OOXML/Common/SimpleTypes_Spreadsheet.cpp index 24d91f3e28..fb2b990041 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.cpp +++ b/OOXML/Common/SimpleTypes_Spreadsheet.cpp @@ -589,7 +589,7 @@ namespace SimpleTypes this->m_eValue = underlineDouble; else if(L"doubleAccounting" == sValue) this->m_eValue = underlineDoubleAccounting; - else if(L"none" == sValue) + else if(L"none" == sValue || L"0" == sValue) this->m_eValue = underlineNone; else if(L"single" == sValue) this->m_eValue = underlineSingle; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 9a710afbef..f898cee414 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1158,7 +1158,7 @@ namespace OOX ColumnRef = static_cast(BinFmla.rgcb.getPtgs().back().get())->col; if(!SharedFormulasRef::sharedRefsLocations) SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::map<_UINT32, XLS::CellRef>); - m_oSi = (unsigned int)SharedFormulasRef::sharedRefsLocations->size() - 1; + m_oSi = (unsigned int)SharedFormulasRef::sharedRefsLocations->size(); SharedFormulasRef::sharedRefsLocations->emplace(m_oSi->GetValue(), XLS::CellRef(rowRef, ColumnRef, true, true)); } @@ -4369,7 +4369,7 @@ namespace OOX } bool CRow::compressCell(CCell* pCell) { - if(!pCell->m_oValue.IsInit() && !m_arrItems.empty()) + if(!pCell->m_oValue.IsInit() && !pCell->m_oFormula.IsInit() && !m_arrItems.empty()) { auto prevCell = m_arrItems.back(); if(!prevCell->m_oRepeated.IsInit()) From 4f4f61bb1918e0a0a6d79827227ae5129443564f Mon Sep 17 00:00:00 2001 From: Green Date: Sat, 15 Mar 2025 01:04:27 +0300 Subject: [PATCH 21/23] Fix bug #73483 --- Common/OfficeFileFormatChecker2.cpp | 248 +++++++++++++++++++++++----- 1 file changed, 206 insertions(+), 42 deletions(-) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index e1ea7b2d88..695efb0628 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -1159,58 +1159,222 @@ bool COfficeFileFormatChecker::isOnlyOfficeFormatFile(const std::wstring &fileNa } return false; } -bool COfficeFileFormatChecker::isMacFormatFile(const std::wstring& fileName) + +struct TIWAField +{ + size_t m_unStart; + size_t m_unEnd; + unsigned m_uIndex; + unsigned m_unWireType; + uint64_t m_oValue; +}; + +bool ReadUVar(BYTE* pBuffer, size_t unEndPos, size_t& unPos, uint64_t& unValue) +{ + std::vector arBytes; + arBytes.reserve(8); + + unValue = 0; + + bool bNext = true; + while (unPos < unEndPos && bNext) + { + const unsigned char c = pBuffer[unPos++]; + arBytes.push_back((unsigned char)(c & ~0x80)); + bNext = c & 0x80; + } + + if (bNext && unPos == unEndPos) + return false; + + for (std::vector::const_reverse_iterator it = arBytes.rbegin(); it != arBytes.rend(); ++it) + { + if (std::numeric_limits::max() >> 7 < unValue || + std::numeric_limits::max() - (unValue << 7) < *it) // overflow + return false; + + unValue = (unValue << 7) + *it; + } + + return true; +} + +bool ReadIWAField(BYTE* pBuffer, size_t unEndPos, size_t& unPos, TIWAField& oIWAField) +{ + if (NULL == pBuffer || unPos + 2 > unEndPos) + return false; + + unsigned uSpec; + + uSpec = (unsigned)pBuffer[unPos++]; + oIWAField.m_unWireType = uSpec & 0x7; + + oIWAField.m_unStart = unPos; + + switch (oIWAField.m_unWireType) + { + case 0: + { + if (!ReadUVar(pBuffer, unEndPos, unPos, oIWAField.m_oValue)) + return false; + + break; + } + case 1: + { + unPos += 4; + break; + } + case 2: + { + uint64_t unLen; + if (!ReadUVar(pBuffer, unEndPos, unPos, unLen) || unPos + unLen > unEndPos) + return false; + + oIWAField.m_unStart = unPos; + unPos += unLen; + break; + } + case 5: + { + unPos += 2; + break; + } + default: + return false; + } + + oIWAField.m_unEnd = unPos; + oIWAField.m_uIndex = uSpec >> 3; + + return true; +} + +bool DetectIWorkFormat(const std::wstring& fileName, int &nType) { COfficeUtils OfficeUtils(NULL); - ULONG nBufferSize = 0; + ULONG unSize = 0; BYTE* pBuffer = NULL; - HRESULT hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Document.iwa", &pBuffer, nBufferSize); - if (hresult == S_OK && pBuffer != NULL) + HRESULT hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Document.iwa", &pBuffer, unSize); + + if (hresult != S_OK || NULL == pBuffer) + return false; + + #define CLEAR_BUFFER_AND_RETURN(return_value)\ + do{\ + delete[] pBuffer;\ + return return_value;\ + }while(false) + + if (unSize < 13) + CLEAR_BUFFER_AND_RETURN(false); + + size_t uPos = 6; + + for (; uPos < 12; ++uPos) { - nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES; - - delete[] pBuffer; - pBuffer = NULL; - - hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Slide.iwa", &pBuffer, nBufferSize); - if (hresult == S_OK && pBuffer != NULL) + if (0x08 == pBuffer[uPos] && 0x01 == pBuffer[uPos + 1]) { - delete[] pBuffer; - pBuffer = NULL; - - nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY; - return true; + --uPos; + break; } - hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Tables/DataList.iwa", &pBuffer, nBufferSize); - if (hresult == S_OK && pBuffer != NULL) - { - delete[] pBuffer; - pBuffer = NULL; - - nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS; - return true; - } - std::wstring::size_type nExtPos = fileName.rfind(L'.'); - std::wstring sExt = L"unknown"; - - if (nExtPos != std::wstring::npos) - sExt = fileName.substr(nExtPos); - - std::transform(sExt.begin(), sExt.end(), sExt.begin(), tolower); - - if (0 == sExt.compare(L".pages")) - nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES; - else if (0 == sExt.compare(L".numbers")) - nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS; - else if (0 == sExt.compare(L".key")) - nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY; - - return true; } - return false; + + if (12 == uPos) + CLEAR_BUFFER_AND_RETURN(false); + + uint64_t unHeaderLen; + if (!ReadUVar(pBuffer, unSize, uPos, unHeaderLen)) + CLEAR_BUFFER_AND_RETURN(false); + + const size_t uStartPos = uPos; + + if (unHeaderLen < 8 || unSize < unHeaderLen + uStartPos) + CLEAR_BUFFER_AND_RETURN(false); + + uPos += 2; + + TIWAField oMessageField; + + if (!ReadIWAField(pBuffer, uStartPos + unHeaderLen, uPos, oMessageField) || 2 != oMessageField.m_unWireType || + 2 != oMessageField.m_uIndex) + CLEAR_BUFFER_AND_RETURN(false); + + size_t uSubPos = oMessageField.m_unStart; + TIWAField oField; + + if (!ReadIWAField(pBuffer, oMessageField.m_unEnd, uSubPos, oField) || 0 != oField.m_unWireType || + 1 != oField.m_uIndex) + CLEAR_BUFFER_AND_RETURN(false); + + switch (oField.m_oValue) + { + case 1: + { + uint32_t unDataLen = 0; + + TIWAField oTempField; + if (ReadIWAField(pBuffer, oMessageField.m_unEnd, uSubPos, oTempField) && + ReadIWAField(pBuffer, oMessageField.m_unEnd, uSubPos, oTempField) && 0 == oTempField.m_unWireType && + 3 == oTempField.m_uIndex) + unDataLen += oTempField.m_oValue; + + size_t unTempPos = uStartPos + unHeaderLen; + + // keynote: presentation ref in 2 + // number: sheet ref in 1 + if (ReadIWAField(pBuffer, uStartPos + unDataLen, unTempPos, oTempField) && + (2 != oTempField.m_unWireType || 1 != oTempField.m_uIndex || oTempField.m_unEnd - oTempField.m_unStart < 2)) + { + nType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY; + CLEAR_BUFFER_AND_RETURN(true); + } + else if (ReadIWAField(pBuffer, uStartPos + unDataLen, unTempPos, oTempField) && + (2 != oTempField.m_unWireType || 2 != oTempField.m_uIndex || oTempField.m_unEnd - oTempField.m_unStart < 2)) + { + nType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS; + CLEAR_BUFFER_AND_RETURN(true); + } + + break; + } + case 10000: + { + nType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES; + CLEAR_BUFFER_AND_RETURN(true); + } + } + + CLEAR_BUFFER_AND_RETURN(false); } + +bool COfficeFileFormatChecker::isMacFormatFile(const std::wstring& fileName) +{ + if (DetectIWorkFormat(fileName, nFileType)) + return true; + + std::wstring::size_type nExtPos = fileName.rfind(L'.'); + std::wstring sExt = L"unknown"; + + if (nExtPos != std::wstring::npos) + sExt = fileName.substr(nExtPos); + + std::transform(sExt.begin(), sExt.end(), sExt.begin(), tolower); + + if (0 == sExt.compare(L".pages")) + nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES; + else if (0 == sExt.compare(L".numbers")) + nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS; + else if (0 == sExt.compare(L".key")) + nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY; + else + return false; + + return true; +} + bool COfficeFileFormatChecker::isOpenOfficeFormatFile(const std::wstring &fileName, std::wstring &documentID) { documentID.clear(); From 2ab94263f2e2f91f448cfea05cf3e2af0450d33d Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Mon, 17 Mar 2025 15:29:49 +0400 Subject: [PATCH 22/23] Remove `lib` directory --- .../doctrenderer/docbuilder.python/src/docbuilder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index a09d1f4afd..bf8f6186a0 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -609,14 +609,14 @@ class FileTypes: PNG = _IMAGE_MASK + 0x0005 BMP = _IMAGE_MASK + 0x0008 -builder_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib') +builder_path = os.path.dirname(os.path.realpath(__file__)) _loadLibrary(builder_path) CDocBuilder.Initialize(builder_path) def registerLibrary(license_path): - docbuilder_bin = os.path.dirname(os.path.realpath(__file__)) + "/lib/docbuilder" + docbuilder_bin = os.path.join(builder_path, "docbuilder") if ("windows" == platform.system().lower()): docbuilder_bin += ".exe" - return subprocess.call([docbuilder_bin, "-register", license_path], stderr=subprocess.STDOUT, shell=True) + return subprocess.call([docbuilder_bin, "-register", license_path], stderr=subprocess.STDOUT, shell=True) atexit.register(CDocBuilder.Dispose) From 72ee82211d317069bf2dfdb3226d2c2ad8aa128d Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Mon, 17 Mar 2025 15:36:03 +0400 Subject: [PATCH 23/23] Add note --- DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index bf8f6186a0..b097c55a2e 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -609,6 +609,7 @@ class FileTypes: PNG = _IMAGE_MASK + 0x0005 BMP = _IMAGE_MASK + 0x0008 +# NOTE: do not change builder_path manually! builder_path = os.path.dirname(os.path.realpath(__file__)) _loadLibrary(builder_path) CDocBuilder.Initialize(builder_path)