aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2021-02-24 21:16:48 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2021-02-24 21:48:54 +0300
commita64964a2219bdfe5906b9de3838d0b97e1b1edb5 (patch)
treec2ddeeeecfda89eb6883dcef494a141c65a095f3
parentadd README.md (diff)
downloadwinapi-common-a64964a2219bdfe5906b9de3838d0b97e1b1edb5.tar.gz
winapi-common-a64964a2219bdfe5906b9de3838d0b97e1b1edb5.zip
use SafeInt to make integers a bit more safe
-rw-r--r--.clang-format8
-rw-r--r--.gitmodules3
m---------3rdparty/microsoft/SafeInt0
-rw-r--r--CMakeLists.txt5
-rw-r--r--include/winapi/buffer.hpp16
-rw-r--r--src/cmd_line.cpp25
6 files changed, 38 insertions, 19 deletions
diff --git a/.clang-format b/.clang-format
index 4e77355..2f5ef0e 100644
--- a/.clang-format
+++ b/.clang-format
@@ -15,10 +15,12 @@ IncludeCategories:
Priority: 1
- Regex: '^<(winapi)/'
Priority: 2
- - Regex: '^<boost\/'
+ - Regex: '^<SafeInt\.hpp>$'
Priority: 3
- - Regex: '^<.*\.h>$'
+ - Regex: '^<boost\/'
Priority: 4
- - Regex: '.*'
+ - Regex: '^<.*\.h>$'
Priority: 5
+ - Regex: '.*'
+ Priority: 6
...
diff --git a/.gitmodules b/.gitmodules
index 9ea0616..99998f2 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,6 @@
[submodule "3rdparty/winapi/utf8"]
path = 3rdparty/winapi/utf8
url = https://github.com/egor-tensin/winapi-utf8.git
+[submodule "3rdparty/microsoft/SafeInt"]
+ path = 3rdparty/microsoft/SafeInt
+ url = https://github.com/dcleblanc/SafeInt.git
diff --git a/3rdparty/microsoft/SafeInt b/3rdparty/microsoft/SafeInt
new file mode 160000
+Subproject a5408ba2c025ec99a7afb6ccca907d5a263242a
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c4a839b..c6a4357 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,6 +12,11 @@ target_include_directories(winapi_common PUBLIC include)
add_subdirectory(3rdparty/winapi/utf8 EXCLUDE_FROM_ALL)
target_link_libraries(winapi_common PRIVATE winapi_utf8)
+if(NOT TARGET SafeInt)
+ add_subdirectory(3rdparty/microsoft/SafeInt EXCLUDE_FROM_ALL)
+endif()
+target_link_libraries(winapi_common PUBLIC SafeInt)
+
find_package(Boost REQUIRED)
target_link_libraries(winapi_common PUBLIC Boost::boost)
diff --git a/include/winapi/buffer.hpp b/include/winapi/buffer.hpp
index 7c8f928..11d029f 100644
--- a/include/winapi/buffer.hpp
+++ b/include/winapi/buffer.hpp
@@ -5,6 +5,8 @@
#pragma once
+#include <SafeInt.hpp>
+
#include <cstddef>
#include <cstring>
#include <initializer_list>
@@ -35,7 +37,11 @@ public:
template <typename CharT>
void set(const std::basic_string<CharT>& src) {
- set(src.c_str(), src.length() * sizeof(std::basic_string<CharT>::char_type));
+ std::size_t new_size = 0;
+ if (!SafeMultiply(src.length(), sizeof(std::basic_string<CharT>::char_type), new_size)) {
+ throw std::runtime_error{"Destination buffer size is too large"};
+ }
+ set(src.c_str(), new_size);
}
void set(const void* src, std::size_t nb) {
@@ -64,7 +70,13 @@ public:
void add(const Buffer& src) {
const auto nb = size();
- resize(size() + src.size());
+ {
+ std::size_t new_size = 0;
+ if (!SafeAdd(size(), src.size(), new_size)) {
+ throw std::runtime_error{"Destination buffer size is too large"};
+ }
+ resize(new_size);
+ }
std::memcpy(data() + nb, src.data(), src.size());
}
};
diff --git a/src/cmd_line.cpp b/src/cmd_line.cpp
index d3dc781..238e0bc 100644
--- a/src/cmd_line.cpp
+++ b/src/cmd_line.cpp
@@ -8,6 +8,8 @@
#include <winapi/utf8.hpp>
#include <winapi/utils.hpp>
+#include <SafeInt.hpp>
+
#include <boost/algorithm/string.hpp>
#include <boost/config.hpp>
@@ -96,40 +98,35 @@ CommandLine::CommandLine(std::vector<std::string>&& argv) : m_args(std::move(arg
}
std::string CommandLine::escape(const std::string& arg) {
- std::string safe;
- // Including the quotes:
- safe.reserve(arg.length() + 2);
-
- safe.push_back('"');
+ std::ostringstream safe;
+ safe << '"';
for (auto it = arg.cbegin(); it != arg.cend(); ++it) {
- std::size_t numof_backslashes = 0;
+ SafeInt<std::size_t> numof_backslashes{0};
for (; it != arg.cend() && *it == '\\'; ++it)
++numof_backslashes;
if (it == arg.cend()) {
- safe.reserve(safe.capacity() + numof_backslashes);
- safe.append(2 * numof_backslashes, '\\');
+ safe << std::string(2 * numof_backslashes, '\\');
break;
}
switch (*it) {
case L'"':
- safe.reserve(safe.capacity() + numof_backslashes + 1);
- safe.append(2 * numof_backslashes + 1, '\\');
+ safe << std::string(2 * numof_backslashes + 1, '\\');
break;
default:
- safe.append(numof_backslashes, '\\');
+ safe << std::string(numof_backslashes, '\\');
break;
}
- safe.push_back(*it);
+ safe << *it;
}
- safe.push_back('"');
- return safe;
+ safe << '"';
+ return safe.str();
}
std::string CommandLine::escape_cmd(const std::string& arg) {