sw/source/uibase/frmdlg/colmgr.cxx | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
New commits: commit 0d0119efd526c17018044a805347d5bce195065a Author: Stephan Bergmann <sberg...@redhat.com> AuthorDate: Wed Feb 27 21:19:21 2019 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Thu Feb 28 09:27:02 2019 +0100 In FitToAcutalSize, keep SwColumn's width >= left + right borders Given SwColumn::m_nWish is documented as "Desired width, borders included." (sw/inc/fmtclds.hxx), it appears that the invariant GetWishWidth() >= GetLeft() + GetRight() should always hold for SwColumn instances. However, during UITest_writer_tests4's test_tdf113284 loading of sw/qa/uitest/writer_tests/data/tdf113284.odt, it appears that some five-column table is created for which initially all SwColumns' GetWishWidth() = 13107 GetLeft() = 144 (except for first SwColumn, where it's 0) GetRight() = 144 (except for last SwColumn, where it's 0) and later FitToActualSize is called reducing each SwColunn to GetWishWidth() = 286 so that for most SwColumns (except first and last), GetLeft() + GetRight() = 288 would exceed GetWishWidth(). And then (still during loading of the test's document), SwFormatCol::CalcPrtColWidth (sw/source/core/layout/atrfrm.cxx) is called for such a problematic SwColumn, trying to subtract from its GetWishWidth() (the result of SwFormatCol::CalcColWidth) both GetLeft() and GetRight(), and store that into sal_uInt16 nRet. Which triggers Clang's -fsanitize=implicit-signed-integer-truncation "runtime error: implicit conversion from type 'int' of value -2 (32-bit, signed) to type 'sal_uInt16' (aka 'unsigned short') changed the value to 65534 (16-bit, unsigned)". So make sure that FitToAcutalSize upholds that presumed SwColumns invariant, shrinking the borders as necessary. Change-Id: I3f6fc07e65a0fc5d5f58c99f1dcdea4467b825f0 Reviewed-on: https://gerrit.libreoffice.org/68463 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sw/source/uibase/frmdlg/colmgr.cxx b/sw/source/uibase/frmdlg/colmgr.cxx index c2ff97fe7145..f9c624293429 100644 --- a/sw/source/uibase/frmdlg/colmgr.cxx +++ b/sw/source/uibase/frmdlg/colmgr.cxx @@ -17,6 +17,10 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <sal/config.h> + +#include <algorithm> + #include <hintids.hxx> #include <editeng/lrspitem.hxx> #include <osl/diagnose.h> @@ -34,7 +38,28 @@ void FitToActualSize(SwFormatCol& rCol, sal_uInt16 nWidth) for(sal_uInt16 i = 0; i < nCount; ++i) { const sal_uInt16 nTmp = rCol.CalcColWidth(i, nWidth); - rCol.GetColumns()[i].SetWishWidth(nTmp); + auto & col = rCol.GetColumns()[i]; + col.SetWishWidth(nTmp); + // If necessary, shrink borders (as equally as possible) to keep up the invariant that + // GetWishWidth() >= GetLeft() + GetRight(): + sal_uInt32 const borders = col.GetLeft() + col.GetRight(); + if (borders > nTmp) + { + auto const shrink = borders - nTmp; + auto const half = shrink / 2; // rounds down + if (col.GetLeft() < col.GetRight()) + { + auto const shrinkLeft = std::min(sal_uInt32(col.GetLeft()), half); + col.SetLeft(col.GetLeft() - shrinkLeft); + col.SetRight(col.GetRight() - (shrink - shrinkLeft)); + } + else + { + auto const shrinkRight = std::min(sal_uInt32(col.GetRight()), half); + col.SetLeft(col.GetLeft() - (shrink - shrinkRight)); + col.SetRight(col.GetRight() - shrinkRight); + } + } } rCol.SetWishWidth(nWidth); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits