Coverage Report

Created: 2023-06-07 07:00

/src/botan/build/include/botan/internal/safeint.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Safe(r) Integer Handling
3
* (C) 2016 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#ifndef BOTAN_UTILS_SAFE_INT_H_
9
#define BOTAN_UTILS_SAFE_INT_H_
10
11
#include <botan/exceptn.h>
12
#include <botan/internal/fmt.h>
13
#include <optional>
14
#include <string_view>
15
16
#if defined(_MSC_VER)
17
   #include <intsafe.h>
18
#endif
19
20
namespace Botan {
21
22
class Integer_Overflow_Detected final : public Exception {
23
   public:
24
      Integer_Overflow_Detected(std::string_view file, int line) :
25
0
            Exception(fmt("Integer overflow detected at {}:{}", file, line)) {}
26
27
0
      ErrorType error_type() const noexcept override { return ErrorType::InternalError; }
28
};
29
30
721k
inline size_t checked_add(size_t x, size_t y, const char* file, int line) {
31
721k
#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_add_overflow)
32
721k
   size_t z;
33
721k
   if(__builtin_add_overflow(x, y, &z)) [[unlikely]]
34
#elif defined(_MSC_VER)
35
   size_t z;
36
   if(SizeTAdd(x, y, &z) != S_OK) [[unlikely]]
37
#else
38
   size_t z = x + y;
39
   if(z < x) [[unlikely]]
40
#endif
41
0
   {
42
0
      throw Integer_Overflow_Detected(file, line);
43
0
   }
44
721k
   return z;
45
721k
}
46
47
38.4M
inline std::optional<size_t> checked_mul(size_t x, size_t y) {
48
38.4M
#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_add_overflow)
49
38.4M
   size_t z;
50
38.4M
   if(__builtin_mul_overflow(x, y, &z)) [[unlikely]]
51
#elif defined(_MSC_VER)
52
   size_t z;
53
   if(SizeTMult(x, y, &z) != S_OK) [[unlikely]]
54
#else
55
   size_t z = x * y;
56
   if(y && z / y != x) [[unlikely]]
57
#endif
58
0
   {
59
0
      return std::nullopt;
60
0
   }
61
38.4M
   return z;
62
38.4M
}
63
64
template <typename RT, typename AT>
65
RT checked_cast_to(AT i) {
66
   RT c = static_cast<RT>(i);
67
   if(i != static_cast<AT>(c))
68
      throw Internal_Error("Error during integer conversion");
69
   return c;
70
}
71
72
722k
#define BOTAN_CHECKED_ADD(x, y) checked_add(x, y, __FILE__, __LINE__)
73
38.4M
#define BOTAN_CHECKED_MUL(x, y) checked_mul(x, y)
74
75
}  // namespace Botan
76
77
#endif