Add a way to limit deserialized string lengths
and use it for most strings being serialized.
This commit is contained in:
parent
003bbd5f76
commit
216e9a4456
4 changed files with 46 additions and 14 deletions
|
@ -60,9 +60,9 @@ public:
|
||||||
READWRITE(setSubVer);
|
READWRITE(setSubVer);
|
||||||
READWRITE(nPriority);
|
READWRITE(nPriority);
|
||||||
|
|
||||||
READWRITE(strComment);
|
READWRITE(LIMITED_STRING(strComment, 65536));
|
||||||
READWRITE(strStatusBar);
|
READWRITE(LIMITED_STRING(strStatusBar, 256));
|
||||||
READWRITE(strReserved);
|
READWRITE(LIMITED_STRING(strReserved, 256));
|
||||||
)
|
)
|
||||||
|
|
||||||
void SetNull();
|
void SetNull();
|
||||||
|
|
|
@ -3559,7 +3559,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||||
if (!vRecv.empty())
|
if (!vRecv.empty())
|
||||||
vRecv >> addrFrom >> nNonce;
|
vRecv >> addrFrom >> nNonce;
|
||||||
if (!vRecv.empty()) {
|
if (!vRecv.empty()) {
|
||||||
vRecv >> pfrom->strSubVer;
|
vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
|
||||||
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
|
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
|
||||||
}
|
}
|
||||||
if (!vRecv.empty())
|
if (!vRecv.empty())
|
||||||
|
@ -4183,7 +4183,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||||
if (fDebug)
|
if (fDebug)
|
||||||
{
|
{
|
||||||
string strMsg; unsigned char ccode; string strReason;
|
string strMsg; unsigned char ccode; string strReason;
|
||||||
vRecv >> strMsg >> ccode >> strReason;
|
vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, 111);
|
||||||
|
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
|
ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
|
||||||
|
@ -4194,10 +4194,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||||
vRecv >> hash;
|
vRecv >> hash;
|
||||||
ss << ": hash " << hash.ToString();
|
ss << ": hash " << hash.ToString();
|
||||||
}
|
}
|
||||||
// Truncate to reasonable length and sanitize before printing:
|
LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
|
||||||
string s = ss.str();
|
|
||||||
if (s.size() > 111) s.erase(111, string::npos);
|
|
||||||
LogPrint("net", "Reject %s\n", SanitizeString(s));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -336,6 +336,7 @@ I ReadVarInt(Stream& is)
|
||||||
|
|
||||||
#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
|
#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
|
||||||
#define VARINT(obj) REF(WrapVarInt(REF(obj)))
|
#define VARINT(obj) REF(WrapVarInt(REF(obj)))
|
||||||
|
#define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
|
||||||
|
|
||||||
/** Wrapper for serializing arrays and POD.
|
/** Wrapper for serializing arrays and POD.
|
||||||
*/
|
*/
|
||||||
|
@ -398,6 +399,40 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<size_t Limit>
|
||||||
|
class LimitedString
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
std::string& string;
|
||||||
|
public:
|
||||||
|
LimitedString(std::string& string) : string(string) {}
|
||||||
|
|
||||||
|
template<typename Stream>
|
||||||
|
void Unserialize(Stream& s, int, int=0)
|
||||||
|
{
|
||||||
|
size_t size = ReadCompactSize(s);
|
||||||
|
if (size > Limit) {
|
||||||
|
throw std::ios_base::failure("String length limit exceeded");
|
||||||
|
}
|
||||||
|
string.resize(size);
|
||||||
|
if (size != 0)
|
||||||
|
s.read((char*)&string[0], size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream>
|
||||||
|
void Serialize(Stream& s, int, int=0) const
|
||||||
|
{
|
||||||
|
WriteCompactSize(s, string.size());
|
||||||
|
if (!string.empty())
|
||||||
|
s.write((char*)&string[0], string.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int GetSerializeSize(int, int=0) const
|
||||||
|
{
|
||||||
|
return GetSizeOfCompactSize(string.size()) + string.size();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<typename I>
|
template<typename I>
|
||||||
CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
|
CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
|
||||||
|
|
||||||
|
|
|
@ -858,7 +858,7 @@ public:
|
||||||
READWRITE(vchPrivKey);
|
READWRITE(vchPrivKey);
|
||||||
READWRITE(nTimeCreated);
|
READWRITE(nTimeCreated);
|
||||||
READWRITE(nTimeExpires);
|
READWRITE(nTimeExpires);
|
||||||
READWRITE(strComment);
|
READWRITE(LIMITED_STRING(strComment, 65536));
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -933,7 +933,7 @@ public:
|
||||||
// Note: strAccount is serialized as part of the key, not here.
|
// Note: strAccount is serialized as part of the key, not here.
|
||||||
READWRITE(nCreditDebit);
|
READWRITE(nCreditDebit);
|
||||||
READWRITE(nTime);
|
READWRITE(nTime);
|
||||||
READWRITE(strOtherAccount);
|
READWRITE(LIMITED_STRING(strOtherAccount, 65536));
|
||||||
|
|
||||||
if (!fRead)
|
if (!fRead)
|
||||||
{
|
{
|
||||||
|
@ -949,7 +949,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
READWRITE(strComment);
|
READWRITE(LIMITED_STRING(strComment, 65536));
|
||||||
|
|
||||||
size_t nSepPos = strComment.find("\0", 0, 1);
|
size_t nSepPos = strComment.find("\0", 0, 1);
|
||||||
if (fRead)
|
if (fRead)
|
||||||
|
|
Loading…
Reference in a new issue