diff --git a/CMakeLists.txt b/CMakeLists.txt index b4d3f46f..5f97d231 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,12 +79,7 @@ option (FLATCC_TRACE_VERIFY # Some producers allow empty vectors to be misaligned. # The following setting will cause the verifier to check for an -# empty vector before checking alignment. This option will also -# ensure accesses to a vector field never materializes misaligned -# pointers. -# -# NOTE: enabling this means empty vectors will not have distinct -# pointer identity. +# empty vector before checking alignment of the vector's elements. option (FLATCC_TOLERATE_MISALIGNED_EMPTY_VECTORS "don't fail verification if empty vectors are misaligned" OFF) diff --git a/include/flatcc/flatcc_flatbuffers.h b/include/flatcc/flatcc_flatbuffers.h index 7868c12f..6b175837 100644 --- a/include/flatcc/flatcc_flatbuffers.h +++ b/include/flatcc/flatcc_flatbuffers.h @@ -48,23 +48,6 @@ extern "C" { #define FLATBUFFERS_WRAP_NAMESPACE(ns, x) ns ## _ ## x #endif -#include - -/* - * Produce a pointer with maximum alignment to use as - * a placeholder when FLATCC_TOLERATE_MISALIGNED_EMPTY_VECTORS - * is specified. - */ -static inline const void* max_aligned_ptr(void) -{ -#ifdef __cplusplus - static const max_align_t m{}; -#else - static const max_align_t m; -#endif - return &m; -} - #endif /* flatcc_flatbuffers_defined */ #ifdef __cplusplus diff --git a/include/flatcc/flatcc_rtconfig.h b/include/flatcc/flatcc_rtconfig.h index 3bfd6eb7..55a79024 100644 --- a/include/flatcc/flatcc_rtconfig.h +++ b/include/flatcc/flatcc_rtconfig.h @@ -66,12 +66,7 @@ extern "C" { /* * Some producers allow empty vectors to be misaligned. * The following setting will cause the verifier to check for an - * empty vector before checking alignment. This option will also - * ensure accesses to a vector field never materializes misaligned - * pointers. - * - * NOTE: enabling this means empty vectors will not have distinct - * pointer identity. + * empty vector before checking alignment of the vector's elements. */ #if !defined(FLATCC_TOLERATE_MISALIGNED_EMPTY_VECTORS) #define FLATCC_TOLERATE_MISALIGNED_EMPTY_VECTORS 0 diff --git a/src/compiler/codegen_c_reader.c b/src/compiler/codegen_c_reader.c index cb1a35dd..6de0f216 100644 --- a/src/compiler/codegen_c_reader.c +++ b/src/compiler/codegen_c_reader.c @@ -5,8 +5,6 @@ #include "codegen_c.h" #include "codegen_c_sort.h" -#include "flatcc/flatcc_rtconfig.h" - static inline int match_kw_identifier(fb_symbol_t *sym) { return (sym->ident->len == 10 && @@ -620,34 +618,10 @@ static void gen_helpers(fb_output_t *out) " return 0;\\\n" "}\n", nsc, nsc, nsc, nsc, nsc); -#if FLATCC_TOLERATE_MISALIGNED_EMPTY_VECTORS - fprintf(out->fp, - "#include \n" - "#define __%svector_field(T, ID, t, r)\\\n" - "{\\\n" - " T out__tmp;\\\n" - " __%sread_vt(ID, offset__tmp, t)\\\n" - " if (offset__tmp) {\\\n" - " offset__tmp += __%suoffset_read_from_pe((uint8_t *)(t) + offset__tmp);\\\n" - " if (__%suoffset_read_from_pe((uint8_t *)(t) + offset__tmp) == 0) {\\\n" - " printf(\"Falling back for empty vector...\");\\\n" - " return (T)max_aligned_ptr();\\\n" - " }\\\n" - " offset__tmp += sizeof(%suoffset_t);\\\n" - " return (T)((uint8_t *)(t) + offset__tmp);\\\n" - " }\\\n" - " FLATCC_ASSERT(!(r) && \"required field missing\");\\\n" - " return 0;\\\n" - "}\n", - nsc, nsc, nsc, nsc, nsc); -#else - fprintf(out->fp, - "#define __%svector_field(T, ID, t, r) __%soffset_field(T, ID, t, r, sizeof(%suoffset_t))\n", - nsc, nsc, nsc); -#endif fprintf(out->fp, + "#define __%svector_field(T, ID, t, r) __%soffset_field(T, ID, t, r, sizeof(%suoffset_t))\n" "#define __%stable_field(T, ID, t, r) __%soffset_field(T, ID, t, r, 0)\n", - nsc, nsc); + nsc, nsc, nsc, nsc, nsc); fprintf(out->fp, "#define __%sdefine_struct_field(ID, N, NK, T, r)\\\n" "static inline T N ## _ ## NK ## _get(N ## _table_t t__tmp)\\\n" diff --git a/src/runtime/verifier.c b/src/runtime/verifier.c index 064a0a77..20b437bc 100644 --- a/src/runtime/verifier.c +++ b/src/runtime/verifier.c @@ -135,20 +135,6 @@ static inline int check_header(uoffset_t end, uoffset_t base, uoffset_t offset) return k > base && k + offset_size <= end && !(k & (offset_size - 1)); } -static inline int check_aligned_header(uoffset_t end, uoffset_t base, uoffset_t offset, uint16_t align) -{ - uoffset_t k = base + offset; - - if (uoffset_size <= voffset_size && k + offset_size < k) { - return 0; - } - /* Alignment refers to element 0 and header must also be aligned. */ - align = align < uoffset_size ? uoffset_size : align; - - /* Note to self: the builder can also use the mask OR trick to propagate `min_align`. */ - return k > base && k + offset_size <= end && !((k + offset_size) & ((offset_size - 1) | (align - 1u))); -} - static inline int verify_struct(uoffset_t end, uoffset_t base, uoffset_t offset, uoffset_t size, uint16_t align) { /* Structs can have zero size so `end` is a valid value. */ @@ -276,22 +262,18 @@ static inline int verify_string(const void *buf, uoffset_t end, uoffset_t base, */ static inline int verify_vector(const void *buf, uoffset_t end, uoffset_t base, uoffset_t offset, uoffset_t elem_size, uint16_t align, uoffset_t max_count) { - uoffset_t n; + verify(check_header(end, base, offset), flatcc_verify_error_vector_header_out_of_range_or_unaligned); + base += offset; + + uoffset_t n = read_uoffset(buf, base); + base += offset_size; #if FLATCC_TOLERATE_MISALIGNED_EMPTY_VECTORS - base += offset; - verify(end - base >= sizeof(n), flatcc_verify_error_vector_header_out_of_range_or_unaligned); - n = read_uoffset(buf, base); - if (n == 0) { - return flatcc_verify_ok; - } - verify(check_aligned_header(end, base - offset, offset, align), flatcc_verify_error_vector_header_out_of_range_or_unaligned); -#else - verify(check_aligned_header(end, base, offset, align), flatcc_verify_error_vector_header_out_of_range_or_unaligned); - base += offset; - n = read_uoffset(buf, base); + align = n == 0 ? uoffset_size : align; #endif - base += offset_size; + align = align < uoffset_size ? uoffset_size : align; + verify(!(base & (align - 1u)),flatcc_verify_error_vector_header_out_of_range_or_unaligned); + /* `n * elem_size` can overflow uncontrollably otherwise. */ verify(n <= max_count, flatcc_verify_error_vector_count_exceeds_representable_vector_size); verify(end - base >= n * elem_size, flatcc_verify_error_vector_out_of_range); diff --git a/test/load_test/load_test.c b/test/load_test/load_test.c index dbd00739..466f5ccb 100644 --- a/test/load_test/load_test.c +++ b/test/load_test/load_test.c @@ -136,8 +136,6 @@ int main(int argc, char *argv[]) create_root_monster(B); flatcc_builder_copy_buffer(B, buffer, size); mon = ns(Monster_as_root(buffer)); - char const *name = ns(Monster_name(mon)); - printf("Name was %s\n", name ? name : ""); ret |= strcmp(ns(Monster_name(mon)), "root_monster"); assert(ret == 0); mv = ns(Monster_testarrayoftables(mon));