[Libreoffice-bugs] [Bug 137542] SIGSEGV on tab cycling focus to input field in a table cell

bugzilla-daemon at bugs.documentfoundation.org bugzilla-daemon at bugs.documentfoundation.org
Thu Oct 29 20:16:34 UTC 2020


https://bugs.documentfoundation.org/show_bug.cgi?id=137542

--- Comment #3 from charkins at pobox.com ---
I am not really familiar with the LO code base, but tried to at least narrow
down the source of the crash. When triggering the focus change,
SwTextShell::ExecField is called and triggers this case:

        case FN_GOTO_NEXT_INPUTFLD:
        case FN_GOTO_PREV_INPUTFLD:
            {
                bool bRet = false;
                SwFieldType* pField = rSh.GetFieldType( 0, SwFieldIds::Input );
                const bool bAddSetExpressionFields = !(
rSh.GetViewOptions()->IsReadonly() );
                if ( pField != nullptr
                     && rSh.MoveFieldType(
                            pField,
                            FN_GOTO_NEXT_INPUTFLD == nSlot,
                            SwFieldIds::Unknown,
                            bAddSetExpressionFields ) )
                {
                    rSh.ClearMark();
                    if (!rSh.IsMultiSelection()
                        && (nullptr != dynamic_cast<const SwTextInputField*>(
                              
SwCursorShell::GetTextFieldAtCursor(rSh.GetCursor(), true))))
                    {
                        rSh.SttSelect();
                        rSh.SelectText(
                            SwCursorShell::StartOfInputFieldAtPos(
*(rSh.GetCursor()->Start()) ) + 1,
                            SwCursorShell::EndOfInputFieldAtPos(
*(rSh.GetCursor()->Start()) ) - 1 );
                    }
                    else
                    {
                        rSh.StartInputFieldDlg(rSh.GetCurField(true), false,
false, GetView().GetFrameWeld());
                    }
                    bRet = true;
                }

                rReq.SetReturnValue( SfxBoolItem( nSlot, bRet ));
            }
            break;


In the working case, SwCursorShell::GetTextFieldAtCursor(...) != nullptr and
the nested if condition is true and focus changes without problem. In the
broken case, SwCursorShell::GetTextFieldAtCursor(...) == nullptr, triggering
the else case of the nested if, eventually leading to the segfault. Digging
further into the GetTextFieldAtCursor code path, the difference arises down in
lcl_GetTextAttrs in sw/source/core/txtnode/ndtxt.cxx:

static void
lcl_GetTextAttrs(
    std::vector<SwTextAttr *> *const pVector,
    SwTextAttr **const ppTextAttr,
    SwpHints const *const pSwpHints,
    sal_Int32 const nIndex, sal_uInt16 const nWhich,
    enum SwTextNode::GetTextAttrMode const eMode)

When this function is called during focus change in the working case, pSwpHints
has a single hint which is assigned to *ppTextAttr, which is then used to get
the GetTextFieldAtCursor return value. In the broken case (with text preceding
the second input field), pSwpHints has TWO hints, with the hint from the
working case at index 1 and another hint at index 0. This block of code in that
function breaks early in the broken case:


        sal_Int32 const nHintStart = pHint->GetStart();
        if (nIndex < nHintStart)
            break; // hints are sorted by which&start, so we are done...

nIndex=0 and nHintStart=0 in the working case, but nIndex=0 and nHintStart=1 in
the broken case. Hopefully this will hope narrow things down for someone
familiar with this code. It might be a while before I can get back to it!

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/libreoffice-bugs/attachments/20201029/41d5e043/attachment.htm>


More information about the Libreoffice-bugs mailing list