diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index 9e58d4be95..dc47c7a9c6 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -245,9 +245,11 @@ class SymbolTable { } bool Add(const std::string& name, T* e) { - vec.emplace_back(e); + // Check for duplicate before adding to vec to avoid use-after-free: + // if caller deletes `e` on duplicate, the pointer must not remain in vec. auto it = dict.find(name); if (it != dict.end()) return true; + vec.emplace_back(e); dict[name] = e; return false; } diff --git a/rust/flexbuffers/src/reader/mod.rs b/rust/flexbuffers/src/reader/mod.rs index 5035dea6c6..d44b6b20bb 100644 --- a/rust/flexbuffers/src/reader/mod.rs +++ b/rust/flexbuffers/src/reader/mod.rs @@ -323,7 +323,12 @@ impl Reader { /// Otherwise Returns error. pub fn get_bool(&self) -> Result { self.expect_type(FlexBufferType::Bool)?; - Ok(self.buffer[self.address..self.address + self.width.n_bytes()].iter().any(|&b| b != 0)) + Ok(self + .buffer + .get(self.address..self.address + self.width.n_bytes()) + .ok_or(Error::FlexbufferOutOfBounds)? + .iter() + .any(|&b| b != 0)) } /// Gets the length of the key if this type is a key. @@ -601,9 +606,9 @@ fn f64_from_le_bytes(bytes: [u8; 8]) -> f64 { } fn read_usize(buffer: &[u8], address: usize, width: BitWidth) -> usize { - let cursor = &buffer[address..]; + let cursor = buffer.get(address..).unwrap_or_default(); match width { - BitWidth::W8 => cursor[0] as usize, + BitWidth::W8 => cursor.first().copied().unwrap_or_default() as usize, BitWidth::W16 => cursor .get(0..2) .and_then(|s| s.try_into().ok())