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{0swisscharset204prq2 Arial Cyr;}} +{\stylesheet{\*+0s16 �������� ����� +} \ 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);