Skip to content

Commit

Permalink
Merge pull request #270 from OutpostUniverse/addStreamSizeChecks
Browse files Browse the repository at this point in the history
Add stream size checks
  • Loading branch information
DanRStevens authored Mar 5, 2019
2 parents aafd60a + 0f6bedb commit e11ca13
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/Stream/Reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ namespace Stream
// passing vector into this function to ensure proper vector size is read
template<typename T, typename A>
inline void Read(std::vector<T, A>& vector) {
// Size calculation can't possibly overflow since the vector size necessarily fits in memory
ReadImplementation(vector.data(), vector.size() * sizeof(T));
}

Expand All @@ -52,9 +53,14 @@ namespace Stream
void Read(std::vector<T, A>& vector) {
SizeType vectorSize;
Read(vectorSize);
// This check is trivially false for unsigned SizeType
if (vectorSize < 0) {
throw std::runtime_error("Vector's size may not be a negative number");
}
// This check may be trivially false when SizeType is much smaller than max vector size
if (vectorSize > vector.max_size()) {
throw std::runtime_error("Vector's size is too big to fit in memory");
}
vector.clear();
vector.resize(vectorSize);
Read(vector);
Expand All @@ -65,6 +71,7 @@ namespace Stream
// passing string into this function to ensure proper string size is read
template<typename CharT, typename Traits, typename Allocator>
void Read(std::basic_string<CharT, Traits, Allocator>& string) {
// Size calculation can't possibly overflow since the string size necessarily fits in memory
Read(&string[0], string.size() * sizeof(CharT));
}

Expand All @@ -74,9 +81,14 @@ namespace Stream
void Read(std::basic_string<CharT, Traits, Allocator>& string) {
SizeType stringSize;
Read(stringSize);
// This check is trivially false for unsigned SizeType
if (stringSize < 0) {
throw std::runtime_error("String's size may not be a negative number");
}
// This check may be trivially false when SizeType is too small to overflow string size for CharT types
if (stringSize > string.max_size()) {
throw std::runtime_error("String's size is too big to fit in memory");
}

string.clear();
string.resize(stringSize);
Expand Down
6 changes: 6 additions & 0 deletions src/Stream/Writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace Stream
// Vector data types
template<typename T, typename A>
inline void Write(const std::vector<T, A>& vector) {
// Size calculation can't possibly overflow since the vector size necessarily fits in memory
WriteImplementation(vector.data(), vector.size() * sizeof(T));
}

Expand All @@ -46,9 +47,11 @@ namespace Stream
template<typename SizeType, typename T, typename A>
void Write(const std::vector<T, A>& vector) {
auto vectorSize = vector.size();
// This check is trivially false if SizeType is larger than max vector size
if (vectorSize > std::numeric_limits<SizeType>::max()) {
throw std::runtime_error("Vector too large to save size field");
}
// This can't overflow due to check above
auto typedSize = static_cast<SizeType>(vectorSize);
Write(typedSize);
Write(vector);
Expand All @@ -58,6 +61,7 @@ namespace Stream
// Does not write null terminator unless specifically included in string
template<typename CharT, typename Traits, typename Allocator>
void Write(const std::basic_string<CharT, Traits, Allocator>& string) {
// Size calculation can't possibly overflow since the string size necessarily fits in memory
Write(&string[0], string.size() * sizeof(CharT));
}

Expand All @@ -67,9 +71,11 @@ namespace Stream
template<typename SizeType, typename CharT, typename Traits, typename Allocator>
void Write(const std::basic_string<CharT, Traits, Allocator>& string) {
auto stringSize = string.size();
// This check is trivially false if SizeType is larger than max string size
if (stringSize > std::numeric_limits<SizeType>::max()) {
throw std::runtime_error("String's size is too large to write in provided size field");
}
// This can't overflow due to check above
Write(static_cast<SizeType>(stringSize));
Write(string);
}
Expand Down

0 comments on commit e11ca13

Please sign in to comment.