From a64964a2219bdfe5906b9de3838d0b97e1b1edb5 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Wed, 24 Feb 2021 21:16:48 +0300 Subject: use SafeInt to make integers a bit more safe --- .clang-format | 8 +++++--- .gitmodules | 3 +++ 3rdparty/microsoft/SafeInt | 1 + CMakeLists.txt | 5 +++++ include/winapi/buffer.hpp | 16 ++++++++++++++-- src/cmd_line.cpp | 25 +++++++++++-------------- 6 files changed, 39 insertions(+), 19 deletions(-) create mode 160000 3rdparty/microsoft/SafeInt 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: '^$' Priority: 3 - - Regex: '^<.*\.h>$' + - Regex: '^$' 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 index 0000000..a5408ba --- /dev/null +++ b/3rdparty/microsoft/SafeInt @@ -0,0 +1 @@ +Subproject commit a5408ba2c025ec99a7afb6ccca907d5a263242a5 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 + #include #include #include @@ -35,7 +37,11 @@ public: template void set(const std::basic_string& src) { - set(src.c_str(), src.length() * sizeof(std::basic_string::char_type)); + std::size_t new_size = 0; + if (!SafeMultiply(src.length(), sizeof(std::basic_string::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 #include +#include + #include #include @@ -96,40 +98,35 @@ CommandLine::CommandLine(std::vector&& 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 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) { -- cgit v1.2.3