sw/qa/extras/rtfexport/data/substream-reusing-parent-encoding.rtf |    5 +
 sw/qa/extras/rtfexport/rtfexport8.cxx                             |   27 
++++++++++
 sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx                 |    3 +
 3 files changed, 35 insertions(+)

New commits:
commit 70f3d70044c77f3d62ee740c0af705ec9998b44f
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sat Jun 14 19:43:00 2025 +0500
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue Jun 17 11:37:01 2025 +0200

    tdf#155835: copy current encoding into newly created substream state
    
    RTF is defined to copy the current state whenever a new destination
    appears. Before the change, RTFDocumentImpl::resolveSubstream didn't
    keep its current encoding in the child RTFDocumentImpl; that led to
    its m_aDefaultState having the default RTL_TEXTENCODING_MS_1252; and
    when the destination didn't define its own encoding (e.g. using N),
    the non-ASCII octets were treated incorrectly.
    
    I don't know if other members of m_aDefaultState should be set to
    parent's current state. In theory, this could even be a full copy.
    
    Change-Id: I6f53bfd519598b5a4b5cd1f04f13575a5aa1fa2f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186499
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    (cherry picked from commit 41b1542326d4924730ffad51cd01399f3b6ca237)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186545
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>
    (cherry picked from commit 66a3d04b5d5e1b968557c0eb656753a77831a87e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186562
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sw/qa/extras/rtfexport/data/substream-reusing-parent-encoding.rtf 
b/sw/qa/extras/rtfexport/data/substream-reusing-parent-encoding.rtf
new file mode 100644
index 000000000000..897de277fb63
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/substream-reusing-parent-encoding.rtf
@@ -0,0 +1,5 @@
+{ tf1nsi
+{onttbl{0swisscharset204prq2 Arial Cyr;}}
+{\stylesheet{\*+0s16 �������� ����� +}
\ No newline at end of file
diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx 
b/sw/qa/extras/rtfexport/rtfexport8.cxx
index ef0a32c374e1..c2e4d04ca150 100644
--- a/sw/qa/extras/rtfexport/rtfexport8.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport8.cxx
@@ -678,6 +678,33 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf166620)
     }
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testTdf155835)
+{
+    // Given a document with an encoding defined for a specific font that is 
defined for a main
+    // text run, which has a footnote substream; but the substream doesn't 
specify own font, and
+    // therefore depends on the parent current state:
+    createSwDoc("substream-reusing-parent-encoding.rtf");
+    {
+        auto xSupplier = mxComponent.queryThrow<text::XFootnotesSupplier>();
+        auto xFootnotes = xSupplier->getFootnotes();
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xFootnotes->getCount());
+        auto xEndnoteText = 
xFootnotes->getByIndex(0).queryThrow<text::XText>();
+        // Check that the footnote encoding was correct; without the fix, this 
would fail with
+        // - Expected: Текст сноски
+        // - Actual  : Òåêñò ñíîñêè
+        CPPUNIT_ASSERT_EQUAL(u"Текст сноски"_ustr, xEndnoteText->getString());
+    }
+    // Check export, too
+    saveAndReload(mpFilter);
+    {
+        auto xSupplier = mxComponent.queryThrow<text::XFootnotesSupplier>();
+        auto xFootnotes = xSupplier->getFootnotes();
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xFootnotes->getCount());
+        auto xEndnoteText = 
xFootnotes->getByIndex(0).queryThrow<text::XText>();
+        CPPUNIT_ASSERT_EQUAL(u"Текст сноски"_ustr, xEndnoteText->getString());
+    }
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx 
b/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
index a4dd2ac93cba..82e01d409183 100644
--- a/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
+++ b/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
@@ -400,6 +400,9 @@ void RTFDocumentImpl::resolveSubstream(std::size_t nPos, Id 
nId, OUString const&
         pImpl->m_aAuthorInitials = m_aAuthorInitials;
         m_aAuthorInitials.clear();
     }
+    // Copy current encoding. Do we need to copy more state?
+    pImpl->m_aDefaultState.setCurrentEncoding(
+        (m_aStates.empty() ? m_aDefaultState : 
m_aStates.top()).getCurrentEncoding());
     pImpl->m_nDefaultFontIndex = m_nDefaultFontIndex;
     pImpl->m_pStyleTableEntries = m_pStyleTableEntries;
     pImpl->Strm().Seek(nPos);

Reply via email to