mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 16:50:48 +00:00
Merge pull request #10512 from ClickHouse/fix-ubsan-decimal-parse
Fix UBSan report in Decimal parse
This commit is contained in:
commit
2ec9d1e9ab
@ -22,9 +22,9 @@ namespace ErrorCodes
|
|||||||
{
|
{
|
||||||
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
|
extern const int DECIMAL_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string DataTypeDecimal<T>::doGetName() const
|
std::string DataTypeDecimal<T>::doGetName() const
|
||||||
@ -61,10 +61,13 @@ template <typename T>
|
|||||||
bool DataTypeDecimal<T>::tryReadText(T & x, ReadBuffer & istr, UInt32 precision, UInt32 scale)
|
bool DataTypeDecimal<T>::tryReadText(T & x, ReadBuffer & istr, UInt32 precision, UInt32 scale)
|
||||||
{
|
{
|
||||||
UInt32 unread_scale = scale;
|
UInt32 unread_scale = scale;
|
||||||
bool done = tryReadDecimalText(istr, x, precision, unread_scale);
|
if (!tryReadDecimalText(istr, x, precision, unread_scale))
|
||||||
|
return false;
|
||||||
|
|
||||||
x *= T::getScaleMultiplier(unread_scale);
|
if (common::mulOverflow(x.value, T::getScaleMultiplier(unread_scale), x.value))
|
||||||
return done;
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -75,7 +78,9 @@ void DataTypeDecimal<T>::readText(T & x, ReadBuffer & istr, UInt32 precision, UI
|
|||||||
readCSVDecimalText(istr, x, precision, unread_scale);
|
readCSVDecimalText(istr, x, precision, unread_scale);
|
||||||
else
|
else
|
||||||
readDecimalText(istr, x, precision, unread_scale);
|
readDecimalText(istr, x, precision, unread_scale);
|
||||||
x *= T::getScaleMultiplier(unread_scale);
|
|
||||||
|
if (common::mulOverflow(x.value, T::getScaleMultiplier(unread_scale), x.value))
|
||||||
|
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -101,7 +106,9 @@ T DataTypeDecimal<T>::parseFromString(const String & str) const
|
|||||||
T x;
|
T x;
|
||||||
UInt32 unread_scale = this->scale;
|
UInt32 unread_scale = this->scale;
|
||||||
readDecimalText(buf, x, this->precision, unread_scale, true);
|
readDecimalText(buf, x, this->precision, unread_scale, true);
|
||||||
x *= T::getScaleMultiplier(unread_scale);
|
|
||||||
|
if (common::mulOverflow(x.value, T::getScaleMultiplier(unread_scale), x.value))
|
||||||
|
throw Exception("Decimal math overflow", ErrorCodes::DECIMAL_OVERFLOW);
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
3
tests/performance/decimal_parse.xml
Normal file
3
tests/performance/decimal_parse.xml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<test>
|
||||||
|
<query>SELECT count() FROM zeros(10000000) WHERE NOT ignore(toDecimal32OrZero(toString(rand() % 10000), 5))</query>
|
||||||
|
</test>
|
@ -0,0 +1 @@
|
|||||||
|
0.000000
|
1
tests/queries/0_stateless/01260_ubsan_decimal_parse.sql
Normal file
1
tests/queries/0_stateless/01260_ubsan_decimal_parse.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
SELECT toDecimal32OrZero(CAST(-7174046, 'String'), 6);
|
Loading…
Reference in New Issue
Block a user