mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-19 00:46:03 +01:00
Net: make MessageHeader limits configurable (#3404)
This commit is contained in:
parent
2aaa7f851d
commit
ea03d882f2
@ -100,7 +100,27 @@ public:
|
||||
/// Specify 0 for unlimited (not recommended).
|
||||
///
|
||||
/// The default limit is 100.
|
||||
|
||||
|
||||
int getNameLengthLimit() const;
|
||||
/// Returns the maximum length of a field name.
|
||||
///
|
||||
/// See setNameLengthLimit() for more information.
|
||||
|
||||
void setNameLengthLimit(int limit);
|
||||
/// Sets the maximum length of a field name.
|
||||
///
|
||||
/// The default limit is 256.
|
||||
|
||||
int getValueLengthLimit() const;
|
||||
/// Returns the maximum length of a field value.
|
||||
///
|
||||
/// See setValueLengthLimit() for more information.
|
||||
|
||||
void setValueLengthLimit(int limit);
|
||||
/// Sets the maximum length of a field value.
|
||||
///
|
||||
/// The default limit is 8192.
|
||||
|
||||
bool hasToken(const std::string& fieldName, const std::string& token) const;
|
||||
/// Returns true iff the field with the given fieldName contains
|
||||
/// the given token. Tokens in a header field are expected to be
|
||||
@ -154,12 +174,15 @@ private:
|
||||
enum Limits
|
||||
/// Limits for basic sanity checks when reading a header
|
||||
{
|
||||
MAX_NAME_LENGTH = 256,
|
||||
MAX_VALUE_LENGTH = 8192,
|
||||
DFL_FIELD_LIMIT = 100
|
||||
DFL_NAME_LENGTH_LIMIT = 256,
|
||||
DFL_VALUE_LENGTH_LIMIT = 8192,
|
||||
DFL_FIELD_LIMIT = 100
|
||||
};
|
||||
|
||||
int _fieldLimit;
|
||||
int _nameLengthLimit;
|
||||
int _valueLengthLimit;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -28,14 +28,18 @@ namespace Net {
|
||||
|
||||
|
||||
MessageHeader::MessageHeader():
|
||||
_fieldLimit(DFL_FIELD_LIMIT)
|
||||
_fieldLimit(DFL_FIELD_LIMIT),
|
||||
_nameLengthLimit(DFL_NAME_LENGTH_LIMIT),
|
||||
_valueLengthLimit(DFL_VALUE_LENGTH_LIMIT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MessageHeader::MessageHeader(const MessageHeader& messageHeader):
|
||||
NameValueCollection(messageHeader),
|
||||
_fieldLimit(DFL_FIELD_LIMIT)
|
||||
_fieldLimit(DFL_FIELD_LIMIT),
|
||||
_nameLengthLimit(DFL_NAME_LENGTH_LIMIT),
|
||||
_valueLengthLimit(DFL_VALUE_LENGTH_LIMIT)
|
||||
{
|
||||
}
|
||||
|
||||
@ -80,12 +84,12 @@ void MessageHeader::read(std::istream& istr)
|
||||
throw MessageException("Too many header fields");
|
||||
name.clear();
|
||||
value.clear();
|
||||
while (ch != eof && ch != ':' && ch != '\n' && name.length() < MAX_NAME_LENGTH) { name += ch; ch = buf.sbumpc(); }
|
||||
while (ch != eof && ch != ':' && ch != '\n' && name.length() < _nameLengthLimit) { name += ch; ch = buf.sbumpc(); }
|
||||
if (ch == '\n') { ch = buf.sbumpc(); continue; } // ignore invalid header lines
|
||||
if (ch != ':') throw MessageException("Field name too long/no colon found");
|
||||
if (ch != eof) ch = buf.sbumpc(); // ':'
|
||||
while (ch != eof && Poco::Ascii::isSpace(ch) && ch != '\r' && ch != '\n') ch = buf.sbumpc();
|
||||
while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += ch; ch = buf.sbumpc(); }
|
||||
while (ch != eof && ch != '\r' && ch != '\n' && value.length() < _valueLengthLimit) { value += ch; ch = buf.sbumpc(); }
|
||||
if (ch == '\r') ch = buf.sbumpc();
|
||||
if (ch == '\n')
|
||||
ch = buf.sbumpc();
|
||||
@ -93,7 +97,7 @@ void MessageHeader::read(std::istream& istr)
|
||||
throw MessageException("Field value too long/no CRLF found");
|
||||
while (ch == ' ' || ch == '\t') // folding
|
||||
{
|
||||
while (ch != eof && ch != '\r' && ch != '\n' && value.length() < MAX_VALUE_LENGTH) { value += ch; ch = buf.sbumpc(); }
|
||||
while (ch != eof && ch != '\r' && ch != '\n' && value.length() < _valueLengthLimit) { value += ch; ch = buf.sbumpc(); }
|
||||
if (ch == '\r') ch = buf.sbumpc();
|
||||
if (ch == '\n')
|
||||
ch = buf.sbumpc();
|
||||
@ -122,6 +126,32 @@ void MessageHeader::setFieldLimit(int limit)
|
||||
}
|
||||
|
||||
|
||||
int MessageHeader::getNameLengthLimit() const
|
||||
{
|
||||
return _nameLengthLimit;
|
||||
}
|
||||
|
||||
void MessageHeader::setNameLengthLimit(int limit)
|
||||
{
|
||||
poco_assert(limit >= 0);
|
||||
|
||||
_nameLengthLimit = limit;
|
||||
}
|
||||
|
||||
|
||||
int MessageHeader::getValueLengthLimit() const
|
||||
{
|
||||
return _valueLengthLimit;
|
||||
}
|
||||
|
||||
void MessageHeader::setValueLengthLimit(int limit)
|
||||
{
|
||||
poco_assert(limit >= 0);
|
||||
|
||||
_valueLengthLimit = limit;
|
||||
}
|
||||
|
||||
|
||||
bool MessageHeader::hasToken(const std::string& fieldName, const std::string& token) const
|
||||
{
|
||||
std::string field = get(fieldName, "");
|
||||
|
@ -360,6 +360,38 @@ void MessageHeaderTest::testFieldLimit()
|
||||
}
|
||||
|
||||
|
||||
void MessageHeaderTest::testNameLengthLimit()
|
||||
{
|
||||
std::string s("name1: value1\r\n");
|
||||
std::istringstream istr(s);
|
||||
MessageHeader mh;
|
||||
mh.setNameLengthLimit(2);
|
||||
try
|
||||
{
|
||||
mh.read(istr);
|
||||
fail("Name length limit exceeded - must throw");
|
||||
}
|
||||
catch (MessageException&)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void MessageHeaderTest::testValueLengthLimit()
|
||||
{
|
||||
std::string s("name1: value1\r\n");
|
||||
std::istringstream istr(s);
|
||||
MessageHeader mh;
|
||||
mh.setValueLengthLimit(2);
|
||||
try
|
||||
{
|
||||
mh.read(istr);
|
||||
fail("Value length limit exceeded - must throw");
|
||||
}
|
||||
catch (MessageException&)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void MessageHeaderTest::testDecodeWord()
|
||||
{
|
||||
std::string coded("this is pure ASCII");
|
||||
|
@ -40,6 +40,8 @@ public:
|
||||
void testSplitElements();
|
||||
void testSplitParameters();
|
||||
void testFieldLimit();
|
||||
void testNameLengthLimit();
|
||||
void testValueLengthLimit();
|
||||
void testDecodeWord();
|
||||
|
||||
void setUp();
|
||||
|
Loading…
x
Reference in New Issue
Block a user