Avoid signed-integer-overflow

...as seen during e.g. UITest_calc_tests9 now,

> unotools/source/i18n/localedatawrapper.cxx:1017:17: runtime error: signed integer overflow: -9223372036854775808 * -1 cannot be represented in type 'long'
>  #0 in LocaleDataWrapper::ImplAddFormatNum(rtl::OUStringBuffer&, long, unsigned short, bool, bool) const at unotools/source/i18n/localedatawrapper.cxx:1017:17
>  #1 in LocaleDataWrapper::getNum(long, unsigned short, bool, bool) const at unotools/source/i18n/localedatawrapper.cxx:1217:5
>  #2 in weld::MetricSpinButton::format_number(long) const at vcl/source/window/builder.cxx:306:32
>  #3 in weld::MetricSpinButton::update_width_chars() at vcl/source/window/builder.cxx:259:61
>  #4 in weld::MetricSpinButton::set_range(long, long, FieldUnit) at include/vcl/weld.hxx:1991:9
>  #5 in weld::MetricSpinButton::set_min(long, FieldUnit) at include/vcl/weld.hxx:2005:9

Change-Id: I940e2f1e2e4d42db84d4bb0e7b68086204dc77ac
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129570
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
Stephan Bergmann
2022-02-06 11:48:56 +01:00
parent 570001ad3a
commit e15c04f16f

View File

@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <limits>
#include <stdio.h>
#include <string>
@@ -1012,14 +1013,21 @@ void LocaleDataWrapper::ImplAddFormatNum( OUStringBuffer& rBuf,
sal_uInt16 nNumLen;
// negative number
sal_uInt64 abs;
if ( nNumber < 0 )
{
nNumber *= -1;
// Avoid overflow, map -2^63 -> 2^63 explicitly:
abs = nNumber == std::numeric_limits<sal_Int64>::min()
? static_cast<sal_uInt64>(std::numeric_limits<sal_Int64>::min()) : nNumber * -1;
rBuf.append('-');
}
else
{
abs = nNumber;
}
// convert number
ImplAddUNum( aNumBuf, static_cast<sal_uInt64>(nNumber) );
ImplAddUNum( aNumBuf, abs );
nNumLen = static_cast<sal_uInt16>(aNumBuf.getLength());
if ( nNumLen <= nDecimals )