sw/source/core/doc/docfld.cxx |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

New commits:
commit 5607e88d5f2f2eb7a6b0c9c329728589761c3431
Author:     Caolán McNamara <caol...@redhat.com>
AuthorDate: Fri Mar 24 16:59:55 2023 +0000
Commit:     Caolán McNamara <caol...@redhat.com>
CommitDate: Sat Mar 25 14:49:48 2023 +0000

    crashtesting: iterator range not partitioned by predicate
    
    i.e.
    
    Error: elements in iterator range [first, last) are not partitioned by the
    predicate __comp and value __val.
    
    with backtrace:
    
     #17 0x00007fa394097dd7 in 
std::upper_bound<__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<std::unique_ptr<SetGetExpField,
 std::default_delete<SetGetExpField> > const*, 
std::__cxx1998::vector<std::unique_ptr<SetGetExpField, 
std::default_delete<SetGetExpField> >, 
std::allocator<std::unique_ptr<SetGetExpField, 
std::default_delete<SetGetExpField> > > > >, 
std::__debug::vector<std::unique_ptr<SetGetExpField, 
std::default_delete<SetGetExpField> >, 
std::allocator<std::unique_ptr<SetGetExpField, 
std::default_delete<SetGetExpField> > > >, std::random_access_iterator_tag>, 
std::unique_ptr<SetGetExpField, std::default_delete<SetGetExpField> >, 
o3tl::less_uniqueptr_to<SetGetExpField> > 
(__first=std::unique_ptr<SetGetExpField> = {get() = 0x5623f9fa1ef0}, 
__last=std::unique_ptr<SetGetExpField> = {get() = 0x6666666666666666}, 
__val=std::unique_ptr<SetGetExpField> = {...}, __comp=...) at 
/usr/include/c++/10/bits/stl_algo.h:2125
             __PRETTY_FUNCTION__ = "_FIter std::upper_bound(_FIter, _FIter, 
const _Tp&, _Compare) [with _FIter = 
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<const 
std::unique_ptr<SetGetExpField>*, std::__cxx1998::vector<std"...
     #18 0x00007fa394089f6f in 
o3tl::sorted_vector<std::unique_ptr<SetGetExpField, 
std::default_delete<SetGetExpField> >, o3tl::less_uniqueptr_to<SetGetExpField>, 
o3tl::find_unique, true>::upper_bound (x=std::unique_ptr<SetGetExpField> = 
{...}, this=0x5623f8889220) at 
/home/buildslave/source/libo-core/include/o3tl/sorted_vector.hxx:202
     No locals.
     #19 o3tl::sorted_vector<std::unique_ptr<SetGetExpField, 
std::default_delete<SetGetExpField> >, o3tl::less_uniqueptr_to<SetGetExpField>, 
o3tl::find_unique, false>::upper_bound (x=0x7ffcf58ff6c8, this=0x5623f8889220) 
at /home/buildslave/source/libo-core/include/o3tl/sorted_vector.hxx:341
             tmp = std::unique_ptr<SetGetExpField> = {get() = 0x7ffcf58ff8a0}
             ret = Python Exception <class 'gdb.error'> value has been 
optimized out:
    
             tmp = std::unique_ptr<SetGetExpField> = {get() = <optimized out>}
             ret = Python Exception <class 'gdb.error'> value has been 
optimized out:
    
     #20 sw::DocumentFieldsManager::FieldsToCalc 
(this=this@entry=0x5623f7c46a40, rCalc=..., rToThisField=..., 
pLayout=pLayout@entry=0x5623f9ef5450) at 
/home/buildslave/source/libo-core/sw/source/core/doc/DocumentFieldsManager.cxx:1535
             itLast = invalid iterator
             pMgr = 0x5623f88b6d30
     #21 0x00007fa39408ba53 in sw::DocumentFieldsManager::UpdateTableFields 
(this=0x5623f7c46a40, pHt=0x0) at /usr/include/c++/10/optional:268
    
    from documents
    
    forums/docx/forum-mso-en-8069.docx
    forums/docx/forum-mso-en-8072.docx
    
    where the problem seems to begin with:
    
    commit 9dc6e2c9062725ef1f9d7e321cae5f4dbe8ca749
    Date:   Tue Apr 5 18:27:35 2022 +0200
    
        sw: fix expansion of SetGetExpField in headers with split table rows
    
        The problem is that a get field in a header on page N may calculate and
        show values that do not take into account a set field on page N-1.
    
    and in DocumentFieldsManager::UpdateTableFields for these documents I
    see if( pTableNd->GetIndex() < 
m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
    is false, and then FindNeighbourFrameForNode finds nothing, so a page
    number of 0 is used as fallback
    
    but the sort isn't consistent on comparing such a page 0 element with
    entries with a valid page number, it has to have some sort of ordering
    one way or the other.
    
    Here, try sorting entries with "invalid" pages to the end.
    
    alternatively in DocumentFieldsManager::UpdateTableFields maybe move
    
    Point aPt;      // return the first frame of the layout - Tab.Headline!!
    std::pair<Point, bool> const tmp(aPt, true);
    pFrame = rTextNd.getLayoutFrame(pLayout, nullptr, &tmp);
    
    before
    
    if( pTableNd->GetIndex() < m_rDoc.GetNodes().GetEndOfExtras().GetIndex() )
    
    which works to give it a non 0 page number in this case
    
    Change-Id: I8cc5a93c4e968f212473b46382650fb30950fd8c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149551
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>

diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx
index 45feaca8d581..b6e8f7267d33 100644
--- a/sw/source/core/doc/docfld.cxx
+++ b/sw/source/core/doc/docfld.cxx
@@ -228,8 +228,11 @@ bool SetGetExpField::operator==( const SetGetExpField& 
rField ) const
 
 bool SetGetExpField::operator<( const SetGetExpField& rField ) const
 {
-    if (m_nPageNumber != 0 && rField.m_nPageNumber != 0 && m_nPageNumber != 
rField.m_nPageNumber)
+    if (m_nPageNumber != rField.m_nPageNumber)
     {
+        // sort "invalid" page nums of 0 after valid page nums of non 0
+        if (m_nPageNumber == 0 || rField.m_nPageNumber == 0)
+            return m_nPageNumber != 0;
         return m_nPageNumber < rField.m_nPageNumber;
     }
     if( m_nNode < rField.m_nNode || ( m_nNode == rField.m_nNode && m_nContent 
< rField.m_nContent ))

Reply via email to