@@ -30,6 +30,7 @@ documentation.
3030#include < cstddef>
3131#include < cstdint>
3232#include < cstring>
33+ #include < limits>
3334#include < string>
3435#include < utility>
3536
@@ -139,6 +140,20 @@ class pbf_reader {
139140 T{m_data, m_data}};
140141 }
141142
143+ // Adds size to ptr safely, and returning ptr if overflow would occur.
144+ const char * safe_ptr_add (const char * ptr, size_t length) {
145+ #if defined __has_builtin
146+ #if __has_builtin(__builtin_add_overflow)
147+ uintptr_t result;
148+ return __builtin_add_overflow (reinterpret_cast <uintptr_t >(ptr), length, &result) ? ptr : reinterpret_cast <const char *>(result);
149+ #endif
150+ #endif
151+ if (length > std::numeric_limits<uintptr_t >::max () - reinterpret_cast <uintptr_t >(ptr)) {
152+ return ptr;
153+ }
154+ return ptr + length;
155+ }
156+
142157public:
143158
144159 /* *
@@ -153,7 +168,7 @@ class pbf_reader {
153168 */
154169 explicit pbf_reader (const data_view& view) noexcept
155170 : m_data{view.data ()},
156- m_end{view.data () + view.size ()} {
171+ m_end{safe_ptr_add ( view.data (), view.size () )} {
157172 }
158173
159174 /* *
@@ -168,7 +183,7 @@ class pbf_reader {
168183 */
169184 pbf_reader (const char * data, std::size_t size) noexcept
170185 : m_data{data},
171- m_end{data + size} {
186+ m_end{safe_ptr_add ( data, size) } {
172187 }
173188
174189#ifndef PROTOZERO_STRICT_API
@@ -185,7 +200,7 @@ class pbf_reader {
185200 */
186201 explicit pbf_reader (const std::pair<const char *, std::size_t >& data) noexcept
187202 : m_data{data.first },
188- m_end{data.first + data.second } {
203+ m_end{safe_ptr_add ( data.first , data.second ) } {
189204 }
190205#endif
191206
@@ -201,7 +216,7 @@ class pbf_reader {
201216 */
202217 explicit pbf_reader (const std::string& data) noexcept
203218 : m_data{data.data ()},
204- m_end{data.data () + data.size ()} {
219+ m_end{safe_ptr_add ( data.data (), data.size () )} {
205220 }
206221
207222 /* *
0 commit comments