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_