diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2021-02-24 21:16:48 +0300 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2021-02-24 21:48:54 +0300 |
commit | a64964a2219bdfe5906b9de3838d0b97e1b1edb5 (patch) | |
tree | c2ddeeeecfda89eb6883dcef494a141c65a095f3 | |
parent | add README.md (diff) | |
download | winapi-common-a64964a2219bdfe5906b9de3838d0b97e1b1edb5.tar.gz winapi-common-a64964a2219bdfe5906b9de3838d0b97e1b1edb5.zip |
use SafeInt to make integers a bit more safe
-rw-r--r-- | .clang-format | 8 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
m--------- | 3rdparty/microsoft/SafeInt | 0 | ||||
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | include/winapi/buffer.hpp | 16 | ||||
-rw-r--r-- | src/cmd_line.cpp | 25 |
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) { |