* @exception invalid_argument The input stream is invalid.
* @see https://github.com/PeterScott/netstring-c/blob/master/netstring.c
*/
-StreamReadStatus NetString::ReadStringFromStream(const Stream::Ptr& stream, String *str, StreamReadContext& context, bool may_wait)
+StreamReadStatus NetString::ReadStringFromStream(const Stream::Ptr& stream, String *str, StreamReadContext& context,
+ bool may_wait, ssize_t maxMessageLength)
{
if (context.Eof)
return StatusEof;
/* read the whole message */
size_t data_length = len + 1;
+ if (maxMessageLength >= 0 && data_length > maxMessageLength) {
+ std::stringstream errorMessage;
+ errorMessage << "Max data length exceeded: " << (maxMessageLength / 1024 / 1024) << " MB";
+
+ BOOST_THROW_EXCEPTION(std::invalid_argument(errorMessage.str()));
+ }
+
char *data = context.Buffer + header_length + 1;
if (context.Size < header_length + 1 + data_length) {
class NetString
{
public:
- static StreamReadStatus ReadStringFromStream(const Stream::Ptr& stream, String *message, StreamReadContext& context, bool may_wait = false);
+ static StreamReadStatus ReadStringFromStream(const Stream::Ptr& stream, String *message, StreamReadContext& context,
+ bool may_wait = false, ssize_t maxMessageLength = -1);
static size_t WriteStringToStream(const Stream::Ptr& stream, const String& message);
static void WriteStringToStream(std::ostream& stream, const String& message);
return NetString::WriteStringToStream(stream, json);
}
-StreamReadStatus JsonRpc::ReadMessage(const Stream::Ptr& stream, String *message, StreamReadContext& src, bool may_wait)
+StreamReadStatus JsonRpc::ReadMessage(const Stream::Ptr& stream, String *message, StreamReadContext& src, bool may_wait, size_t maxMessageLength)
{
String jsonString;
- StreamReadStatus srs = NetString::ReadStringFromStream(stream, &jsonString, src, may_wait);
+ StreamReadStatus srs = NetString::ReadStringFromStream(stream, &jsonString, src, may_wait, maxMessageLength);
if (srs != StatusNewItem)
return srs;
{
public:
static size_t SendMessage(const Stream::Ptr& stream, const Dictionary::Ptr& message);
- static StreamReadStatus ReadMessage(const Stream::Ptr& stream, String *message, StreamReadContext& src, bool may_wait = false);
+ static StreamReadStatus ReadMessage(const Stream::Ptr& stream, String *message, StreamReadContext& src, bool may_wait = false, size_t maxMessageLength = -1);
static Dictionary::Ptr DecodeMessage(const String& message);
private:
bool JsonRpcConnection::ProcessMessage()
{
+ ssize_t maxMessageLength = 64 * 1024;
+
+ if (m_Endpoint)
+ maxMessageLength = -1; /* no limit */
+
String message;
- StreamReadStatus srs = JsonRpc::ReadMessage(m_Stream, &message, m_Context, false);
+ StreamReadStatus srs = JsonRpc::ReadMessage(m_Stream, &message, m_Context, false, maxMessageLength);
if (srs != StatusNewItem)
return false;