mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 01:51:59 +00:00
Fix buffer overflow in parser
This commit is contained in:
parent
4fd22ed515
commit
d331f0ce82
@ -1,13 +1,12 @@
|
||||
#include <Access/Common/QuotaDefs.h>
|
||||
#include <Common/Exception.h>
|
||||
|
||||
#include <base/range.h>
|
||||
#include <IO/ReadHelpers.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -29,15 +28,15 @@ String QuotaTypeInfo::valueToString(QuotaValue value) const
|
||||
if (!(value % output_denominator))
|
||||
return std::to_string(value / output_denominator);
|
||||
else
|
||||
return boost::lexical_cast<std::string>(static_cast<double>(value) / output_denominator);
|
||||
return toString(static_cast<double>(value) / output_denominator);
|
||||
}
|
||||
|
||||
QuotaValue QuotaTypeInfo::stringToValue(const String & str) const
|
||||
{
|
||||
if (output_denominator == 1)
|
||||
return static_cast<QuotaValue>(std::strtoul(str.c_str(), nullptr, 10));
|
||||
return static_cast<QuotaValue>(parse<UInt64>(str));
|
||||
else
|
||||
return static_cast<QuotaValue>(std::strtod(str.c_str(), nullptr) * output_denominator);
|
||||
return static_cast<QuotaValue>(parse<Float64>(str) * output_denominator);
|
||||
}
|
||||
|
||||
String QuotaTypeInfo::valueToStringWithName(QuotaValue value) const
|
||||
|
@ -144,7 +144,7 @@ bool assertOrParseNaN(ReadBuffer & buf)
|
||||
template <typename T, typename ReturnType>
|
||||
ReturnType readFloatTextPreciseImpl(T & x, ReadBuffer & buf)
|
||||
{
|
||||
static_assert(std::is_same_v<T, double> || std::is_same_v<T, float>, "Argument for readFloatTextFastFloatImpl must be float or double");
|
||||
static_assert(std::is_same_v<T, double> || std::is_same_v<T, float>, "Argument for readFloatTextPreciseImpl must be float or double");
|
||||
static_assert('a' > '.' && 'A' > '.' && '\n' < '.' && '\t' < '.' && '\'' < '.' && '"' < '.', "Layout of char is not like ASCII"); //-V590
|
||||
|
||||
static constexpr bool throw_exception = std::is_same_v<ReturnType, void>;
|
||||
|
@ -1,15 +1,14 @@
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <Poco/String.h>
|
||||
|
||||
#include <IO/ReadBufferFromMemory.h>
|
||||
#include <IO/ReadHelpers.h>
|
||||
#include <Parsers/DumpASTNode.h>
|
||||
#include <IO/readFloatText.h>
|
||||
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <Common/StringUtils/StringUtils.h>
|
||||
#include <Common/BinStringDecodeHelper.h>
|
||||
|
||||
#include <Parsers/DumpASTNode.h>
|
||||
#include <Parsers/ASTAsterisk.h>
|
||||
#include <Parsers/ASTCollation.h>
|
||||
#include <Parsers/ASTColumnsTransformers.h>
|
||||
@ -29,22 +28,17 @@
|
||||
#include <Parsers/ASTAssignment.h>
|
||||
#include <Parsers/ASTColumnsMatcher.h>
|
||||
#include <Parsers/ASTExplainQuery.h>
|
||||
|
||||
#include <Parsers/ASTSelectQuery.h>
|
||||
#include <Parsers/ASTTablesInSelectQuery.h>
|
||||
|
||||
|
||||
#include <Parsers/parseIdentifierOrStringLiteral.h>
|
||||
#include <Parsers/parseIntervalKind.h>
|
||||
#include <Parsers/ExpressionListParsers.h>
|
||||
#include <Parsers/IAST_fwd.h>
|
||||
#include <Parsers/ParserSelectWithUnionQuery.h>
|
||||
#include <Parsers/ParserCase.h>
|
||||
|
||||
#include <Parsers/ExpressionElementParsers.h>
|
||||
#include <Parsers/ParserCreateQuery.h>
|
||||
#include <Parsers/ParserExplainQuery.h>
|
||||
|
||||
#include <Parsers/queryToString.h>
|
||||
|
||||
#include <Interpreters/StorageID.h>
|
||||
@ -834,10 +828,9 @@ bool ParserNumber::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
|
||||
auto try_read_float = [&](const char * it, const char * end)
|
||||
{
|
||||
char * str_end;
|
||||
errno = 0; /// Functions strto* don't clear errno.
|
||||
Float64 float_value = std::strtod(it, &str_end);
|
||||
if (str_end == end && errno != ERANGE)
|
||||
Float64 float_value = 0;
|
||||
ReadBufferFromMemory buf(it, end - it);
|
||||
if (tryReadFloatTextPrecise(float_value, buf))
|
||||
{
|
||||
if (float_value < 0)
|
||||
throw Exception("Logical error: token number cannot begin with minus, but parsed float number is less than zero.", ErrorCodes::LOGICAL_ERROR);
|
||||
@ -882,7 +875,10 @@ bool ParserNumber::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
for (const auto * it = pos->begin; it != pos->end; ++it)
|
||||
{
|
||||
if (*it != '_')
|
||||
buf[buf_size++] = *it;
|
||||
{
|
||||
buf[buf_size] = *it;
|
||||
++buf_size;
|
||||
}
|
||||
if (unlikely(buf_size > MAX_LENGTH_OF_NUMBER))
|
||||
{
|
||||
expected.add(pos, "number");
|
||||
|
@ -553,7 +553,9 @@ bool ConstantExpressionTemplate::parseLiteralAndAssertType(
|
||||
{
|
||||
Field number;
|
||||
if (type_info.is_nullable && 4 <= istr.available() && 0 == strncasecmp(istr.position(), "NULL", 4))
|
||||
{
|
||||
istr.position() += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// ParserNumber::parse(...) is about 20x slower than strtod(...)
|
||||
|
Loading…
Reference in New Issue
Block a user