From 4ffc881fb6002f37163ec7507c3dd2d1009abd08 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Wed, 25 May 2016 17:47:44 -0700 Subject: [PATCH] Fixed LoadFile crashing on directory arguments. Change-Id: I737f6fd0bb1302ab7cfa6ab8b06108e221ebb63c Tested: on Linux. --- include/flatbuffers/util.h | 6 +++++- samples/monster_generated.h | 19 ++++++++++++++++++- src/util.cpp | 17 ++++++++++++++++- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/flatbuffers/util.h b/include/flatbuffers/util.h index cfb211f09..7bd7513bb 100644 --- a/include/flatbuffers/util.h +++ b/include/flatbuffers/util.h @@ -35,9 +35,10 @@ #include #include #else -#include #include #endif +#include +#include #include "flatbuffers/flatbuffers.h" @@ -124,6 +125,9 @@ FileExistsFunction SetFileExistsFunction(FileExistsFunction // Check if file "name" exists. bool FileExists(const char *name); +// Check if "name" exists and it is also a directory. +bool DirExists(const char *name); + // Load file "name" into "buf" returning true if successful // false otherwise. If "binary" is false data is read // using ifstream's text mode, otherwise data is read with diff --git a/samples/monster_generated.h b/samples/monster_generated.h index cf45bbb91..1a16126a5 100644 --- a/samples/monster_generated.h +++ b/samples/monster_generated.h @@ -5,12 +5,13 @@ #include "flatbuffers/flatbuffers.h" - namespace MyGame { namespace Sample { struct Vec3; + struct Monster; + struct Weapon; enum Color { @@ -55,8 +56,11 @@ MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS { : x_(flatbuffers::EndianScalar(_x)), y_(flatbuffers::EndianScalar(_y)), z_(flatbuffers::EndianScalar(_z)) { } float x() const { return flatbuffers::EndianScalar(x_); } + void mutate_x(float _x) { flatbuffers::WriteScalar(&x_, _x); } float y() const { return flatbuffers::EndianScalar(y_); } + void mutate_y(float _y) { flatbuffers::WriteScalar(&y_, _y); } float z() const { return flatbuffers::EndianScalar(z_); } + void mutate_z(float _z) { flatbuffers::WriteScalar(&z_, _z); } }; STRUCT_END(Vec3, 12); @@ -73,14 +77,23 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_EQUIPPED = 22 }; const Vec3 *pos() const { return GetStruct(VT_POS); } + Vec3 *mutable_pos() { return GetStruct(VT_POS); } int16_t mana() const { return GetField(VT_MANA, 150); } + bool mutate_mana(int16_t _mana) { return SetField(VT_MANA, _mana); } int16_t hp() const { return GetField(VT_HP, 100); } + bool mutate_hp(int16_t _hp) { return SetField(VT_HP, _hp); } const flatbuffers::String *name() const { return GetPointer(VT_NAME); } + flatbuffers::String *mutable_name() { return GetPointer(VT_NAME); } const flatbuffers::Vector *inventory() const { return GetPointer *>(VT_INVENTORY); } + flatbuffers::Vector *mutable_inventory() { return GetPointer *>(VT_INVENTORY); } Color color() const { return static_cast(GetField(VT_COLOR, 2)); } + bool mutate_color(Color _color) { return SetField(VT_COLOR, static_cast(_color)); } const flatbuffers::Vector> *weapons() const { return GetPointer> *>(VT_WEAPONS); } + flatbuffers::Vector> *mutable_weapons() { return GetPointer> *>(VT_WEAPONS); } Equipment equipped_type() const { return static_cast(GetField(VT_EQUIPPED_TYPE, 0)); } + bool mutate_equipped_type(Equipment _equipped_type) { return SetField(VT_EQUIPPED_TYPE, static_cast(_equipped_type)); } const void *equipped() const { return GetPointer(VT_EQUIPPED); } + void *mutable_equipped() { return GetPointer(VT_EQUIPPED); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_POS) && @@ -150,7 +163,9 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_DAMAGE = 6 }; const flatbuffers::String *name() const { return GetPointer(VT_NAME); } + flatbuffers::String *mutable_name() { return GetPointer(VT_NAME); } int16_t damage() const { return GetField(VT_DAMAGE, 0); } + bool mutate_damage(int16_t _damage) { return SetField(VT_DAMAGE, _damage); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_NAME) && @@ -192,6 +207,8 @@ inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *union_o inline const MyGame::Sample::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot(buf); } +inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot(buf); } + inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer(); } inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset root) { fbb.Finish(root); } diff --git a/src/util.cpp b/src/util.cpp index 452e9eae5..f4aecb5c3 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -24,12 +24,14 @@ bool FileExistsRaw(const char *name) { } bool LoadFileRaw(const char *name, bool binary, std::string *buf) { + if (DirExists(name)) return false; std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in); if (!ifs.is_open()) return false; if (binary) { // The fastest way to read a file into a string. ifs.seekg(0, std::ios::end); - (*buf).resize(static_cast(ifs.tellg())); + auto size = ifs.tellg(); + (*buf).resize(static_cast(size)); ifs.seekg(0, std::ios::beg); ifs.read(&(*buf)[0], (*buf).size()); } else { @@ -54,6 +56,19 @@ bool FileExists(const char *name) { return g_file_exists_function(name); } +bool DirExists(const char *name) { + #ifdef _WIN32 + #define flatbuffers_stat _stat + #define FLATBUFFERS_S_IFDIR _S_IFDIR + #else + #define flatbuffers_stat stat + #define FLATBUFFERS_S_IFDIR S_IFDIR + #endif + struct flatbuffers_stat file_info; + if (flatbuffers_stat(name, &file_info) != 0) return false; + return (file_info.st_mode & FLATBUFFERS_S_IFDIR) != 0; +} + LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function) { LoadFileFunction previous_function = g_load_file_function; g_load_file_function = load_file_function ? load_file_function : LoadFileRaw;