Merge "UTF8 validation in CQL binary protocol" from Paweł

"These patches add verification that strings passed using CQL binary protocol
are valid utf8. Exception hierarchy is also adjusted to make sure that
protocol exceptions are properly translated to an appropriate error code.

This makes DTEST cql_tests.py:TestCQL.invalid_string_literals_test pass."

Reviewed-by: Pekka Enberg <penberg@cloudius-systems.com>
This commit is contained in:
Avi Kivity
2015-07-09 17:44:09 +03:00
3 changed files with 16 additions and 18 deletions

View File

@@ -55,13 +55,7 @@ enum class exception_code : int32_t {
UNPREPARED = 0x2500
};
class transport_exception {
public:
virtual exception_code code() const = 0;
virtual sstring get_message() const = 0;
};
class cassandra_exception : public std::exception, public transport_exception {
class cassandra_exception : public std::exception {
private:
exception_code _code;
sstring _msg;
@@ -71,8 +65,8 @@ public:
, _msg(std::move(msg))
{ }
virtual const char* what() const noexcept override { return _msg.begin(); }
virtual exception_code code() const override { return _code; }
virtual sstring get_message() const override { return what(); }
exception_code code() const { return _code; }
sstring get_message() const { return what(); }
};
class request_validation_exception : public cassandra_exception {

View File

@@ -28,18 +28,11 @@
namespace transport {
class protocol_exception : public std::exception, public exceptions::transport_exception {
private:
exceptions::exception_code _code;
sstring _msg;
class protocol_exception : public exceptions::cassandra_exception {
public:
protocol_exception(sstring msg)
: _code(exceptions::exception_code::PROTOCOL_ERROR)
, _msg(std::move(msg))
: exceptions::cassandra_exception{exceptions::exception_code::PROTOCOL_ERROR, std::move(msg)}
{ }
virtual const char* what() const noexcept override { return _msg.begin(); }
virtual exceptions::exception_code code() const override { return _code; }
virtual sstring get_message() const override { return _msg; }
};
}

View File

@@ -8,6 +8,7 @@
#include <boost/range/irange.hpp>
#include <boost/bimap.hpp>
#include <boost/assign.hpp>
#include <boost/locale/encoding_utf.hpp>
#include "db/consistency_level.hh"
#include "core/future-util.hh"
@@ -175,6 +176,14 @@ private:
}
}
void validate_utf8(sstring_view s) {
try {
boost::locale::conv::utf_to_utf<char>(s.data(), boost::locale::conv::stop);
} catch (const boost::locale::conv::conversion_error& ex) {
throw transport::protocol_exception("Cannot decode string as UTF8");
}
}
int8_t read_byte(temporary_buffer<char>& buf);
int32_t read_int(temporary_buffer<char>& buf);
int64_t read_long(temporary_buffer<char>& buf);
@@ -677,6 +686,7 @@ sstring cql_server::connection::read_string(temporary_buffer<char>& buf)
sstring s{buf.begin(), static_cast<size_t>(n)};
assert(n >= 0);
buf.trim_front(n);
validate_utf8(s);
return s;
}
@@ -686,6 +696,7 @@ sstring_view cql_server::connection::read_long_string_view(temporary_buffer<char
check_room(buf, n);
sstring_view s{buf.begin(), static_cast<size_t>(n)};
buf.trim_front(n);
validate_utf8(s);
return s;
}