aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Weingärtner <timo@tiwe.de>2013-07-19 21:35:50 +0200
committerTimo Weingärtner <timo@tiwe.de>2013-07-19 22:30:27 +0200
commitf2fe95a2720e31b66dc60c1109b05af7475f35db (patch)
tree7095338db81c3dcb567e53d986bb6749438aa0b5
parent6bc571e8e273f2c1efd12f83f43bb56f07242d32 (diff)
downloadssh-agent-filter-f2fe95a2720e31b66dc60c1109b05af7475f35db.tar.gz
rfc4251string: add length checks
-rw-r--r--rfc4251.h13
1 files changed, 13 insertions, 0 deletions
diff --git a/rfc4251.h b/rfc4251.h
index 3f442f1..c15d2c7 100644
--- a/rfc4251.h
+++ b/rfc4251.h
@@ -31,6 +31,7 @@
#include <vector>
#include <string>
#include <iostream>
+#include <limits>
#include <arpa/inet.h> // ntohl() / htonl()
#include <gmpxx.h>
@@ -186,13 +187,19 @@ inline rfc4251string::rfc4251string (char const * s) {
}
inline rfc4251string::rfc4251string (char const * s, size_t l) {
+ if (l > std::numeric_limits<uint32_t>::max())
+ throw std::length_error{"32-bit limit for rfc4251string exceeded"};
value.insert(value.end(), s, s + l);
}
inline rfc4251string::rfc4251string (std::vector<std::string> const & v) {
if (v.size()) {
+ if (v.begin()->size() > std::numeric_limits<uint32_t>::max())
+ throw std::length_error{"32-bit limit for rfc4251string exceeded"};
value.assign(v.begin()->data(), v.begin()->data() + v.begin()->size());
for (auto it = v.begin() + 1; it != v.end(); ++it) {
+ if (value.size() + 1 + it->size() > std::numeric_limits<uint32_t>::max())
+ throw std::length_error{"32-bit limit for rfc4251string exceeded"};
value.push_back(',');
value.insert(value.end(), it->data(), it->data() + it->size());
}
@@ -205,6 +212,8 @@ inline rfc4251string::rfc4251string (mpz_srcptr x) {
ssize_t bits = mpz_sizeinbase(x, 2);
ssize_t bytes = (bits + 7) / 8;
ssize_t extrabyte = bits % 8 ? 0 : 1; // need extra byte if MSB is 1 to keep it non-negative
+ if (bytes + extrabyte > std::numeric_limits<uint32_t>::max())
+ throw std::length_error{"32-bit limit for rfc4251string exceeded"};
value.resize(bytes + extrabyte);
value[0] = 0;
mpz_export(value.data() + extrabyte, nullptr, 1, 1, 1, 0, x);
@@ -215,6 +224,8 @@ inline rfc4251string::rfc4251string (mpz_srcptr x) {
ssize_t bits = mpz_sizeinbase(x, 2);
ssize_t bytes = (bits + 7) / 8;
ssize_t extrabyte = bits % 8 ? 0 : 1; // need extra byte if MSB is 1 (0 after ^= below) to keep it negative
+ if (bytes + extrabyte > std::numeric_limits<uint32_t>::max())
+ throw std::length_error{"32-bit limit for rfc4251string exceeded"};
value.resize(bytes + extrabyte);
value[0] = 0;
mpz_export(value.data() + extrabyte, nullptr, 1, 1, 1, 0, x);
@@ -266,6 +277,8 @@ inline std::istream & operator>> (std::istream & is, rfc4251string & s) {
}
inline std::ostream & operator<< (std::ostream & os, rfc4251string const & s) {
+ if (s.value.size() > std::numeric_limits<uint32_t>::max())
+ throw std::length_error{"32-bit limit for rfc4251string exceeded"};
if (os << rfc4251uint32(s.value.size()))
os.write(s.value.data(), s.value.size());
return os;