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);

Reply via email to