sw/qa/uibase/shells/data/tracked-change-in-unused-first-page-header.docx |binary sw/qa/uibase/shells/shells.cxx | 29 ++++++++++ sw/source/uibase/uno/loktxdoc.cxx | 4 + 3 files changed, 33 insertions(+)
New commits: commit 3ac3d45fa0350af9b5b0b4af56c04fcdc2292923 Author: Mike Kaganski <[email protected]> AuthorDate: Mon Mar 2 17:43:24 2026 +0500 Commit: Mike Kaganski <[email protected]> CommitDate: Mon Mar 2 19:26:55 2026 +0100 LOK Extract API: avoid crash on orphaned redlines The test document contains tracked changes in the header of the first page, but the import creates a page style without a separate first page header, so that header is not actually used in the document. The tracked changes are not removed from the document (they are kept in document nodes, as well as the now-unused header). The redlines are visible in the UI (Manage Changes dialog shows four changes: two for the shared header, and two for orphaned header; clicking the orphaned elements does not navigate to them). Interesting, that save-and-reload gets rid of the redlines. The problem used to be, that "ExtractDocumentStructure" command crashed, when tried to dereference orphaned redline's XText (its parent XText was empty, defined by sw::CreateParentXText). It is unclear to me, what is the correct behavior here: - Maybe we should preserve the separate first header (and its redlines); - Maybe we should drop the unused nodes (header and its redlines); - Maybe we just need to handle the orphaned redlines without a crash. Here I implemented the last option. Change-Id: Ibddc5d73e440e14b288021717193530a1e26bee1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200825 Reviewed-by: Mike Kaganski <[email protected]> Tested-by: Jenkins diff --git a/sw/qa/uibase/shells/data/tracked-change-in-unused-first-page-header.docx b/sw/qa/uibase/shells/data/tracked-change-in-unused-first-page-header.docx new file mode 100644 index 000000000000..fd3171c46be4 Binary files /dev/null and b/sw/qa/uibase/shells/data/tracked-change-in-unused-first-page-header.docx differ diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx index 5855d4570306..ec57b28b9d6c 100644 --- a/sw/qa/uibase/shells/shells.cxx +++ b/sw/qa/uibase/shells/shells.cxx @@ -1030,6 +1030,35 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractRedlines) CPPUNIT_ASSERT(bool(it == docStructure.end())); } +CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractRedlines_UnusedFirstPageHeader) +{ + // The document contains tracked changes in the header of the first page, but the import code + // eventually creates a page style without a separate first page header, so that header is not + // actually used in the document. The tracked changes are not removed from the document (they + // are kept in document nodes, as well as the nodes of the now-unused header). Interesting, + // that save-and-reload gets rid of the redlines. + // + // The problem used to be, that collecting redlines for the "ExtractDocumentStructure" command + // crashed, when tried to dereference orphaned redline's XText unconditionally (its parent + // XText was empty, defined by sw::CreateParentXText). + // + // It is unclear to me, what is the correct behavior here: + // - Maybe we should preserve the separate first header (and its redlines); + // - Maybe we should make sure to drop the unused nodes (header and its redlines); + // - Maybe we just need to handle the orphaned redlines without a crash. + // + // Here I only check that the document doesn't crash (no test of count of redlines, nor their + // properties). + + createSwDoc("tracked-change-in-unused-first-page-header.docx"); + + tools::JsonWriter aJsonWriter; + // Before the fix, this crashed: + getSwTextDoc()->getCommandValues(aJsonWriter, + ".uno:ExtractDocumentStructure?filter=trackchanges"); + aJsonWriter.finishAndGetAsOString(); // writer must be finished +} + CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractRedlines_textBeforeAfter) { // The document here has a series of insert/delete/format changes having different times. diff --git a/sw/source/uibase/uno/loktxdoc.cxx b/sw/source/uibase/uno/loktxdoc.cxx index 5fa3ad62fff9..dfbd052b81c9 100644 --- a/sw/source/uibase/uno/loktxdoc.cxx +++ b/sw/source/uibase/uno/loktxdoc.cxx @@ -1014,8 +1014,12 @@ void GetDocStructureTrackChanges(tools::JsonWriter& rJsonWriter, SwDocShell* pDo HideNewerShowOlder prepare(pSwXRedline->GetRedline()->GetTimeStamp(), rTable); auto xStart = pSwXRedline->getPropertyValue(UNO_NAME_REDLINE_START) .query<css::text::XTextRange>(); + if (xStart && !xStart->getText()) + xStart.clear(); auto xEnd = pSwXRedline->getPropertyValue(UNO_NAME_REDLINE_END) .query<css::text::XTextRange>(); + if (xEnd && !xEnd->getText()) + xEnd.clear(); if (xStart) { auto xCursor = xStart->getText()->createTextCursorByRange(xStart);
