Bug 154463 - Typing dots in Text Form Field crashes Writer
Summary: Typing dots in Text Form Field crashes Writer
Status: NEW
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: Writer (show other bugs)
(earliest affected) release
Hardware: All All
: medium critical
Assignee: Not Assigned
Keywords: bibisected, bisected, haveBacktrace, regression
Depends on:
Blocks: DOCX-ActiveX-Legacy Crash-Assert
  Show dependency treegraph
Reported: 2023-03-30 03:50 UTC by Aron Budea
Modified: 2023-09-08 20:12 UTC (History)
4 users (show)

See Also:
Crash report or crash signature: ["SwNodeIndex::SwNodeIndex(SwNodeIndex const &,o3tl::strong_int<long,Tag_SwNodeOffset>)"]

Sample DOCX (4.35 KB, application/vnd.openxmlformats-officedocument.wordprocessingml.document)
2023-03-30 03:50 UTC, Aron Budea
Backtrace (20.58 KB, text/plain)
2023-03-30 03:51 UTC, Aron Budea
bt with debug symbols (8.97 KB, text/plain)
2023-03-30 19:20 UTC, Julien Nabet

Note You need to log in before you can comment on or make changes to this bug.
Description Aron Budea 2023-03-30 03:50:48 UTC
Created attachment 186306 [details]
Sample DOCX

The attached document was created in Writer by:
- first enabling "Reorganize Form menu for Microsoft compatibility" in Tools -> Options..., LibreOffice Writer -> Compatibility,
- adding a Form -> Legacy Form Fields -> Text Form Field,
- saving as DOCX.

Another prerequisite is that Tools -> AutoCorrect is enabled.

Open the sample, click into the field, and type a bunch of dots (about 4-6).

=> Crash.

Crash report:
(a crash report taken on Win with LO should be here, but it isn't for some reason, Xisco, do you know if something is wrong with the crash report server?)

A debug build fails with the following assertion:
sw/source/core/crsr/bookmark.cxx:89: SwPosition sw::mark::FindFieldSep(const sw::mark::IFieldmark&): Assertion `0 <= nFields' failed

Observed in LO (7a7eb4aa21ca0c83db825fe8d5a5278611b391d8) / Ubuntu.

This is a regression from the following commit, bibisected using repo bibisect-linux-64-6.4:

author		Michael Stahl <Michael.Stahl@cib.de>	2019-09-24 18:11:45 +0200
committer	Michael Stahl <michael.stahl@cib.de>	2019-10-23 12:47:40 +0200

sw: maintain fieldmarks in DeleteRange()/DeleteAndJoin()/ReplaceRange()
Comment 1 Aron Budea 2023-03-30 03:51:27 UTC
Created attachment 186307 [details]
Comment 2 Stéphane Guillou (stragu) 2023-03-30 06:41:55 UTC
Thanks Aron. Reproduced with example document on Linux in 7.2 and recent master build.
Crash report:

Comment 3 Xisco Faulí 2023-03-30 08:36:37 UTC
(In reply to Aron Budea from comment #0)
> Crash report:
> https://crashreport.libreoffice.org/stats/crash_details/0a8cc30e-d1ba-409b-
> b2d8-33e8b581e6c7
> (a crash report taken on Win with LO should be here, but it isn't
> for some reason, Xisco, do you know if something is wrong with the crash
> report server?)

it just takes a while to process the report. The link works now.
FYI, infra is planning to migrate it to another bot, so it should be faster once migrated.
Comment 4 Julien Nabet 2023-03-30 19:20:12 UTC
Created attachment 186333 [details]
bt with debug symbols

On pc Debian x86-64 with master sources updated today, I had an assertion.
Comment 5 Julien Nabet 2023-09-08 20:12:42 UTC
Just for info, at the beginning when typing the fourth ".", I got:
"\a\003   ....  \b"
     69         for (SwNodeOffset n = nEndNode; nStartNode <= n; --n)
     70         {
     71             SwNode *const pNode(rNodes[n]);
     72             if (pNode->IsTextNode())
     73             {
     74                 SwTextNode & rTextNode(*pNode->GetTextNode());
when doing in gdb:
p rTextNode.GetText()
and everything is ok but LO reenters the same location (I suppose because of autocorrect mechanism) and the string becomes:
"\a\003\a   ….  \b"
Notice both \a (which correspond to CH_TXT_ATR_FIELDSTART)

LO analyzes the string from end to start and when encounters CH_TXT_ATR_FIELDSTART:
     87                         case CH_TXT_ATR_FIELDSTART:
     88                             --nFields;
     89                             assert(0 <= nFields);
     90                             break;

whereas in the first case when it's ok, it got there:
     96                         case CH_TXT_ATR_FIELDSEP:
     97                             if (nFields == 0)
     98                             {
     99                                 assert(!ret); // one per field
    100                                 ret.emplace(rTextNode, i - 1);
    101 #ifndef DBG_UTIL
    102                                 return *ret;
    103 #endif
    104                             }