Coverage Report

Created: 2026-09-14 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openexr/src/lib/OpenEXR/ImfCheckedArithmetic.h
Line
Count
Source
1
//
2
// SPDX-License-Identifier: BSD-3-Clause
3
// Copyright (c) Contributors to the OpenEXR Project.
4
//
5
6
#ifndef INCLUDED_IMF_CHECKED_ARITHMETIC_H
7
#define INCLUDED_IMF_CHECKED_ARITHMETIC_H
8
9
//-----------------------------------------------------------------------------
10
//
11
//  Integer arithmetic operations that throw exceptions
12
//      on overflow, underflow or division by zero.
13
//
14
//-----------------------------------------------------------------------------
15
16
#include "ImfNamespace.h"
17
18
#include "IexMathExc.h"
19
20
#include <limits>
21
22
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
23
24
template <bool b> struct StaticAssertionFailed;
25
template <> struct StaticAssertionFailed<true>
26
{};
27
28
#define IMF_STATIC_ASSERT(x)                                                   \
29
3.60k
    do                                                                         \
30
3.60k
    {                                                                          \
31
3.60k
        StaticAssertionFailed<x> staticAssertionFailed;                        \
32
3.60k
        ((void) staticAssertionFailed);                                        \
33
3.60k
    } while (false)
34
35
template <class T>
36
inline T
37
uiMult (T a, T b)
38
1.20k
{
39
    //
40
    // Unsigned integer multiplication
41
    //
42
43
1.20k
    IMF_STATIC_ASSERT (
44
1.20k
        !std::numeric_limits<T>::is_signed &&
45
1.20k
        std::numeric_limits<T>::is_integer);
46
47
1.20k
    if (a > 0 && b > std::numeric_limits<T>::max () / a)
48
0
        throw IEX_NAMESPACE::OverflowExc ("Integer multiplication overflow.");
49
50
1.20k
    return a * b;
51
1.20k
}
unsigned int Imf_3_4::uiMult<unsigned int>(unsigned int, unsigned int)
Line
Count
Source
38
1.20k
{
39
    //
40
    // Unsigned integer multiplication
41
    //
42
43
1.20k
    IMF_STATIC_ASSERT (
44
1.20k
        !std::numeric_limits<T>::is_signed &&
45
1.20k
        std::numeric_limits<T>::is_integer);
46
47
1.20k
    if (a > 0 && b > std::numeric_limits<T>::max () / a)
48
0
        throw IEX_NAMESPACE::OverflowExc ("Integer multiplication overflow.");
49
50
1.20k
    return a * b;
51
1.20k
}
Unexecuted instantiation: unsigned long Imf_3_4::uiMult<unsigned long>(unsigned long, unsigned long)
52
53
template <class T>
54
inline T
55
uiDiv (T a, T b)
56
{
57
    //
58
    // Unsigned integer division
59
    //
60
61
    IMF_STATIC_ASSERT (
62
        !std::numeric_limits<T>::is_signed &&
63
        std::numeric_limits<T>::is_integer);
64
65
    if (b == 0) throw IEX_NAMESPACE::DivzeroExc ("Integer division by zero.");
66
67
    return a / b;
68
}
69
70
template <class T>
71
inline T
72
uiAdd (T a, T b)
73
{
74
    //
75
    // Unsigned integer addition
76
    //
77
78
    IMF_STATIC_ASSERT (
79
        !std::numeric_limits<T>::is_signed &&
80
        std::numeric_limits<T>::is_integer);
81
82
    if (a > std::numeric_limits<T>::max () - b)
83
        throw IEX_NAMESPACE::OverflowExc ("Integer addition overflow.");
84
85
    return a + b;
86
}
87
88
template <class T>
89
inline T
90
uiSub (T a, T b)
91
{
92
    //
93
    // Unsigned integer subtraction
94
    //
95
96
    IMF_STATIC_ASSERT (
97
        !std::numeric_limits<T>::is_signed &&
98
        std::numeric_limits<T>::is_integer);
99
100
    if (a < b)
101
        throw IEX_NAMESPACE::UnderflowExc ("Integer subtraction underflow.");
102
103
    return a - b;
104
}
105
106
template <class T>
107
inline size_t
108
checkArraySize (T n, size_t s)
109
1.20k
{
110
    //
111
    // Verify that the size, in bytes, of an array with n elements
112
    // of size s can be computed without overflowing:
113
    //
114
    // If computing
115
    //
116
    //      size_t (n) * s
117
    //
118
    // would overflow, then throw an IEX_NAMESPACE::OverflowExc exception.
119
    // Otherwise return
120
    //
121
    //      size_t (n).
122
    //
123
124
1.20k
    IMF_STATIC_ASSERT (
125
1.20k
        !std::numeric_limits<T>::is_signed &&
126
1.20k
        std::numeric_limits<T>::is_integer);
127
128
1.20k
    IMF_STATIC_ASSERT (sizeof (T) <= sizeof (size_t));
129
130
1.20k
    if (size_t (n) > std::numeric_limits<size_t>::max () / s)
131
0
        throw IEX_NAMESPACE::OverflowExc ("Integer multiplication overflow.");
132
133
1.20k
    return size_t (n);
134
1.20k
}
135
136
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
137
138
#endif