github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/executor/_include/flatbuffers/base.h (about) 1 #ifndef FLATBUFFERS_BASE_H_ 2 #define FLATBUFFERS_BASE_H_ 3 4 // clang-format off 5 6 // If activate should be declared and included first. 7 #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \ 8 defined(_MSC_VER) && defined(_DEBUG) 9 // The _CRTDBG_MAP_ALLOC inside <crtdbg.h> will replace 10 // calloc/free (etc) to its debug version using #define directives. 11 #define _CRTDBG_MAP_ALLOC 12 #include <stdlib.h> 13 #include <crtdbg.h> 14 // Replace operator new by trace-enabled version. 15 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__) 16 #define new DEBUG_NEW 17 #endif 18 19 #if !defined(FLATBUFFERS_ASSERT) 20 #include <assert.h> 21 #define FLATBUFFERS_ASSERT assert 22 #elif defined(FLATBUFFERS_ASSERT_INCLUDE) 23 // Include file with forward declaration 24 #include FLATBUFFERS_ASSERT_INCLUDE 25 #endif 26 27 #ifndef ARDUINO 28 #include <cstdint> 29 #endif 30 31 #include <cstddef> 32 #include <cstdlib> 33 #include <cstring> 34 35 #if defined(ARDUINO) && !defined(ARDUINOSTL_M_H) 36 #include <utility.h> 37 #else 38 #include <utility> 39 #endif 40 41 #include <string> 42 #include <type_traits> 43 #include <vector> 44 #include <set> 45 #include <algorithm> 46 #include <iterator> 47 #include <memory> 48 49 #if defined(__unix__) && !defined(FLATBUFFERS_LOCALE_INDEPENDENT) 50 #include <unistd.h> 51 #endif 52 53 #ifdef __ANDROID__ 54 #include <android/api-level.h> 55 #endif 56 57 #if defined(__ICCARM__) 58 #include <intrinsics.h> 59 #endif 60 61 // Note the __clang__ check is needed, because clang presents itself 62 // as an older GNUC compiler (4.2). 63 // Clang 3.3 and later implement all of the ISO C++ 2011 standard. 64 // Clang 3.4 and later implement all of the ISO C++ 2014 standard. 65 // http://clang.llvm.org/cxx_status.html 66 67 // Note the MSVC value '__cplusplus' may be incorrect: 68 // The '__cplusplus' predefined macro in the MSVC stuck at the value 199711L, 69 // indicating (erroneously!) that the compiler conformed to the C++98 Standard. 70 // This value should be correct starting from MSVC2017-15.7-Preview-3. 71 // The '__cplusplus' will be valid only if MSVC2017-15.7-P3 and the `/Zc:__cplusplus` switch is set. 72 // Workaround (for details see MSDN): 73 // Use the _MSC_VER and _MSVC_LANG definition instead of the __cplusplus for compatibility. 74 // The _MSVC_LANG macro reports the Standard version regardless of the '/Zc:__cplusplus' switch. 75 76 #if defined(__GNUC__) && !defined(__clang__) 77 #define FLATBUFFERS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 78 #else 79 #define FLATBUFFERS_GCC 0 80 #endif 81 82 #if defined(__clang__) 83 #define FLATBUFFERS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) 84 #else 85 #define FLATBUFFERS_CLANG 0 86 #endif 87 88 /// @cond FLATBUFFERS_INTERNAL 89 #if __cplusplus <= 199711L && \ 90 (!defined(_MSC_VER) || _MSC_VER < 1600) && \ 91 (!defined(__GNUC__) || \ 92 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40400)) 93 #error A C++11 compatible compiler with support for the auto typing is \ 94 required for FlatBuffers. 95 #error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__ 96 #endif 97 98 #if !defined(__clang__) && \ 99 defined(__GNUC__) && \ 100 (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600) 101 // Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr 102 // and constexpr keywords. Note the __clang__ check is needed, because clang 103 // presents itself as an older GNUC compiler. 104 #ifndef nullptr_t 105 const class nullptr_t { 106 public: 107 template<class T> inline operator T*() const { return 0; } 108 private: 109 void operator&() const; 110 } nullptr = {}; 111 #endif 112 #ifndef constexpr 113 #define constexpr const 114 #endif 115 #endif 116 117 // The wire format uses a little endian encoding (since that's efficient for 118 // the common platforms). 119 #if defined(__s390x__) 120 #define FLATBUFFERS_LITTLEENDIAN 0 121 #endif // __s390x__ 122 #if !defined(FLATBUFFERS_LITTLEENDIAN) 123 #if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__) 124 #if (defined(__BIG_ENDIAN__) || \ 125 (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) 126 #define FLATBUFFERS_LITTLEENDIAN 0 127 #else 128 #define FLATBUFFERS_LITTLEENDIAN 1 129 #endif // __BIG_ENDIAN__ 130 #elif defined(_MSC_VER) 131 #if defined(_M_PPC) 132 #define FLATBUFFERS_LITTLEENDIAN 0 133 #else 134 #define FLATBUFFERS_LITTLEENDIAN 1 135 #endif 136 #else 137 #error Unable to determine endianness, define FLATBUFFERS_LITTLEENDIAN. 138 #endif 139 #endif // !defined(FLATBUFFERS_LITTLEENDIAN) 140 141 #define FLATBUFFERS_VERSION_MAJOR 2 142 #define FLATBUFFERS_VERSION_MINOR 0 143 #define FLATBUFFERS_VERSION_REVISION 8 144 #define FLATBUFFERS_STRING_EXPAND(X) #X 145 #define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X) 146 namespace flatbuffers { 147 // Returns version as string "MAJOR.MINOR.REVISION". 148 const char* FLATBUFFERS_VERSION(); 149 } 150 151 #if (!defined(_MSC_VER) || _MSC_VER > 1600) && \ 152 (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \ 153 defined(__clang__) 154 #define FLATBUFFERS_FINAL_CLASS final 155 #define FLATBUFFERS_OVERRIDE override 156 #define FLATBUFFERS_EXPLICIT_CPP11 explicit 157 #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE : flatbuffers::voffset_t 158 #else 159 #define FLATBUFFERS_FINAL_CLASS 160 #define FLATBUFFERS_OVERRIDE 161 #define FLATBUFFERS_EXPLICIT_CPP11 162 #define FLATBUFFERS_VTABLE_UNDERLYING_TYPE 163 #endif 164 165 #if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ 166 (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ 167 (defined(__cpp_constexpr) && __cpp_constexpr >= 200704) 168 #define FLATBUFFERS_CONSTEXPR constexpr 169 #define FLATBUFFERS_CONSTEXPR_CPP11 constexpr 170 #define FLATBUFFERS_CONSTEXPR_DEFINED 171 #else 172 #define FLATBUFFERS_CONSTEXPR const 173 #define FLATBUFFERS_CONSTEXPR_CPP11 174 #endif 175 176 #if (defined(__cplusplus) && __cplusplus >= 201402L) || \ 177 (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) 178 #define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR_CPP11 179 #else 180 #define FLATBUFFERS_CONSTEXPR_CPP14 181 #endif 182 183 #if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \ 184 (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \ 185 defined(__clang__) 186 #define FLATBUFFERS_NOEXCEPT noexcept 187 #else 188 #define FLATBUFFERS_NOEXCEPT 189 #endif 190 191 // NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to 192 // private, so be sure to put it at the end or reset access mode explicitly. 193 #if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \ 194 (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \ 195 defined(__clang__) 196 #define FLATBUFFERS_DELETE_FUNC(func) func = delete 197 #else 198 #define FLATBUFFERS_DELETE_FUNC(func) private: func 199 #endif 200 201 #if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \ 202 (!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ 203 defined(__clang__) 204 #define FLATBUFFERS_DEFAULT_DECLARATION 205 #endif 206 207 // Check if we can use template aliases 208 // Not possible if Microsoft Compiler before 2012 209 // Possible is the language feature __cpp_alias_templates is defined well 210 // Or possible if the C++ std is C+11 or newer 211 #if (defined(_MSC_VER) && _MSC_VER > 1700 /* MSVC2012 */) \ 212 || (defined(__cpp_alias_templates) && __cpp_alias_templates >= 200704) \ 213 || (defined(__cplusplus) && __cplusplus >= 201103L) 214 #define FLATBUFFERS_TEMPLATES_ALIASES 215 #endif 216 217 #ifndef FLATBUFFERS_HAS_STRING_VIEW 218 // Only provide flatbuffers::string_view if __has_include can be used 219 // to detect a header that provides an implementation 220 #if defined(__has_include) 221 // Check for std::string_view (in c++17) 222 #if __has_include(<string_view>) && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17)) 223 #include <string_view> 224 namespace flatbuffers { 225 typedef std::string_view string_view; 226 } 227 #define FLATBUFFERS_HAS_STRING_VIEW 1 228 // Check for std::experimental::string_view (in c++14, compiler-dependent) 229 #elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411) 230 #include <experimental/string_view> 231 namespace flatbuffers { 232 typedef std::experimental::string_view string_view; 233 } 234 #define FLATBUFFERS_HAS_STRING_VIEW 1 235 // Check for absl::string_view 236 #elif __has_include("absl/strings/string_view.h") 237 #include "absl/strings/string_view.h" 238 namespace flatbuffers { 239 typedef absl::string_view string_view; 240 } 241 #define FLATBUFFERS_HAS_STRING_VIEW 1 242 #endif 243 #endif // __has_include 244 #endif // !FLATBUFFERS_HAS_STRING_VIEW 245 246 #ifndef FLATBUFFERS_GENERAL_HEAP_ALLOC_OK 247 // Allow heap allocations to be used 248 #define FLATBUFFERS_GENERAL_HEAP_ALLOC_OK 1 249 #endif // !FLATBUFFERS_GENERAL_HEAP_ALLOC_OK 250 251 #ifndef FLATBUFFERS_HAS_NEW_STRTOD 252 // Modern (C++11) strtod and strtof functions are available for use. 253 // 1) nan/inf strings as argument of strtod; 254 // 2) hex-float as argument of strtod/strtof. 255 #if (defined(_MSC_VER) && _MSC_VER >= 1900) || \ 256 (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || \ 257 (defined(__clang__)) 258 #define FLATBUFFERS_HAS_NEW_STRTOD 1 259 #endif 260 #endif // !FLATBUFFERS_HAS_NEW_STRTOD 261 262 #ifndef FLATBUFFERS_LOCALE_INDEPENDENT 263 // Enable locale independent functions {strtof_l, strtod_l,strtoll_l, 264 // strtoull_l}. 265 #if (defined(_MSC_VER) && _MSC_VER >= 1800) || \ 266 (defined(__ANDROID_API__) && __ANDROID_API__>= 21) || \ 267 (defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 700)) && \ 268 (!defined(__Fuchsia__) && !defined(__ANDROID_API__)) 269 #define FLATBUFFERS_LOCALE_INDEPENDENT 1 270 #else 271 #define FLATBUFFERS_LOCALE_INDEPENDENT 0 272 #endif 273 #endif // !FLATBUFFERS_LOCALE_INDEPENDENT 274 275 // Suppress Undefined Behavior Sanitizer (recoverable only). Usage: 276 // - __suppress_ubsan__("undefined") 277 // - __suppress_ubsan__("signed-integer-overflow") 278 #if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7)) 279 #define __suppress_ubsan__(type) __attribute__((no_sanitize(type))) 280 #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) 281 #define __suppress_ubsan__(type) __attribute__((no_sanitize_undefined)) 282 #else 283 #define __suppress_ubsan__(type) 284 #endif 285 286 // This is constexpr function used for checking compile-time constants. 287 // Avoid `#pragma warning(disable: 4127) // C4127: expression is constant`. 288 template<typename T> FLATBUFFERS_CONSTEXPR inline bool IsConstTrue(T t) { 289 return !!t; 290 } 291 292 // Enable C++ attribute [[]] if std:c++17 or higher. 293 #if ((__cplusplus >= 201703L) \ 294 || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201703L))) 295 // All attributes unknown to an implementation are ignored without causing an error. 296 #define FLATBUFFERS_ATTRIBUTE(attr) attr 297 298 #define FLATBUFFERS_FALLTHROUGH() [[fallthrough]] 299 #else 300 #define FLATBUFFERS_ATTRIBUTE(attr) 301 302 #if FLATBUFFERS_CLANG >= 30800 303 #define FLATBUFFERS_FALLTHROUGH() [[clang::fallthrough]] 304 #elif FLATBUFFERS_GCC >= 70300 305 #define FLATBUFFERS_FALLTHROUGH() [[gnu::fallthrough]] 306 #else 307 #define FLATBUFFERS_FALLTHROUGH() 308 #endif 309 #endif 310 311 /// @endcond 312 313 /// @file 314 namespace flatbuffers { 315 316 /// @cond FLATBUFFERS_INTERNAL 317 // Our default offset / size type, 32bit on purpose on 64bit systems. 318 // Also, using a consistent offset type maintains compatibility of serialized 319 // offset values between 32bit and 64bit systems. 320 typedef uint32_t uoffset_t; 321 322 // Signed offsets for references that can go in both directions. 323 typedef int32_t soffset_t; 324 325 // Offset/index used in v-tables, can be changed to uint8_t in 326 // format forks to save a bit of space if desired. 327 typedef uint16_t voffset_t; 328 329 typedef uintmax_t largest_scalar_t; 330 331 // In 32bits, this evaluates to 2GB - 1 332 #define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1) 333 334 // The minimum size buffer that can be a valid flatbuffer. 335 // Includes the offset to the root table (uoffset_t), the offset to the vtable 336 // of the root table (soffset_t), the size of the vtable (uint16_t), and the 337 // size of the referring table (uint16_t). 338 #define FLATBUFFERS_MIN_BUFFER_SIZE sizeof(uoffset_t) + sizeof(soffset_t) + \ 339 sizeof(uint16_t) + sizeof(uint16_t) 340 341 // We support aligning the contents of buffers up to this size. 342 #ifndef FLATBUFFERS_MAX_ALIGNMENT 343 #define FLATBUFFERS_MAX_ALIGNMENT 32 344 #endif 345 346 /// @brief The length of a FlatBuffer file header. 347 static const size_t kFileIdentifierLength = 4; 348 349 inline bool VerifyAlignmentRequirements(size_t align, size_t min_align = 1) { 350 return (min_align <= align) && (align <= (FLATBUFFERS_MAX_ALIGNMENT)) && 351 (align & (align - 1)) == 0; // must be power of 2 352 } 353 354 #if defined(_MSC_VER) 355 #pragma warning(disable: 4351) // C4351: new behavior: elements of array ... will be default initialized 356 #pragma warning(push) 357 #pragma warning(disable: 4127) // C4127: conditional expression is constant 358 #endif 359 360 template<typename T> T EndianSwap(T t) { 361 #if defined(_MSC_VER) 362 #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort 363 #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong 364 #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64 365 #elif defined(__ICCARM__) 366 #define FLATBUFFERS_BYTESWAP16 __REV16 367 #define FLATBUFFERS_BYTESWAP32 __REV 368 #define FLATBUFFERS_BYTESWAP64(x) \ 369 ((__REV(static_cast<uint32_t>(x >> 32U))) | (static_cast<uint64_t>(__REV(static_cast<uint32_t>(x)))) << 32U) 370 #else 371 #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__) 372 // __builtin_bswap16 was missing prior to GCC 4.8. 373 #define FLATBUFFERS_BYTESWAP16(x) \ 374 static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16)) 375 #else 376 #define FLATBUFFERS_BYTESWAP16 __builtin_bswap16 377 #endif 378 #define FLATBUFFERS_BYTESWAP32 __builtin_bswap32 379 #define FLATBUFFERS_BYTESWAP64 __builtin_bswap64 380 #endif 381 if (sizeof(T) == 1) { // Compile-time if-then's. 382 return t; 383 } else if (sizeof(T) == 2) { 384 union { T t; uint16_t i; } u = { t }; 385 u.i = FLATBUFFERS_BYTESWAP16(u.i); 386 return u.t; 387 } else if (sizeof(T) == 4) { 388 union { T t; uint32_t i; } u = { t }; 389 u.i = FLATBUFFERS_BYTESWAP32(u.i); 390 return u.t; 391 } else if (sizeof(T) == 8) { 392 union { T t; uint64_t i; } u = { t }; 393 u.i = FLATBUFFERS_BYTESWAP64(u.i); 394 return u.t; 395 } else { 396 FLATBUFFERS_ASSERT(0); 397 return t; 398 } 399 } 400 401 #if defined(_MSC_VER) 402 #pragma warning(pop) 403 #endif 404 405 406 template<typename T> T EndianScalar(T t) { 407 #if FLATBUFFERS_LITTLEENDIAN 408 return t; 409 #else 410 return EndianSwap(t); 411 #endif 412 } 413 414 template<typename T> 415 // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. 416 __suppress_ubsan__("alignment") 417 T ReadScalar(const void *p) { 418 return EndianScalar(*reinterpret_cast<const T *>(p)); 419 } 420 421 // See https://github.com/google/flatbuffers/issues/5950 422 423 #if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000) 424 #pragma GCC diagnostic push 425 #pragma GCC diagnostic ignored "-Wstringop-overflow" 426 #endif 427 428 template<typename T> 429 // UBSAN: C++ aliasing type rules, see std::bit_cast<> for details. 430 __suppress_ubsan__("alignment") 431 void WriteScalar(void *p, T t) { 432 *reinterpret_cast<T *>(p) = EndianScalar(t); 433 } 434 435 template<typename T> struct Offset; 436 template<typename T> __suppress_ubsan__("alignment") void WriteScalar(void *p, Offset<T> t) { 437 *reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o); 438 } 439 440 #if (FLATBUFFERS_GCC >= 100000) && (FLATBUFFERS_GCC < 110000) 441 #pragma GCC diagnostic pop 442 #endif 443 444 // Computes how many bytes you'd have to pad to be able to write an 445 // "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in 446 // memory). 447 __suppress_ubsan__("unsigned-integer-overflow") 448 inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) { 449 return ((~buf_size) + 1) & (scalar_size - 1); 450 } 451 452 // Generic 'operator==' with conditional specialisations. 453 // T e - new value of a scalar field. 454 // T def - default of scalar (is known at compile-time). 455 template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; } 456 457 #if defined(FLATBUFFERS_NAN_DEFAULTS) && \ 458 defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) 459 // Like `operator==(e, def)` with weak NaN if T=(float|double). 460 template<typename T> inline bool IsFloatTheSameAs(T e, T def) { 461 return (e == def) || ((def != def) && (e != e)); 462 } 463 template<> inline bool IsTheSameAs<float>(float e, float def) { 464 return IsFloatTheSameAs(e, def); 465 } 466 template<> inline bool IsTheSameAs<double>(double e, double def) { 467 return IsFloatTheSameAs(e, def); 468 } 469 #endif 470 471 // Check 'v' is out of closed range [low; high]. 472 // Workaround for GCC warning [-Werror=type-limits]: 473 // comparison is always true due to limited range of data type. 474 template<typename T> 475 inline bool IsOutRange(const T &v, const T &low, const T &high) { 476 return (v < low) || (high < v); 477 } 478 479 // Check 'v' is in closed range [low; high]. 480 template<typename T> 481 inline bool IsInRange(const T &v, const T &low, const T &high) { 482 return !IsOutRange(v, low, high); 483 } 484 485 } // namespace flatbuffers 486 #endif // FLATBUFFERS_BASE_H_