[Libreoffice-commits] core.git: compilerplugins/clang sw/source

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 3 21:30:20 UTC 2020


 compilerplugins/clang/toolslong.cxx |   17 +++++++++++++++++
 sw/source/core/doc/doccomp.cxx      |    3 ++-
 2 files changed, 19 insertions(+), 1 deletion(-)

New commits:
commit 64e58879c4445bfc733d337c53ac7dc1748fdbb9
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Tue Nov 3 08:33:19 2020 +0100
Commit:     Stephan Bergmann <sbergman at redhat.com>
CommitDate: Tue Nov 3 22:29:36 2020 +0100

    Avoid UBSan pointer-overflow
    
    ...as seen with recently introduced UITest_writer_tests
    UITEST_TEST_NAME=compareDocuments.compareDocuments.test_tdf137855, but where the
    unsigned sal_uLong (aka sal_uIntPtr) value is apparently meant to wrap around
    and address an element of m_pMemory at a negative index from m_pBDiag:
    
    > sw/source/core/doc/doccomp.cxx:832:13: runtime error: addition of unsigned offset to 0x6250014a90d0 overflowed to 0x6250014a90b8
    >  #0 in (anonymous namespace)::Compare::CompareSequence::Compare(unsigned long, unsigned long, unsigned long, unsigned long) at sw/source/core/doc/doccomp.cxx:832:13
    >  #1 in (anonymous namespace)::Compare::CompareSequence::CompareSequence((anonymous namespace)::CompareData&, (anonymous namespace)::CompareData&, (anonymous namespace)::Compare::MovedData const&, (anonymous namespace)::Compare::MovedData const&) at sw/source/core/doc/doccomp.cxx:794:5
    >  #2 in (anonymous namespace)::Compare::Compare(unsigned long, (anonymous namespace)::CompareData&, (anonymous namespace)::CompareData&) at sw/source/core/doc/doccomp.cxx:605:25
    >  #3 in (anonymous namespace)::CompareData::CompareLines((anonymous namespace)::CompareData&) at sw/source/core/doc/doccomp.cxx:440:17
    >  #4 in SwDoc::CompareDoc(SwDoc const&) at sw/source/core/doc/doccomp.cxx:1877:13
    >  #5 in SwEditShell::CompareDoc(SwDoc const&) at sw/source/core/edit/editsh.cxx:877:34
    >  #6 in SwView::InsertMedium(unsigned short, std::unique_ptr<SfxMedium, std::default_delete<SfxMedium> >, short) at sw/source/uibase/uiview/view2.cxx:2377:39
    >  #7 in SwView::DialogClosedHdl(sfx2::FileDialogHelper*) at sw/source/uibase/uiview/view2.cxx:2574:26
    [...]
    
    Using std::make_signed_t where its canonic type happens to be `long` requires a
    workaround for old Clang to avoid a false
    
    > CXXFunctionalCastExpr, suspicious cast from 'sal_uLong' (aka 'unsigned long') to 'std::make_signed_t<decltype(d)>' (aka 'long') [loplugin:toolslong]
    
    warning.
    
    Change-Id: I07413ba06051f75d80832a4772ab1c541805b259
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105234
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/compilerplugins/clang/toolslong.cxx b/compilerplugins/clang/toolslong.cxx
index 719b5b0caca5..b0d6a78d35ab 100644
--- a/compilerplugins/clang/toolslong.cxx
+++ b/compilerplugins/clang/toolslong.cxx
@@ -17,6 +17,8 @@
 #include "clang/AST/Attr.h"
 #include "clang/Basic/Builtins.h"
 
+#include "config_clang.h"
+
 #include "check.hxx"
 #include "compat.hxx"
 #include "plugin.hxx"
@@ -32,6 +34,21 @@ bool isLong(QualType type)
     // some parts of the STL have ::difference_type => long
     if (type->getAs<AutoType>() || type->getAs<DecltypeType>())
         return false;
+#if CLANG_VERSION < 80000
+    // Prior to <https://github.com/llvm/llvm-project/commit/
+    // c50240dac133451b3eae5b89cecca4c1c4af9fd4> "[AST] Get aliased type info from an aliased
+    // TemplateSpecialization" in Clang 8, if type is a TemplateSpecializationType on top of a
+    // TypedefType, the above getAs<TypedefType> returned null (as it unconditionally desugared the
+    // TemplateSpecializationType to the underlying canonic type, not to any aliased type), so re-
+    // check with the TemplateSpecializationType's aliased type:
+    if (auto const t = type->getAs<TemplateSpecializationType>())
+    {
+        if (t->isTypeAlias())
+        {
+            return isLong(t->getAliasedType());
+        }
+    }
+#endif
     if (type->isSpecificBuiltinType(BuiltinType::Kind::Long))
         return true;
     auto arrayType = type->getAsArrayTypeUnsafe();
diff --git a/sw/source/core/doc/doccomp.cxx b/sw/source/core/doc/doccomp.cxx
index 1b81e89ab4c8..cabd1ff97401 100644
--- a/sw/source/core/doc/doccomp.cxx
+++ b/sw/source/core/doc/doccomp.cxx
@@ -47,6 +47,7 @@
 
 #include <cstddef>
 #include <memory>
+#include <type_traits>
 #include <vector>
 
 using namespace ::com::sun::star;
@@ -829,7 +830,7 @@ void Compare::CompareSequence::Compare( sal_uLong nStt1, sal_uLong nEnd1,
         /* Find a point of correspondence in the middle of the files.  */
 
         d = CheckDiag( nStt1, nEnd1, nStt2, nEnd2, &c );
-        b = m_pBDiag[ d ];
+        b = m_pBDiag[ std::make_signed_t<decltype(d)>(d) ];
 
         if( 1 != c )
         {


More information about the Libreoffice-commits mailing list