Bug 96479 - Bookmark end node is destroyed by inserting text
Summary: Bookmark end node is destroyed by inserting text
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: Writer (show other bugs)
Version:
(earliest affected)
4.2 all versions
Hardware: All All
: medium normal
Assignee: Not Assigned
URL:
Whiteboard: target:5.2.0 target:5.1.0.2 target:5...
Keywords: bibisected, regression
Depends on: 90816
Blocks:
  Show dependency treegraph
 
Reported: 2015-12-14 10:47 UTC by Jan-Marek Glogowski
Modified: 2016-10-25 19:11 UTC (History)
3 users (show)

See Also:
Crash report or crash signature:


Attachments
Dokument with bookmark replacement macro (11.77 KB, application/odt)
2015-12-14 10:47 UTC, Jan-Marek Glogowski
Details
The orriginal error document without my strippings. (11.67 KB, application/odt)
2015-12-14 12:56 UTC, Jan-Marek Glogowski
Details
Changed macro, which doesn't insertString the dot. (11.68 KB, application/odt)
2015-12-17 18:17 UTC, Jan-Marek Glogowski
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jan-Marek Glogowski 2015-12-14 10:47:57 UTC
Created attachment 121292 [details]
Dokument with bookmark replacement macro

The attached document contains the bookmark 'bookmark' and the following macro, which should replaces the bookmark.

	bm = ThisComponent.bookmarks.getByName("bookmark")
	range = bm.Anchor
	cursor = range.getText().createTextCursorByRange(range)

	range.Text.removeTextContent(bm)

	newBm = ThisComponent.createInstance("com.sun.star.text.Bookmark")
	newBm.setName("bookmark1")

	' Destroys the bookmark end mark!
	cursor.getText().insertString(cursor, ".", true)

The replacement works, but the insertString actually destroys the bookmark end mark.
The saved document misses the broken "bookmark1".

The bug was introduced during the 4.2 development by:

commit c2b5521921b806ff7b04cdacebde3834d2aafd4b
Author: Oliver-Rainer Wittmann <orw@apache.org>
Date:   Mon Nov 18 11:29:24 2013 +0000

    Resolves: #i33737# enable in-place editing of Input Fields

This breaks the bookmark based mail merge of our WollMux extension for all newer LO and AOO releases.
Comment 1 Jan-Marek Glogowski 2015-12-14 11:40:12 UTC
This is probably related to the same regression then bug 90816.
At least it looks the same.

Actually the code:

    cursor.getText().insertString(cursor, ".", true)

is just a workaround for an other problem we found when switching from OOo 3.2.1 to LibreOffice 3.6. WollMux works again, if the workaround is removed.
In the end it's still a bug in LO and probably also AOO.
Comment 2 Oliver Specht (CIB) 2015-12-14 12:31:56 UTC
With range.Text.removeTextContent(bm) you remove the bookmark.
The bookmark newBm is never inserted. 
Seems o.k. to me.
Comment 3 Jan-Marek Glogowski 2015-12-14 12:56:25 UTC
Created attachment 121294 [details]
The orriginal error document without my strippings.

Seems my stripping actually destroyed the error case. This should be the correct document.
Comment 4 Jan-Marek Glogowski 2015-12-14 13:00:22 UTC
Hmm - I was told the insertString was the problem and didn't evaluate. And I removed everything, and obviously the "bookmark1" is not in the target document. Silly me.

The problem is, the original document contains a bookmark1 after the macro, which is lost in the stripped document. Sorry for the confusion.
Comment 5 Oliver Specht (CIB) 2015-12-14 13:18:42 UTC
This still seems o.k. to me:
	cursor.getText().insertString(cursor, ".", true)
cursor includes the '.'
	cursor.getText().insertTextContent(cursor, newBm, true)
newBm includes '.'
	cursor2 = newBm.Anchor.Text.createTextCursorByRange(newBm.Anchor)
cursor2 includes newBm
	cursor2.Text.insertTextContent(cursor2, inputField, true)
insertTextContent removes the selection - that removes newBm - and then inserts the field
Comment 6 Jan-Marek Glogowski 2015-12-14 16:09:36 UTC
(In reply to Oliver Specht from comment #5)
> This still seems o.k. to me:
> 	cursor.getText().insertString(cursor, ".", true)
> cursor includes the '.'
> 	cursor.getText().insertTextContent(cursor, newBm, true)
> newBm includes '.'
> 	cursor2 = newBm.Anchor.Text.createTextCursorByRange(newBm.Anchor)
> cursor2 includes newBm
> 	cursor2.Text.insertTextContent(cursor2, inputField, true)
> insertTextContent removes the selection - that removes newBm - and then
> inserts the field

If you run this code in LO 4.1, i.e. before the patch, it replaces "bookmark" with "bookmark1" with the input field as content.

In versions after the patch, the code modifies the document - I assume correctly, so it still replaces "bookmark" with "bookmark1" (I can see this change in the navigator), but when saving the document the "bookmark1" is gone.

Now you claim that "bookmark1" is correctly removed, but this is contradicted by the GUI and previous behavior, as the navigator for the original document, not the saved and loaded one, shows "bookmark1" in the navigator. The loaded document misses "bookmark1".

Whatever behavior is correct:
  1. the behavior has changed and
  2. the current state is inconsistent, as the navigator shows a "bookmark1", which is lost on save 

Hope this helps to understand my point.
Comment 7 Jan-Marek Glogowski 2015-12-15 18:40:10 UTC
And just to make it clear: commenting the line

  cursor.getText().insertString(cursor, ".", true)

allows the save-load cycle to succeed!
Comment 8 Oliver Specht (CIB) 2015-12-16 11:32:40 UTC
The bookmarks is saved but cannot be loaded where it is:
<text:text-input text:description=""/>
<text:bookmark-start text:name="bookmark1"/>
<text:text-input text:description=""/>
The bookmark is inside of the input field. It should have been moved outside of the field before.
Comment 9 Jan-Marek Glogowski 2015-12-17 18:13:03 UTC
Hmm - seems the overall conclusion is still wrong. I don't know how my co-worker came to the conclusion, that removing the "cursor.getText().insertString(cursor, ".", true)" call fixes the problem. But probably he also just loaded the document without looking at the actual bookmark in XML. Remember: we want to replace "bookmark" with "bookmark1" and change the content to an input field. Here we go:

The original document to be modified by the macro contains:
      <text:p text:style-name="P1">
        <text:text-input text:description=""/>
        <text:bookmark text:name="bookmark"/>
      </text:p>

I guess the bug also happens with a document without the first input field. It contains the empty "bookmark" and no content after the first input field in the paragraph.

Our test office versions are OOo 3.2.1, LO 4.1.6 and LO 4.2+ (current master) . We run the unchanged macro of the document and a modified version of the macro without the following line and check the resulting documents:
      cursor.getText().insertString(cursor, ".", true)

Generated document from macro with "." in OOo 3.2.1
      <text:p text:style-name="Standard">
        <text:text-input text:description=""/>
        <text:bookmark-start text:name="bookmark1"/>
        <text:text-input text:description=""/>
        <text:bookmark-end text:name="bookmark1"/>
      </text:p>

Generated document from macro with_out_ "." in OOo 3.2.1
      <text:p text:style-name="Standard">
        <text:text-input text:description=""/>
        <text:bookmark-start text:name="bookmark1"/>
        <text:text-input text:description=""/>
        <text:bookmark-end text:name="bookmark1"/>
      </text:p>

POV: both are identical and correct.

Generated document from macro with "." in LO 4.1.6
      <text:p text:style-name="P1">
        <text:text-input text:description=""/>
        <text:bookmark-start text:name="bookmark1"/>
        <text:text-input text:description=""/>
        <text:bookmark-end text:name="bookmark1"/>
      </text:p>

Generated document from macro with_out_ "." in LO 4.1.6
      <text:p text:style-name="P1">
        <text:text-input text:description=""/>
        <text:bookmark text:name="bookmark1"/>
        <text:text-input text:description=""/>
      </text:p>

POV: now things start to break (quite probably much earlier then LO 4.1; I didn't check, but we tested LO 3.6 for some time. The commit message just states LO, no version). The empty bookmark isn't "expanded" when inserting / replacing the content. The input field is actually appended after the bookmark. Thanks to the "." workaround, we "force-expand" the bookmark before the insert and still get the expected result.

Generated document from macro with "." in LO 4.2+
      <text:p text:style-name="P1">
        <text:text-input text:description=""/>
        <text:bookmark-start text:name="bookmark1"/>
        <text:text-input text:description=""/>
      </text:p>

Generated document from macro with_out_ "." in LO 4.2+
      <text:p text:style-name="P1">
        <text:text-input text:description=""/>
        <text:bookmark text:name="bookmark1"/>
        <text:text-input text:description=""/>
      </text:p>

POV: now it's really broken. Without the "." the macro actually generates an invalid document (XML is correct, but there is no <text:bookmark-end text:name="bookmark1"/> in the document). I'm not sure we can find a workaround for this in WollMux.

Since we always work with an empty bookmark, the original replacement problem from i#101283 probably still hits us. At least the patch from https://bz.apache.org/ooo/show_bug.cgi?id=101283 still applies and is included in our 4.1 build. But that's another bug I need to verify.
Comment 10 Jan-Marek Glogowski 2015-12-17 18:17:27 UTC
Created attachment 121372 [details]
Changed macro, which doesn't insertString the dot.

Also generates a different file: "/tmp/stripped_saved_no_dot.odt"
Comment 11 Jan-Marek Glogowski 2015-12-18 12:20:03 UTC
(In reply to Oliver Specht from comment #5)
> 	cursor2 = newBm.Anchor.Text.createTextCursorByRange(newBm.Anchor)
> cursor2 includes newBm

If this were true, it would be very hard to replace the content of a bookmark and it changes the behavior.
From my POV the current behavior is broken, but probably there was a reason for the new handling.

That's also the reason why the macro calls
	bm.Anchor.Text.removeTextContent(bm)
Comment 12 Commit Notification 2016-01-02 03:22:14 UTC
Jan-Marek Glogowski committed a patch related to this issue.
It has been pushed to "master":

http://cgit.freedesktop.org/libreoffice/core/commit/?id=c91024891ff10c2ae01e11a28a9aecca2f36b6c3

tdf#96479 workaround bookmark end pos handling...

It will be available in 5.2.0.

The patch should be included in the daily builds available at
http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
http://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 13 Commit Notification 2016-01-05 14:47:52 UTC
Jan-Marek Glogowski committed a patch related to this issue.
It has been pushed to "libreoffice-5-1":

http://cgit.freedesktop.org/libreoffice/core/commit/?id=e781a8273eb2938f905485c00fbaf432e517d1dc&h=libreoffice-5-1

tdf#96479 workaround bookmark end pos handling...

It will be available in 5.1.0.2.

The patch should be included in the daily builds available at
http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
http://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 14 Commit Notification 2016-01-11 09:12:04 UTC
Jan-Marek Glogowski committed a patch related to this issue.
It has been pushed to "libreoffice-5-0":

http://cgit.freedesktop.org/libreoffice/core/commit/?id=107664a977c4893a0bc02f10cd20411c330b6d94&h=libreoffice-5-0

tdf#96479 workaround bookmark end pos handling...

It will be available in 5.0.5.

The patch should be included in the daily builds available at
http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
http://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.
Comment 15 Thorsten Behrens (allotropia) 2016-02-16 10:36:45 UTC
Reporter said this is fixed.