1*890232f2SAndroid Build Coastguard Worker /* 2*890232f2SAndroid Build Coastguard Worker * Copyright 2021 Google Inc. All rights reserved. 3*890232f2SAndroid Build Coastguard Worker * 4*890232f2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*890232f2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*890232f2SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*890232f2SAndroid Build Coastguard Worker * 8*890232f2SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*890232f2SAndroid Build Coastguard Worker * 10*890232f2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*890232f2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*890232f2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*890232f2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*890232f2SAndroid Build Coastguard Worker * limitations under the License. 15*890232f2SAndroid Build Coastguard Worker */ 16*890232f2SAndroid Build Coastguard Worker 17*890232f2SAndroid Build Coastguard Worker #ifndef FLATBUFFERS_VERIFIER_H_ 18*890232f2SAndroid Build Coastguard Worker #define FLATBUFFERS_VERIFIER_H_ 19*890232f2SAndroid Build Coastguard Worker 20*890232f2SAndroid Build Coastguard Worker #include "flatbuffers/base.h" 21*890232f2SAndroid Build Coastguard Worker #include "flatbuffers/vector.h" 22*890232f2SAndroid Build Coastguard Worker 23*890232f2SAndroid Build Coastguard Worker namespace flatbuffers { 24*890232f2SAndroid Build Coastguard Worker 25*890232f2SAndroid Build Coastguard Worker // Helper class to verify the integrity of a FlatBuffer 26*890232f2SAndroid Build Coastguard Worker class Verifier FLATBUFFERS_FINAL_CLASS { 27*890232f2SAndroid Build Coastguard Worker public: 28*890232f2SAndroid Build Coastguard Worker Verifier(const uint8_t *const buf, const size_t buf_len, 29*890232f2SAndroid Build Coastguard Worker const uoffset_t _max_depth = 64, 30*890232f2SAndroid Build Coastguard Worker const uoffset_t _max_tables = 1000000, 31*890232f2SAndroid Build Coastguard Worker const bool _check_alignment = true) buf_(buf)32*890232f2SAndroid Build Coastguard Worker : buf_(buf), 33*890232f2SAndroid Build Coastguard Worker size_(buf_len), 34*890232f2SAndroid Build Coastguard Worker max_depth_(_max_depth), 35*890232f2SAndroid Build Coastguard Worker max_tables_(_max_tables), 36*890232f2SAndroid Build Coastguard Worker check_alignment_(_check_alignment), 37*890232f2SAndroid Build Coastguard Worker upper_bound_(0), 38*890232f2SAndroid Build Coastguard Worker depth_(0), 39*890232f2SAndroid Build Coastguard Worker num_tables_(0), 40*890232f2SAndroid Build Coastguard Worker flex_reuse_tracker_(nullptr) { 41*890232f2SAndroid Build Coastguard Worker FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE); 42*890232f2SAndroid Build Coastguard Worker } 43*890232f2SAndroid Build Coastguard Worker 44*890232f2SAndroid Build Coastguard Worker // Central location where any verification failures register. Check(const bool ok)45*890232f2SAndroid Build Coastguard Worker bool Check(const bool ok) const { 46*890232f2SAndroid Build Coastguard Worker // clang-format off 47*890232f2SAndroid Build Coastguard Worker #ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE 48*890232f2SAndroid Build Coastguard Worker FLATBUFFERS_ASSERT(ok); 49*890232f2SAndroid Build Coastguard Worker #endif 50*890232f2SAndroid Build Coastguard Worker #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 51*890232f2SAndroid Build Coastguard Worker if (!ok) 52*890232f2SAndroid Build Coastguard Worker upper_bound_ = 0; 53*890232f2SAndroid Build Coastguard Worker #endif 54*890232f2SAndroid Build Coastguard Worker // clang-format on 55*890232f2SAndroid Build Coastguard Worker return ok; 56*890232f2SAndroid Build Coastguard Worker } 57*890232f2SAndroid Build Coastguard Worker 58*890232f2SAndroid Build Coastguard Worker // Verify any range within the buffer. Verify(const size_t elem,const size_t elem_len)59*890232f2SAndroid Build Coastguard Worker bool Verify(const size_t elem, const size_t elem_len) const { 60*890232f2SAndroid Build Coastguard Worker // clang-format off 61*890232f2SAndroid Build Coastguard Worker #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 62*890232f2SAndroid Build Coastguard Worker auto upper_bound = elem + elem_len; 63*890232f2SAndroid Build Coastguard Worker if (upper_bound_ < upper_bound) 64*890232f2SAndroid Build Coastguard Worker upper_bound_ = upper_bound; 65*890232f2SAndroid Build Coastguard Worker #endif 66*890232f2SAndroid Build Coastguard Worker // clang-format on 67*890232f2SAndroid Build Coastguard Worker return Check(elem_len < size_ && elem <= size_ - elem_len); 68*890232f2SAndroid Build Coastguard Worker } 69*890232f2SAndroid Build Coastguard Worker VerifyAlignment(const size_t elem,const size_t align)70*890232f2SAndroid Build Coastguard Worker bool VerifyAlignment(const size_t elem, const size_t align) const { 71*890232f2SAndroid Build Coastguard Worker return Check((elem & (align - 1)) == 0 || !check_alignment_); 72*890232f2SAndroid Build Coastguard Worker } 73*890232f2SAndroid Build Coastguard Worker 74*890232f2SAndroid Build Coastguard Worker // Verify a range indicated by sizeof(T). Verify(const size_t elem)75*890232f2SAndroid Build Coastguard Worker template<typename T> bool Verify(const size_t elem) const { 76*890232f2SAndroid Build Coastguard Worker return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T)); 77*890232f2SAndroid Build Coastguard Worker } 78*890232f2SAndroid Build Coastguard Worker VerifyFromPointer(const uint8_t * const p,const size_t len)79*890232f2SAndroid Build Coastguard Worker bool VerifyFromPointer(const uint8_t *const p, const size_t len) { 80*890232f2SAndroid Build Coastguard Worker return Verify(static_cast<size_t>(p - buf_), len); 81*890232f2SAndroid Build Coastguard Worker } 82*890232f2SAndroid Build Coastguard Worker 83*890232f2SAndroid Build Coastguard Worker // Verify relative to a known-good base pointer. VerifyFieldStruct(const uint8_t * const base,const voffset_t elem_off,const size_t elem_len,const size_t align)84*890232f2SAndroid Build Coastguard Worker bool VerifyFieldStruct(const uint8_t *const base, const voffset_t elem_off, 85*890232f2SAndroid Build Coastguard Worker const size_t elem_len, const size_t align) const { 86*890232f2SAndroid Build Coastguard Worker const auto f = static_cast<size_t>(base - buf_) + elem_off; 87*890232f2SAndroid Build Coastguard Worker return VerifyAlignment(f, align) && Verify(f, elem_len); 88*890232f2SAndroid Build Coastguard Worker } 89*890232f2SAndroid Build Coastguard Worker 90*890232f2SAndroid Build Coastguard Worker template<typename T> VerifyField(const uint8_t * const base,const voffset_t elem_off,const size_t align)91*890232f2SAndroid Build Coastguard Worker bool VerifyField(const uint8_t *const base, const voffset_t elem_off, 92*890232f2SAndroid Build Coastguard Worker const size_t align) const { 93*890232f2SAndroid Build Coastguard Worker const auto f = static_cast<size_t>(base - buf_) + elem_off; 94*890232f2SAndroid Build Coastguard Worker return VerifyAlignment(f, align) && Verify(f, sizeof(T)); 95*890232f2SAndroid Build Coastguard Worker } 96*890232f2SAndroid Build Coastguard Worker 97*890232f2SAndroid Build Coastguard Worker // Verify a pointer (may be NULL) of a table type. VerifyTable(const T * const table)98*890232f2SAndroid Build Coastguard Worker template<typename T> bool VerifyTable(const T *const table) { 99*890232f2SAndroid Build Coastguard Worker return !table || table->Verify(*this); 100*890232f2SAndroid Build Coastguard Worker } 101*890232f2SAndroid Build Coastguard Worker 102*890232f2SAndroid Build Coastguard Worker // Verify a pointer (may be NULL) of any vector type. VerifyVector(const Vector<T> * const vec)103*890232f2SAndroid Build Coastguard Worker template<typename T> bool VerifyVector(const Vector<T> *const vec) const { 104*890232f2SAndroid Build Coastguard Worker return !vec || VerifyVectorOrString(reinterpret_cast<const uint8_t *>(vec), 105*890232f2SAndroid Build Coastguard Worker sizeof(T)); 106*890232f2SAndroid Build Coastguard Worker } 107*890232f2SAndroid Build Coastguard Worker 108*890232f2SAndroid Build Coastguard Worker // Verify a pointer (may be NULL) of a vector to struct. 109*890232f2SAndroid Build Coastguard Worker template<typename T> VerifyVector(const Vector<const T * > * const vec)110*890232f2SAndroid Build Coastguard Worker bool VerifyVector(const Vector<const T *> *const vec) const { 111*890232f2SAndroid Build Coastguard Worker return VerifyVector(reinterpret_cast<const Vector<T> *>(vec)); 112*890232f2SAndroid Build Coastguard Worker } 113*890232f2SAndroid Build Coastguard Worker 114*890232f2SAndroid Build Coastguard Worker // Verify a pointer (may be NULL) to string. VerifyString(const String * const str)115*890232f2SAndroid Build Coastguard Worker bool VerifyString(const String *const str) const { 116*890232f2SAndroid Build Coastguard Worker size_t end; 117*890232f2SAndroid Build Coastguard Worker return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str), 118*890232f2SAndroid Build Coastguard Worker 1, &end) && 119*890232f2SAndroid Build Coastguard Worker Verify(end, 1) && // Must have terminator 120*890232f2SAndroid Build Coastguard Worker Check(buf_[end] == '\0')); // Terminating byte must be 0. 121*890232f2SAndroid Build Coastguard Worker } 122*890232f2SAndroid Build Coastguard Worker 123*890232f2SAndroid Build Coastguard Worker // Common code between vectors and strings. 124*890232f2SAndroid Build Coastguard Worker bool VerifyVectorOrString(const uint8_t *const vec, const size_t elem_size, 125*890232f2SAndroid Build Coastguard Worker size_t *const end = nullptr) const { 126*890232f2SAndroid Build Coastguard Worker const auto veco = static_cast<size_t>(vec - buf_); 127*890232f2SAndroid Build Coastguard Worker // Check we can read the size field. 128*890232f2SAndroid Build Coastguard Worker if (!Verify<uoffset_t>(veco)) return false; 129*890232f2SAndroid Build Coastguard Worker // Check the whole array. If this is a string, the byte past the array 130*890232f2SAndroid Build Coastguard Worker // must be 0. 131*890232f2SAndroid Build Coastguard Worker const auto size = ReadScalar<uoffset_t>(vec); 132*890232f2SAndroid Build Coastguard Worker const auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size; 133*890232f2SAndroid Build Coastguard Worker if (!Check(size < max_elems)) 134*890232f2SAndroid Build Coastguard Worker return false; // Protect against byte_size overflowing. 135*890232f2SAndroid Build Coastguard Worker const auto byte_size = sizeof(size) + elem_size * size; 136*890232f2SAndroid Build Coastguard Worker if (end) *end = veco + byte_size; 137*890232f2SAndroid Build Coastguard Worker return Verify(veco, byte_size); 138*890232f2SAndroid Build Coastguard Worker } 139*890232f2SAndroid Build Coastguard Worker 140*890232f2SAndroid Build Coastguard Worker // Special case for string contents, after the above has been called. VerifyVectorOfStrings(const Vector<Offset<String>> * const vec)141*890232f2SAndroid Build Coastguard Worker bool VerifyVectorOfStrings(const Vector<Offset<String>> *const vec) const { 142*890232f2SAndroid Build Coastguard Worker if (vec) { 143*890232f2SAndroid Build Coastguard Worker for (uoffset_t i = 0; i < vec->size(); i++) { 144*890232f2SAndroid Build Coastguard Worker if (!VerifyString(vec->Get(i))) return false; 145*890232f2SAndroid Build Coastguard Worker } 146*890232f2SAndroid Build Coastguard Worker } 147*890232f2SAndroid Build Coastguard Worker return true; 148*890232f2SAndroid Build Coastguard Worker } 149*890232f2SAndroid Build Coastguard Worker 150*890232f2SAndroid Build Coastguard Worker // Special case for table contents, after the above has been called. 151*890232f2SAndroid Build Coastguard Worker template<typename T> VerifyVectorOfTables(const Vector<Offset<T>> * const vec)152*890232f2SAndroid Build Coastguard Worker bool VerifyVectorOfTables(const Vector<Offset<T>> *const vec) { 153*890232f2SAndroid Build Coastguard Worker if (vec) { 154*890232f2SAndroid Build Coastguard Worker for (uoffset_t i = 0; i < vec->size(); i++) { 155*890232f2SAndroid Build Coastguard Worker if (!vec->Get(i)->Verify(*this)) return false; 156*890232f2SAndroid Build Coastguard Worker } 157*890232f2SAndroid Build Coastguard Worker } 158*890232f2SAndroid Build Coastguard Worker return true; 159*890232f2SAndroid Build Coastguard Worker } 160*890232f2SAndroid Build Coastguard Worker VerifyTableStart(const uint8_t * const table)161*890232f2SAndroid Build Coastguard Worker __supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart( 162*890232f2SAndroid Build Coastguard Worker const uint8_t *const table) { 163*890232f2SAndroid Build Coastguard Worker // Check the vtable offset. 164*890232f2SAndroid Build Coastguard Worker const auto tableo = static_cast<size_t>(table - buf_); 165*890232f2SAndroid Build Coastguard Worker if (!Verify<soffset_t>(tableo)) return false; 166*890232f2SAndroid Build Coastguard Worker // This offset may be signed, but doing the subtraction unsigned always 167*890232f2SAndroid Build Coastguard Worker // gives the result we want. 168*890232f2SAndroid Build Coastguard Worker const auto vtableo = 169*890232f2SAndroid Build Coastguard Worker tableo - static_cast<size_t>(ReadScalar<soffset_t>(table)); 170*890232f2SAndroid Build Coastguard Worker // Check the vtable size field, then check vtable fits in its entirety. 171*890232f2SAndroid Build Coastguard Worker if (!(VerifyComplexity() && Verify<voffset_t>(vtableo) && 172*890232f2SAndroid Build Coastguard Worker VerifyAlignment(ReadScalar<voffset_t>(buf_ + vtableo), 173*890232f2SAndroid Build Coastguard Worker sizeof(voffset_t)))) 174*890232f2SAndroid Build Coastguard Worker return false; 175*890232f2SAndroid Build Coastguard Worker const auto vsize = ReadScalar<voffset_t>(buf_ + vtableo); 176*890232f2SAndroid Build Coastguard Worker return Check((vsize & 1) == 0) && Verify(vtableo, vsize); 177*890232f2SAndroid Build Coastguard Worker } 178*890232f2SAndroid Build Coastguard Worker 179*890232f2SAndroid Build Coastguard Worker template<typename T> VerifyBufferFromStart(const char * const identifier,const size_t start)180*890232f2SAndroid Build Coastguard Worker bool VerifyBufferFromStart(const char *const identifier, const size_t start) { 181*890232f2SAndroid Build Coastguard Worker // Buffers have to be of some size to be valid. The reason it is a runtime 182*890232f2SAndroid Build Coastguard Worker // check instead of static_assert, is that nested flatbuffers go through 183*890232f2SAndroid Build Coastguard Worker // this call and their size is determined at runtime. 184*890232f2SAndroid Build Coastguard Worker if (!Check(size_ >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false; 185*890232f2SAndroid Build Coastguard Worker 186*890232f2SAndroid Build Coastguard Worker // If an identifier is provided, check that we have a buffer 187*890232f2SAndroid Build Coastguard Worker if (identifier && !Check((size_ >= 2 * sizeof(flatbuffers::uoffset_t) && 188*890232f2SAndroid Build Coastguard Worker BufferHasIdentifier(buf_ + start, identifier)))) { 189*890232f2SAndroid Build Coastguard Worker return false; 190*890232f2SAndroid Build Coastguard Worker } 191*890232f2SAndroid Build Coastguard Worker 192*890232f2SAndroid Build Coastguard Worker // Call T::Verify, which must be in the generated code for this type. 193*890232f2SAndroid Build Coastguard Worker const auto o = VerifyOffset(start); 194*890232f2SAndroid Build Coastguard Worker return Check(o != 0) && 195*890232f2SAndroid Build Coastguard Worker reinterpret_cast<const T *>(buf_ + start + o)->Verify(*this) 196*890232f2SAndroid Build Coastguard Worker // clang-format off 197*890232f2SAndroid Build Coastguard Worker #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 198*890232f2SAndroid Build Coastguard Worker && GetComputedSize() 199*890232f2SAndroid Build Coastguard Worker #endif 200*890232f2SAndroid Build Coastguard Worker ; 201*890232f2SAndroid Build Coastguard Worker // clang-format on 202*890232f2SAndroid Build Coastguard Worker } 203*890232f2SAndroid Build Coastguard Worker 204*890232f2SAndroid Build Coastguard Worker template<typename T> VerifyNestedFlatBuffer(const Vector<uint8_t> * const buf,const char * const identifier)205*890232f2SAndroid Build Coastguard Worker bool VerifyNestedFlatBuffer(const Vector<uint8_t> *const buf, 206*890232f2SAndroid Build Coastguard Worker const char *const identifier) { 207*890232f2SAndroid Build Coastguard Worker // An empty buffer is OK as it indicates not present. 208*890232f2SAndroid Build Coastguard Worker if (!buf) return true; 209*890232f2SAndroid Build Coastguard Worker 210*890232f2SAndroid Build Coastguard Worker // If there is a nested buffer, it must be greater than the min size. 211*890232f2SAndroid Build Coastguard Worker if(!Check(buf->size() >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false; 212*890232f2SAndroid Build Coastguard Worker 213*890232f2SAndroid Build Coastguard Worker Verifier nested_verifier(buf->data(), buf->size()); 214*890232f2SAndroid Build Coastguard Worker return nested_verifier.VerifyBuffer<T>(identifier); 215*890232f2SAndroid Build Coastguard Worker } 216*890232f2SAndroid Build Coastguard Worker 217*890232f2SAndroid Build Coastguard Worker // Verify this whole buffer, starting with root type T. VerifyBuffer()218*890232f2SAndroid Build Coastguard Worker template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); } 219*890232f2SAndroid Build Coastguard Worker VerifyBuffer(const char * const identifier)220*890232f2SAndroid Build Coastguard Worker template<typename T> bool VerifyBuffer(const char *const identifier) { 221*890232f2SAndroid Build Coastguard Worker return VerifyBufferFromStart<T>(identifier, 0); 222*890232f2SAndroid Build Coastguard Worker } 223*890232f2SAndroid Build Coastguard Worker 224*890232f2SAndroid Build Coastguard Worker template<typename T> VerifySizePrefixedBuffer(const char * const identifier)225*890232f2SAndroid Build Coastguard Worker bool VerifySizePrefixedBuffer(const char *const identifier) { 226*890232f2SAndroid Build Coastguard Worker return Verify<uoffset_t>(0U) && 227*890232f2SAndroid Build Coastguard Worker Check(ReadScalar<uoffset_t>(buf_) == size_ - sizeof(uoffset_t)) && 228*890232f2SAndroid Build Coastguard Worker VerifyBufferFromStart<T>(identifier, sizeof(uoffset_t)); 229*890232f2SAndroid Build Coastguard Worker } 230*890232f2SAndroid Build Coastguard Worker VerifyOffset(const size_t start)231*890232f2SAndroid Build Coastguard Worker uoffset_t VerifyOffset(const size_t start) const { 232*890232f2SAndroid Build Coastguard Worker if (!Verify<uoffset_t>(start)) return 0; 233*890232f2SAndroid Build Coastguard Worker const auto o = ReadScalar<uoffset_t>(buf_ + start); 234*890232f2SAndroid Build Coastguard Worker // May not point to itself. 235*890232f2SAndroid Build Coastguard Worker if (!Check(o != 0)) return 0; 236*890232f2SAndroid Build Coastguard Worker // Can't wrap around / buffers are max 2GB. 237*890232f2SAndroid Build Coastguard Worker if (!Check(static_cast<soffset_t>(o) >= 0)) return 0; 238*890232f2SAndroid Build Coastguard Worker // Must be inside the buffer to create a pointer from it (pointer outside 239*890232f2SAndroid Build Coastguard Worker // buffer is UB). 240*890232f2SAndroid Build Coastguard Worker if (!Verify(start + o, 1)) return 0; 241*890232f2SAndroid Build Coastguard Worker return o; 242*890232f2SAndroid Build Coastguard Worker } 243*890232f2SAndroid Build Coastguard Worker VerifyOffset(const uint8_t * const base,const voffset_t start)244*890232f2SAndroid Build Coastguard Worker uoffset_t VerifyOffset(const uint8_t *const base, 245*890232f2SAndroid Build Coastguard Worker const voffset_t start) const { 246*890232f2SAndroid Build Coastguard Worker return VerifyOffset(static_cast<size_t>(base - buf_) + start); 247*890232f2SAndroid Build Coastguard Worker } 248*890232f2SAndroid Build Coastguard Worker 249*890232f2SAndroid Build Coastguard Worker // Called at the start of a table to increase counters measuring data 250*890232f2SAndroid Build Coastguard Worker // structure depth and amount, and possibly bails out with false if 251*890232f2SAndroid Build Coastguard Worker // limits set by the constructor have been hit. Needs to be balanced 252*890232f2SAndroid Build Coastguard Worker // with EndTable(). VerifyComplexity()253*890232f2SAndroid Build Coastguard Worker bool VerifyComplexity() { 254*890232f2SAndroid Build Coastguard Worker depth_++; 255*890232f2SAndroid Build Coastguard Worker num_tables_++; 256*890232f2SAndroid Build Coastguard Worker return Check(depth_ <= max_depth_ && num_tables_ <= max_tables_); 257*890232f2SAndroid Build Coastguard Worker } 258*890232f2SAndroid Build Coastguard Worker 259*890232f2SAndroid Build Coastguard Worker // Called at the end of a table to pop the depth count. EndTable()260*890232f2SAndroid Build Coastguard Worker bool EndTable() { 261*890232f2SAndroid Build Coastguard Worker depth_--; 262*890232f2SAndroid Build Coastguard Worker return true; 263*890232f2SAndroid Build Coastguard Worker } 264*890232f2SAndroid Build Coastguard Worker 265*890232f2SAndroid Build Coastguard Worker // Returns the message size in bytes GetComputedSize()266*890232f2SAndroid Build Coastguard Worker size_t GetComputedSize() const { 267*890232f2SAndroid Build Coastguard Worker // clang-format off 268*890232f2SAndroid Build Coastguard Worker #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE 269*890232f2SAndroid Build Coastguard Worker uintptr_t size = upper_bound_; 270*890232f2SAndroid Build Coastguard Worker // Align the size to uoffset_t 271*890232f2SAndroid Build Coastguard Worker size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1); 272*890232f2SAndroid Build Coastguard Worker return (size > size_) ? 0 : size; 273*890232f2SAndroid Build Coastguard Worker #else 274*890232f2SAndroid Build Coastguard Worker // Must turn on FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE for this to work. 275*890232f2SAndroid Build Coastguard Worker (void)upper_bound_; 276*890232f2SAndroid Build Coastguard Worker FLATBUFFERS_ASSERT(false); 277*890232f2SAndroid Build Coastguard Worker return 0; 278*890232f2SAndroid Build Coastguard Worker #endif 279*890232f2SAndroid Build Coastguard Worker // clang-format on 280*890232f2SAndroid Build Coastguard Worker } 281*890232f2SAndroid Build Coastguard Worker GetFlexReuseTracker()282*890232f2SAndroid Build Coastguard Worker std::vector<uint8_t> *GetFlexReuseTracker() { return flex_reuse_tracker_; } 283*890232f2SAndroid Build Coastguard Worker SetFlexReuseTracker(std::vector<uint8_t> * const rt)284*890232f2SAndroid Build Coastguard Worker void SetFlexReuseTracker(std::vector<uint8_t> *const rt) { 285*890232f2SAndroid Build Coastguard Worker flex_reuse_tracker_ = rt; 286*890232f2SAndroid Build Coastguard Worker } 287*890232f2SAndroid Build Coastguard Worker 288*890232f2SAndroid Build Coastguard Worker private: 289*890232f2SAndroid Build Coastguard Worker const uint8_t *buf_; 290*890232f2SAndroid Build Coastguard Worker const size_t size_; 291*890232f2SAndroid Build Coastguard Worker const uoffset_t max_depth_; 292*890232f2SAndroid Build Coastguard Worker const uoffset_t max_tables_; 293*890232f2SAndroid Build Coastguard Worker const bool check_alignment_; 294*890232f2SAndroid Build Coastguard Worker 295*890232f2SAndroid Build Coastguard Worker mutable size_t upper_bound_; 296*890232f2SAndroid Build Coastguard Worker 297*890232f2SAndroid Build Coastguard Worker uoffset_t depth_; 298*890232f2SAndroid Build Coastguard Worker uoffset_t num_tables_; 299*890232f2SAndroid Build Coastguard Worker std::vector<uint8_t> *flex_reuse_tracker_; 300*890232f2SAndroid Build Coastguard Worker }; 301*890232f2SAndroid Build Coastguard Worker 302*890232f2SAndroid Build Coastguard Worker } // namespace flatbuffers 303*890232f2SAndroid Build Coastguard Worker 304*890232f2SAndroid Build Coastguard Worker #endif // FLATBUFFERS_VERIFIER_H_ 305