mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 09:32:06 +00:00
Merge pull request #32955 from azat/read-fix
Fix UB in case of unexpected EOF during filling a set from HTTP query
This commit is contained in:
commit
7660530fcc
@ -29,7 +29,8 @@ bool LimitReadBuffer::nextImpl()
|
||||
|
||||
if (!in->next())
|
||||
{
|
||||
working_buffer = in->buffer();
|
||||
/// Clearing the buffer with existing data.
|
||||
set(in->position(), 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -183,8 +183,8 @@ void HTMLForm::readMultipart(ReadBuffer & in_, PartHandler & handler)
|
||||
size_t fields = 0;
|
||||
MultipartReadBuffer in(in_, boundary);
|
||||
|
||||
/// Assume there is at least one part
|
||||
in.skipToNextBoundary();
|
||||
if (!in.skipToNextBoundary())
|
||||
throw Poco::Net::HTMLFormException("No boundary line found");
|
||||
|
||||
/// Read each part until next boundary (or last boundary)
|
||||
while (!in.eof())
|
||||
@ -241,7 +241,9 @@ HTMLForm::MultipartReadBuffer::MultipartReadBuffer(ReadBuffer & in_, const std::
|
||||
|
||||
bool HTMLForm::MultipartReadBuffer::skipToNextBoundary()
|
||||
{
|
||||
assert(working_buffer.empty() || eof());
|
||||
if (in.eof())
|
||||
return false;
|
||||
|
||||
assert(boundary_hit);
|
||||
|
||||
boundary_hit = false;
|
||||
@ -257,7 +259,7 @@ bool HTMLForm::MultipartReadBuffer::skipToNextBoundary()
|
||||
}
|
||||
}
|
||||
|
||||
throw Poco::Net::HTMLFormException("No boundary line found");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string HTMLForm::MultipartReadBuffer::readLine(bool append_crlf)
|
||||
|
@ -0,0 +1,2 @@
|
||||
124
|
||||
124
|
27
tests/queries/0_stateless/02151_http_s_structure_set_eof.sh
Executable file
27
tests/queries/0_stateless/02151_http_s_structure_set_eof.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
tmp_file=$(mktemp "$CURDIR/clickhouse.XXXXXX.csv")
|
||||
trap 'rm $tmp_file' EXIT
|
||||
|
||||
# NOTE: this file should be huge enough, so that it is impossible to upload it
|
||||
# in 0.15s, see timeout command below, this will ensure, that EOF will be
|
||||
# received during creating a set from externally uploaded table.
|
||||
#
|
||||
# Previously code there wasn't ready for EOF, and you will get one of the
|
||||
# following assertions:
|
||||
#
|
||||
# - ./src/IO/ReadBuffer.h:58: bool DB::ReadBuffer::next(): Assertion `!hasPendingData()' failed.
|
||||
# - ./src/Server/HTTP/HTMLForm.cpp:245: bool DB::HTMLForm::MultipartReadBuffer::skipToNextBoundary(): Assertion `boundary_hit' failed.
|
||||
# - ./src/IO/LimitReadBuffer.cpp:17: virtual bool DB::LimitReadBuffer::nextImpl(): Assertion `position() >= in->position()' failed.
|
||||
#
|
||||
$CLICKHOUSE_CLIENT -q "SELECT toString(number) FROM numbers(10e6) FORMAT TSV" > "$tmp_file"
|
||||
|
||||
# NOTE: Just in case check w/ input_format_parallel_parsing and w/o
|
||||
timeout 0.15s ${CLICKHOUSE_CURL} -sS -F "s=@$tmp_file;" "${CLICKHOUSE_URL}&s_structure=key+Int&query=SELECT+dummy+IN+s&input_format_parallel_parsing=true" -o /dev/null
|
||||
echo $?
|
||||
timeout 0.15s ${CLICKHOUSE_CURL} -sS -F "s=@$tmp_file;" "${CLICKHOUSE_URL}&s_structure=key+Int&query=SELECT+dummy+IN+s&input_format_parallel_parsing=false" -o /dev/null
|
||||
echo $?
|
Loading…
Reference in New Issue
Block a user