// Copyright 2019 The MediaPipe Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // A "safe int" is a StrongInt<T> which does additional validation of the // various arithmetic and logical operations, and reacts to overflows and // underflow and invalid operations. You can define the "safe int" types // to react to errors in pre-defined ways or you can define your own policy // classes. // // Usage: // MEDIAPIPE_DEFINE_SAFE_INT_TYPE(Name, NativeType, PolicyType); // // Defines a new StrongInt type named 'Name' in the current namespace with // underflow/overflow checking on all operations, with configurable error // policy. // // Name: The desired name for the new StrongInt typedef. Must be unique // within the current namespace. // NativeType: The primitive integral type this StrongInt will hold, as // defined by std::is_integral (see <type_traits>). // PolicyType: The type of policy used by this StrongInt type. A few // pre-built policy types are provided here, but the caller can // define any custom policy they desire. // // PolicyTypes: // LogFatalOnError: ABSL_LOG(FATAL) when a error occurs. #ifndef MEDIAPIPE_DEPS_SAFE_INT_H_ #define MEDIAPIPE_DEPS_SAFE_INT_H_ #include <limits.h> #include <cstdint> #include <limits> #include <type_traits> #include "absl/log/absl_check.h" #include "absl/log/absl_log.h" #include "mediapipe/framework/deps/strong_int.h" namespace mediapipe { namespace intops { // A StrongInt validator class for "safe" type enforcement. For signed types, // this checks for overflows and underflows as well as undefined- or // implementation-defined behaviors. For unsigned type, this further disallows // operations that would take advantage of unsigned wrap-around behavior and // operations which would discard data unexpectedly. This assumes two's // complement representations, and that division truncates towards zero. // // For some more on overflow safety, see: // https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow?showComments=false template <typename ErrorType> class SafeIntStrongIntValidator { … }; // A SafeIntStrongIntValidator policy class to ABSL_LOG(FATAL) on errors. struct LogFatalOnError { … }; } // namespace intops } // namespace mediapipe // Defines the StrongInt using value_type and typedefs it to type_name, with // strong checking of under/overflow conditions. // The struct int_type_name ## _tag_ trickery is needed to ensure that a new // type is created per type_name. #define MEDIAPIPE_DEFINE_SAFE_INT_TYPE(type_name, value_type, policy_type) … #endif // MEDIAPIPE_DEPS_SAFE_INT_H_