mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 09:32:06 +00:00
Merge pull request #42465 from ClickHouse/decimal-asan
Fix buffer overflow in Decimal scale
This commit is contained in:
commit
3beace607b
@ -47,6 +47,11 @@ namespace common
|
|||||||
|
|
||||||
constexpr inline int exp10_i32(int x)
|
constexpr inline int exp10_i32(int x)
|
||||||
{
|
{
|
||||||
|
if (x < 0)
|
||||||
|
return 0;
|
||||||
|
if (x > 9)
|
||||||
|
return std::numeric_limits<int>::max();
|
||||||
|
|
||||||
constexpr int values[] =
|
constexpr int values[] =
|
||||||
{
|
{
|
||||||
1,
|
1,
|
||||||
@ -65,6 +70,11 @@ constexpr inline int exp10_i32(int x)
|
|||||||
|
|
||||||
constexpr inline int64_t exp10_i64(int x)
|
constexpr inline int64_t exp10_i64(int x)
|
||||||
{
|
{
|
||||||
|
if (x < 0)
|
||||||
|
return 0;
|
||||||
|
if (x > 18)
|
||||||
|
return std::numeric_limits<int64_t>::max();
|
||||||
|
|
||||||
constexpr int64_t values[] =
|
constexpr int64_t values[] =
|
||||||
{
|
{
|
||||||
1LL,
|
1LL,
|
||||||
@ -92,6 +102,11 @@ constexpr inline int64_t exp10_i64(int x)
|
|||||||
|
|
||||||
constexpr inline Int128 exp10_i128(int x)
|
constexpr inline Int128 exp10_i128(int x)
|
||||||
{
|
{
|
||||||
|
if (x < 0)
|
||||||
|
return 0;
|
||||||
|
if (x > 38)
|
||||||
|
return std::numeric_limits<Int128>::max();
|
||||||
|
|
||||||
constexpr Int128 values[] =
|
constexpr Int128 values[] =
|
||||||
{
|
{
|
||||||
static_cast<Int128>(1LL),
|
static_cast<Int128>(1LL),
|
||||||
@ -140,6 +155,11 @@ constexpr inline Int128 exp10_i128(int x)
|
|||||||
|
|
||||||
inline Int256 exp10_i256(int x)
|
inline Int256 exp10_i256(int x)
|
||||||
{
|
{
|
||||||
|
if (x < 0)
|
||||||
|
return 0;
|
||||||
|
if (x > 76)
|
||||||
|
return std::numeric_limits<Int256>::max();
|
||||||
|
|
||||||
using Int256 = Int256;
|
using Int256 = Int256;
|
||||||
static constexpr Int256 i10e18{1000000000000000000ll};
|
static constexpr Int256 i10e18{1000000000000000000ll};
|
||||||
static const Int256 values[] = {
|
static const Int256 values[] = {
|
||||||
@ -231,8 +251,10 @@ inline Int256 exp10_i256(int x)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
constexpr inline T intExp10OfSize(int x)
|
constexpr inline T intExp10OfSize(int x)
|
||||||
{
|
{
|
||||||
if constexpr (sizeof(T) <= 8)
|
if constexpr (sizeof(T) <= 4)
|
||||||
return intExp10(x);
|
return common::exp10_i32(x);
|
||||||
|
else if constexpr (sizeof(T) <= 8)
|
||||||
|
return common::exp10_i64(x);
|
||||||
else if constexpr (sizeof(T) <= 16)
|
else if constexpr (sizeof(T) <= 16)
|
||||||
return common::exp10_i128(x);
|
return common::exp10_i128(x);
|
||||||
else
|
else
|
||||||
|
@ -19,6 +19,7 @@ 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 ILLEGAL_COLUMN;
|
extern const int ILLEGAL_COLUMN;
|
||||||
|
extern const int BAD_ARGUMENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -41,6 +42,9 @@ struct TimeSlotsImpl
|
|||||||
const PaddedPODArray<UInt32> & starts, const PaddedPODArray<UInt32> & durations, UInt32 time_slot_size,
|
const PaddedPODArray<UInt32> & starts, const PaddedPODArray<UInt32> & durations, UInt32 time_slot_size,
|
||||||
PaddedPODArray<UInt32> & result_values, ColumnArray::Offsets & result_offsets)
|
PaddedPODArray<UInt32> & result_values, ColumnArray::Offsets & result_offsets)
|
||||||
{
|
{
|
||||||
|
if (time_slot_size == 0)
|
||||||
|
throw Exception("Time slot size cannot be zero", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
size_t size = starts.size();
|
size_t size = starts.size();
|
||||||
|
|
||||||
result_offsets.resize(size);
|
result_offsets.resize(size);
|
||||||
@ -63,6 +67,9 @@ struct TimeSlotsImpl
|
|||||||
const PaddedPODArray<UInt32> & starts, UInt32 duration, UInt32 time_slot_size,
|
const PaddedPODArray<UInt32> & starts, UInt32 duration, UInt32 time_slot_size,
|
||||||
PaddedPODArray<UInt32> & result_values, ColumnArray::Offsets & result_offsets)
|
PaddedPODArray<UInt32> & result_values, ColumnArray::Offsets & result_offsets)
|
||||||
{
|
{
|
||||||
|
if (time_slot_size == 0)
|
||||||
|
throw Exception("Time slot size cannot be zero", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
size_t size = starts.size();
|
size_t size = starts.size();
|
||||||
|
|
||||||
result_offsets.resize(size);
|
result_offsets.resize(size);
|
||||||
@ -85,6 +92,9 @@ struct TimeSlotsImpl
|
|||||||
UInt32 start, const PaddedPODArray<UInt32> & durations, UInt32 time_slot_size,
|
UInt32 start, const PaddedPODArray<UInt32> & durations, UInt32 time_slot_size,
|
||||||
PaddedPODArray<UInt32> & result_values, ColumnArray::Offsets & result_offsets)
|
PaddedPODArray<UInt32> & result_values, ColumnArray::Offsets & result_offsets)
|
||||||
{
|
{
|
||||||
|
if (time_slot_size == 0)
|
||||||
|
throw Exception("Time slot size cannot be zero", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
size_t size = durations.size();
|
size_t size = durations.size();
|
||||||
|
|
||||||
result_offsets.resize(size);
|
result_offsets.resize(size);
|
||||||
@ -125,6 +135,9 @@ struct TimeSlotsImpl
|
|||||||
|
|
||||||
ColumnArray::Offset current_offset = 0;
|
ColumnArray::Offset current_offset = 0;
|
||||||
time_slot_size = time_slot_size.value * ts_multiplier;
|
time_slot_size = time_slot_size.value * ts_multiplier;
|
||||||
|
if (time_slot_size == 0)
|
||||||
|
throw Exception("Time slot size cannot be zero", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
for (DateTime64 value = (starts[i] * dt_multiplier) / time_slot_size, end = (starts[i] * dt_multiplier + durations[i] * dur_multiplier) / time_slot_size; value <= end; value += 1)
|
for (DateTime64 value = (starts[i] * dt_multiplier) / time_slot_size, end = (starts[i] * dt_multiplier + durations[i] * dur_multiplier) / time_slot_size; value <= end; value += 1)
|
||||||
@ -155,6 +168,9 @@ struct TimeSlotsImpl
|
|||||||
ColumnArray::Offset current_offset = 0;
|
ColumnArray::Offset current_offset = 0;
|
||||||
duration = duration * dur_multiplier;
|
duration = duration * dur_multiplier;
|
||||||
time_slot_size = time_slot_size.value * ts_multiplier;
|
time_slot_size = time_slot_size.value * ts_multiplier;
|
||||||
|
if (time_slot_size == 0)
|
||||||
|
throw Exception("Time slot size cannot be zero", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
for (DateTime64 value = (starts[i] * dt_multiplier) / time_slot_size, end = (starts[i] * dt_multiplier + duration) / time_slot_size; value <= end; value += 1)
|
for (DateTime64 value = (starts[i] * dt_multiplier) / time_slot_size, end = (starts[i] * dt_multiplier + duration) / time_slot_size; value <= end; value += 1)
|
||||||
@ -185,6 +201,9 @@ struct TimeSlotsImpl
|
|||||||
ColumnArray::Offset current_offset = 0;
|
ColumnArray::Offset current_offset = 0;
|
||||||
start = dt_multiplier * start;
|
start = dt_multiplier * start;
|
||||||
time_slot_size = time_slot_size.value * ts_multiplier;
|
time_slot_size = time_slot_size.value * ts_multiplier;
|
||||||
|
if (time_slot_size == 0)
|
||||||
|
throw Exception("Time slot size cannot be zero", ErrorCodes::BAD_ARGUMENTS);
|
||||||
|
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
for (DateTime64 value = start / time_slot_size, end = (start + durations[i] * dur_multiplier) / time_slot_size; value <= end; value += 1)
|
for (DateTime64 value = start / time_slot_size, end = (start + durations[i] * dur_multiplier) / time_slot_size; value <= end; value += 1)
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
DROP TABLE IF EXISTS series__fuzz_35;
|
||||||
|
CREATE TABLE series__fuzz_35 (`i` UInt8, `x_value` Decimal(18, 14), `y_value` DateTime) ENGINE = Memory;
|
||||||
|
INSERT INTO series__fuzz_35(i, x_value, y_value) VALUES (1, 5.6,-4.4),(2, -9.6,3),(3, -1.3,-4),(4, 5.3,9.7),(5, 4.4,0.037),(6, -8.6,-7.8),(7, 5.1,9.3),(8, 7.9,-3.6),(9, -8.2,0.62),(10, -3,7.3);
|
||||||
|
SELECT skewSamp(x_value) FROM (SELECT x_value as x_value FROM series__fuzz_35 LIMIT 2) FORMAT Null;
|
||||||
|
DROP TABLE series__fuzz_35;
|
Loading…
Reference in New Issue
Block a user