diff options
| author | Timo Weingärtner <timo@tiwe.de> | 2013-07-19 21:35:50 +0200 | 
|---|---|---|
| committer | Timo Weingärtner <timo@tiwe.de> | 2013-07-19 22:30:27 +0200 | 
| commit | f2fe95a2720e31b66dc60c1109b05af7475f35db (patch) | |
| tree | 7095338db81c3dcb567e53d986bb6749438aa0b5 | |
| parent | 6bc571e8e273f2c1efd12f83f43bb56f07242d32 (diff) | |
| download | ssh-agent-filter-f2fe95a2720e31b66dc60c1109b05af7475f35db.tar.gz | |
rfc4251string: add length checks
| -rw-r--r-- | rfc4251.h | 13 | 
1 files changed, 13 insertions, 0 deletions
| @@ -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; | 
