external/liborcus/UnpackedTarball_liborcus.mk | 1 external/liborcus/win_path_utf16.patch | 33 ------------ sc/source/filter/orcus/orcusfiltersimpl.cxx | 68 ++++++++++++++++---------- 3 files changed, 44 insertions(+), 58 deletions(-)
New commits: commit f1ad49f9989f163c7c103df3f0513f6608801858 Author: Kohei Yoshida <kohei.yosh...@collabora.com> AuthorDate: Fri Jul 11 22:47:02 2025 -0400 Commit: Kohei Yoshida <kohei.yosh...@collabora.com> CommitDate: Sat Jul 12 06:37:47 2025 +0200 tdf#150247: Copy the content to temp file and use its path Hopefully this is a more reliable fix for loading a file that contains a unicode segment on Windows. Change-Id: Iabe3ea849858290e782123840d8756ed07159dec Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187762 Reviewed-by: Kohei Yoshida <ko...@libreoffice.org> Tested-by: Jenkins diff --git a/external/liborcus/UnpackedTarball_liborcus.mk b/external/liborcus/UnpackedTarball_liborcus.mk index 8bf355a1abed..6c1b846f23a0 100644 --- a/external/liborcus/UnpackedTarball_liborcus.mk +++ b/external/liborcus/UnpackedTarball_liborcus.mk @@ -21,7 +21,6 @@ $(eval $(call gb_UnpackedTarball_add_patches,liborcus,\ ifeq ($(OS),WNT) $(eval $(call gb_UnpackedTarball_add_patches,liborcus,\ external/liborcus/windows-constants-hack.patch \ - external/liborcus/win_path_utf16.patch \ )) endif diff --git a/external/liborcus/win_path_utf16.patch b/external/liborcus/win_path_utf16.patch deleted file mode 100644 index 0a6781e728b3..000000000000 --- a/external/liborcus/win_path_utf16.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff --git a/src/parser/stream.cpp b/src/parser/stream.cpp -index 00395f59ff25..8f385fb8965a 100644 ---- a/src/parser/stream.cpp -+++ b/src/parser/stream.cpp -@@ -147,6 +147,14 @@ std::tuple<std::string_view, size_t, size_t> find_line_with_offset(std::string_v - return std::make_tuple(line, line_num, offset_on_line); - } - -+#ifdef _WIN32 -+std::wstring to_wstring(std::string_view s) -+{ -+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conversion; -+ return conversion.from_bytes(s.data(), s.data() + s.size()); -+} -+#endif -+ - } // anonymous namespace - - struct file_content::impl -@@ -162,8 +170,13 @@ struct file_content::impl - impl() : content_size(0), content(nullptr) {} - - impl(std::string_view filepath) : -+#ifdef _WIN32 -+ content_size(fs::file_size(to_wstring(filepath))), -+ mapped_file(to_wstring(filepath).c_str(), bip::read_only), -+#else - content_size(fs::file_size(std::string{filepath}.c_str())), - mapped_file(std::string{filepath}.c_str(), bip::read_only), -+#endif - mapped_region(mapped_file, bip::read_only, 0, content_size), - content(nullptr) - { diff --git a/sc/source/filter/orcus/orcusfiltersimpl.cxx b/sc/source/filter/orcus/orcusfiltersimpl.cxx index 8ea4faebf9c6..8b8023545186 100644 --- a/sc/source/filter/orcus/orcusfiltersimpl.cxx +++ b/sc/source/filter/orcus/orcusfiltersimpl.cxx @@ -12,6 +12,7 @@ #include <tokenarray.hxx> #include <osl/thread.hxx> +#include <osl/file.hxx> #include <sfx2/docfile.hxx> #include <sfx2/frame.hxx> #include <sfx2/sfxsids.hrc> @@ -29,6 +30,37 @@ using namespace com::sun::star; namespace { +/** + * Stream copied to a temporary file with a filepath. + */ +class CopiedTempStream +{ + utl::TempFileNamed maTemp; + +public: + CopiedTempStream(SvStream& rSrc) + { + maTemp.EnableKillingFile(); + SvStream* pDest = maTemp.GetStream(StreamMode::WRITE); + + rSrc.Seek(0); + + const std::size_t nReadBuffer = 1024 * 32; + std::size_t nRead = 0; + + do + { + char pData[nReadBuffer]; + nRead = rSrc.ReadBytes(pData, nReadBuffer); + pDest->WriteBytes(pData, nRead); + } while (nRead == nReadBuffer); + + maTemp.CloseStream(); + } + + OString getFileName() const { return maTemp.GetFileName().toUtf8(); } +}; + uno::Reference<task::XStatusIndicator> getStatusIndicator(const SfxMedium& rMedium) { uno::Reference<task::XStatusIndicator> xStatusIndicator; @@ -41,29 +73,15 @@ uno::Reference<task::XStatusIndicator> getStatusIndicator(const SfxMedium& rMedi bool loadFileContent(SfxMedium& rMedium, orcus::iface::import_filter& filter) { - // write the content to a temp file - utl::TempFileNamed aTemp; - aTemp.EnableKillingFile(); - SvStream* pDest = aTemp.GetStream(StreamMode::WRITE); - SvStream* pSrc = rMedium.GetInStream(); - pSrc->Seek(0); - const std::size_t nReadBuffer = 1024 * 32; - std::size_t nRead = 0; - - do - { - char pData[nReadBuffer]; - nRead = pSrc->ReadBytes(pData, nReadBuffer); - pDest->WriteBytes(pData, nRead); - } while (nRead == nReadBuffer); - - aTemp.CloseStream(); + if (!pSrc) + return false; try { // memory-map the temp file and start the import - orcus::file_content input(aTemp.GetFileName().toUtf8()); + CopiedTempStream aTemp(*pSrc); + orcus::file_content input(aTemp.getFileName()); filter.read_stream(input.str()); } catch (const std::exception& e) @@ -112,12 +130,14 @@ bool ScOrcusFiltersImpl::importODS_Styles(ScDocument& rDoc, OUString& aPath) con { try { -#if defined _WIN32 - OString aPath8 = OUStringToOString(aPath, RTL_TEXTENCODING_UTF8); -#else - OString aPath8 = OUStringToOString(aPath, osl_getThreadTextEncoding()); -#endif - orcus::file_content content(aPath8); + OUString aURL; + if (osl::FileBase::getFileURLFromSystemPath(aPath, aURL) != osl::FileBase::E_None) + return false; + + SvFileStream aSrc(aURL, StreamMode::READ); + CopiedTempStream aTemp(aSrc); + orcus::file_content content(aTemp.getFileName()); + ScOrcusFactory aFactory(rDoc); ScOrcusStyles aStyles(aFactory); orcus::import_ods::read_styles(content.str(), &aStyles);