aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2014-08-07 23:00:01 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2014-08-18 15:34:29 +0200
commita78996503fc5a3e9f80741d6546fdb7eaf18feef (patch)
tree9b6706a60a9a8dc6de52052f2830fb33355a3ea2
parentd78e4312b248661c7a5b10ab0f2cd13e81369cd7 (diff)
downloadbitcoin-a78996503fc5a3e9f80741d6546fdb7eaf18feef.tar.xz
Add a way to limit deserialized string lengths
and use it for most strings being serialized. Rebased-From: 216e9a4
-rw-r--r--src/alert.h6
-rw-r--r--src/main.cpp9
-rw-r--r--src/serialize.h39
-rw-r--r--src/wallet.h6
4 files changed, 46 insertions, 14 deletions
diff --git a/src/alert.h b/src/alert.h
index da140be5e5..296d48891a 100644
--- a/src/alert.h
+++ b/src/alert.h
@@ -60,9 +60,9 @@ public:
READWRITE(setSubVer);
READWRITE(nPriority);
- READWRITE(strComment);
- READWRITE(strStatusBar);
- READWRITE(strReserved);
+ READWRITE(LIMITED_STRING(strComment, 65536));
+ READWRITE(LIMITED_STRING(strStatusBar, 256));
+ READWRITE(LIMITED_STRING(strReserved, 256));
)
void SetNull();
diff --git a/src/main.cpp b/src/main.cpp
index dc38d1159d..a0b6842e7e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -3408,7 +3408,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (!vRecv.empty())
vRecv >> addrFrom >> nNonce;
if (!vRecv.empty()) {
- vRecv >> pfrom->strSubVer;
+ vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
}
if (!vRecv.empty())
@@ -4005,7 +4005,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (fDebug)
{
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;
ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
@@ -4016,10 +4016,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
vRecv >> hash;
ss << ": hash " << hash.ToString();
}
- // Truncate to reasonable length and sanitize before printing:
- string s = ss.str();
- if (s.size() > 111) s.erase(111, string::npos);
- LogPrint("net", "Reject %s\n", SanitizeString(s));
+ LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
}
}
diff --git a/src/serialize.h b/src/serialize.h
index 1341746592..a157048d56 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -306,8 +306,9 @@ I ReadVarInt(Stream& is)
}
}
-#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
-#define VARINT(obj) REF(WrapVarInt(REF(obj)))
+#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
+#define VARINT(obj) REF(WrapVarInt(REF(obj)))
+#define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
/** Wrapper for serializing arrays and POD.
*/
@@ -364,6 +365,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>
CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }
diff --git a/src/wallet.h b/src/wallet.h
index 88ee87196b..2d4b18dccd 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -756,7 +756,7 @@ public:
READWRITE(vchPrivKey);
READWRITE(nTimeCreated);
READWRITE(nTimeExpires);
- READWRITE(strComment);
+ READWRITE(LIMITED_STRING(strComment, 65536));
)
};
@@ -831,7 +831,7 @@ public:
// Note: strAccount is serialized as part of the key, not here.
READWRITE(nCreditDebit);
READWRITE(nTime);
- READWRITE(strOtherAccount);
+ READWRITE(LIMITED_STRING(strOtherAccount, 65536));
if (!fRead)
{
@@ -847,7 +847,7 @@ public:
}
}
- READWRITE(strComment);
+ READWRITE(LIMITED_STRING(strComment, 65536));
size_t nSepPos = strComment.find("\0", 0, 1);
if (fRead)