sw/qa/extras/rtfexport/data/text-change-tracking.rtf | 17 ++++++++++++++ sw/qa/extras/rtfexport/rtfexport8.cxx | 23 +++++++++++++++++++ sw/source/filter/ww8/rtfattributeoutput.cxx | 19 ++++++++++----- sw/source/filter/ww8/rtfattributeoutput.hxx | 3 -- sw/source/filter/ww8/rtfexport.cxx | 14 ++++++++++- sw/source/filter/ww8/rtfexport.hxx | 10 ++++++++ 6 files changed, 76 insertions(+), 10 deletions(-)
New commits: commit 63b46c2136d95960bab30a15e27bc94e6eefe6e6 Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Mon Jun 17 11:51:41 2024 +0200 Commit: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> CommitDate: Thu Jun 20 09:22:30 2024 +0200 rtf: Don't export changes author/date when in privacy mode Change-Id: Id8f8dea4563df3cfb0ea9009783886bdabf91b11 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168996 Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> Tested-by: Jenkins diff --git a/sw/qa/extras/rtfexport/data/text-change-tracking.rtf b/sw/qa/extras/rtfexport/data/text-change-tracking.rtf new file mode 100644 index 000000000000..c6f72ceeade5 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/text-change-tracking.rtf @@ -0,0 +1,17 @@ +{ tf1nsi\deff3deflang1025 +{onttbl{0romanprq2charset0 Liberat;}{1romanprq2charset2 Symbol;}{2 swissprq2charset0 Arial;}{3romanprq2charset0 Liberation Serif{\*alt Times New Roman};}{4swissprq2charset0 Liberation Sans{\*alt Arial};}{5 nilprq2charset0 Noto Sans CJK SC;}{6nilprq2charset0 Noto Sans Devanagari;}{7swissprq0charset0 Noto Sans Devanagari;}} +{+{\stylesheet{\s0\snext0 tlchf6fs24lang1081 \ltrch\lang1031\langfe2052\hichf3\loch\widctlpar\hyphpar0spalpha\ltrpar+{\*+{\s16\sbasedon0\snext17 tlchf6fs28 \ltrch\hichf4\loch\sb240\sa120\keepn4s28\dbchf5 Heading;} +{\s17\sbasedon0\snext17\loch\sl276\slmult1\sb0\sa140 Body Text;} +{\s18\sbasedon17\snext18 tlchf7 \ltrch List;} +{\s19\sbasedon0\snext19 tlchf7fs24i \ltrch\loch\sb120\sa120 olines24\i caption;} +{\s20\sbasedon0\snext20 tlchf7 \ltrch\loch oline Index;} +}{\* evtbl {Unknown;}{Max Mustermann;}} +{\*\generator LibreOfficeDev/25.2.0.0.alpha0$Linux_X86_64 LibreOffice_project/c558004906bfaef6d1983e09473e4c236de730d3}{\info{+\hyphauto1 iewscale130 evisionsormshade obrkwrptbl\paperh16838\paperw11906\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sftnnar\saftnnrlc\sectunlocked1\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134 tnbjtnstart1tnrstconttnnaretftnrstcontftnstart1ftnnrlc +{\*tnsep+Test}{ evised evauth1 evdttm667323072 \loch +Deleted} +\par } \ No newline at end of file diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx b/sw/qa/extras/rtfexport/rtfexport8.cxx index 1ed6eee0ded4..3f013605d625 100644 --- a/sw/qa/extras/rtfexport/rtfexport8.cxx +++ b/sw/qa/extras/rtfexport/rtfexport8.cxx @@ -482,6 +482,29 @@ CPPUNIT_TEST_FIXTURE(Test, testNotesAuthorDate) CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aRtfContent.indexOf("\atndate", 0)); } +CPPUNIT_TEST_FIXTURE(Test, testChangesAuthor) +{ + createSwDoc("text-change-tracking.rtf"); + + auto pBatch(comphelper::ConfigurationChanges::create()); + // Remove all personal info + officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(true, pBatch); + pBatch->commit(); + saveAndReload(mpFilter); + + SvStream* pStream = maTempFile.GetStream(StreamMode::READ); + CPPUNIT_ASSERT(pStream); + OString aRtfContent(read_uInt8s_ToOString(*pStream, pStream->TellEnd())); + + // Make sure user name was anonymized + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), + aRtfContent.indexOf("\revtbl {Unknown;}{Max Mustermann;}", 0)); + CPPUNIT_ASSERT(aRtfContent.indexOf("\revtbl {Author1;}{Author2;}", 0) >= 0); + + // Make sure no date is set + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aRtfContent.indexOf("\revdttmdel", 0)); +} + CPPUNIT_TEST_FIXTURE(Test, testTdf158982) { auto verify = [this]() { diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 22a76de4a109..07063fb4d5c5 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -626,13 +626,19 @@ void RtfAttributeOutput::Redline(const SwRedlineData* pRedline) if (!pRedline) return; + bool bRemoveCommentAuthorDates + = SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo) + && !SvtSecurityOptions::IsOptionSet( + SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo); + if (pRedline->GetType() == RedlineType::Insert) { m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVISED); m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTH); m_aRun->append(static_cast<sal_Int32>( m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())))); - m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM); + if (!bRemoveCommentAuthorDates) + m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM); } else if (pRedline->GetType() == RedlineType::Delete) { @@ -640,9 +646,11 @@ void RtfAttributeOutput::Redline(const SwRedlineData* pRedline) m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL); m_aRun->append(static_cast<sal_Int32>( m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())))); - m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL); + if (!bRemoveCommentAuthorDates) + m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL); } - m_aRun->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()))); + if (!bRemoveCommentAuthorDates) + m_aRun->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()))); m_aRun->append(' '); } @@ -4092,10 +4100,10 @@ void RtfAttributeOutput::PostitField(const SwField* pField) return; } OUString sAuthor(bRemoveCommentAuthorDates - ? "Author" + OUString::number(mpAuthorIDs->GetInfoID(rPField.GetPar1())) + ? "Author" + OUString::number(m_rExport.GetInfoID(rPField.GetPar1())) : rPField.GetPar1()); OUString sInitials(bRemoveCommentAuthorDates - ? "A" + OUString::number(mpAuthorIDs->GetInfoID(rPField.GetPar1())) + ? "A" + OUString::number(m_rExport.GetInfoID(rPField.GetPar1())) : rPField.GetInitials()); m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " "); m_aRunText->append(OUStringToOString(sInitials, m_rExport.GetCurrentEncoding())); @@ -4169,7 +4177,6 @@ RtfAttributeOutput::RtfAttributeOutput(RtfExport& rExport) , m_nParaBeforeSpacing(0) , m_bParaAfterAutoSpacing(false) , m_nParaAfterSpacing(0) - , mpAuthorIDs(new SvtSecurityMapPersonalInfo) { } diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index 7642918332ff..8ba84bed6055 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -666,9 +666,6 @@ private: editeng::WordPageMargins m_aPageMargins; - /// map authors to remove personal info - std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs; - public: explicit RtfAttributeOutput(RtfExport& rExport); diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx index 88a3086c6dfc..4eb04d4f8bbf 100644 --- a/sw/source/filter/ww8/rtfexport.cxx +++ b/sw/source/filter/ww8/rtfexport.cxx @@ -56,6 +56,7 @@ #include <svtools/rtfkeywd.hxx> #include <filter/msfilter/rtfutil.hxx> #include <unotools/docinfohelper.hxx> +#include <unotools/securityoptions.hxx> #include <xmloff/odffields.hxx> #include <o3tl/string_view.hxx> #include <osl/diagnose.h> @@ -272,6 +273,11 @@ void RtfExport::WriteRevTab() GetRedline(SW_MOD()->GetRedlineAuthor(pRedl->GetAuthor())); } + bool bRemoveCommentAuthorDates + = SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo) + && !SvtSecurityOptions::IsOptionSet( + SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo); + // Now write the table Strm() .WriteChar('{') @@ -283,7 +289,12 @@ void RtfExport::WriteRevTab() const OUString* pAuthor = GetRedline(i); Strm().WriteChar('{'); if (pAuthor) - Strm().WriteOString(msfilter::rtfutil::OutString(*pAuthor, m_eDefaultEncoding)); + { + OUString sAuthor(bRemoveCommentAuthorDates + ? "Author" + OUString::number(GetInfoID(*pAuthor)) + : *pAuthor); + Strm().WriteOString(msfilter::rtfutil::OutString(sAuthor, m_eDefaultEncoding)); + } Strm().WriteOString(";}"); } Strm().WriteChar('}').WriteOString(SAL_NEWLINE_STRING); @@ -1155,6 +1166,7 @@ RtfExport::RtfExport(RtfExportFilter* pFilter, SwDoc& rDocument, , m_eCurrentEncoding(m_eDefaultEncoding) , m_bRTFFlySyntax(false) , m_nCurrentNodeIndex(0) + , mpAuthorIDs(new SvtSecurityMapPersonalInfo) { m_bExportModeRTF = true; // the attribute output for the document diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx index 1a24aaf3e151..9f56549b7ea0 100644 --- a/sw/source/filter/ww8/rtfexport.hxx +++ b/sw/source/filter/ww8/rtfexport.hxx @@ -23,6 +23,8 @@ #include <memory> #include "wrtww8.hxx" +#include <unotools/securityoptions.hxx> + class RtfAttributeOutput; class RtfExportFilter; class RtfSdrExport; @@ -202,6 +204,12 @@ public: const SfxItemSet* GetFirstPageItemSet() const { return m_pFirstPageItemSet; } + // Get author id to remove personal info + size_t GetInfoID(const OUString sPersonalInfo) const + { + return mpAuthorIDs->GetInfoID(sPersonalInfo); + } + private: void WriteFonts(); void WriteStyles(); @@ -229,6 +237,8 @@ private: std::unique_ptr<SvMemoryStream> m_pStream; /// Item set of the first page during export of a follow page format. const SfxItemSet* m_pFirstPageItemSet = nullptr; + /// map authors to remove personal info + std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs; }; #endif // INCLUDED_SW_SOURCE_FILTER_WW8_RTFEXPORT_HXX