From d1a6942ea7963a33c90eb844fb6adf859709b90f Mon Sep 17 00:00:00 2001 From: xirvik Date: Sat, 19 Sep 2026 04:13:12 +0000 Subject: [PATCH] Keep the object_storage key terminator inside the key buffer find_raw_string now honours the raw_string size instead of scanning for a nul. --- src/rpc/object_storage.cc | 5 +---- src/rpc/object_storage.h | 9 +-------- test/rpc/test_object_storage.cc | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/rpc/object_storage.cc b/src/rpc/object_storage.cc index b79b783a..d8353e22 100644 --- a/src/rpc/object_storage.cc +++ b/src/rpc/object_storage.cc @@ -26,10 +26,7 @@ const size_t object_storage::key_size; object_storage::iterator object_storage::find_raw_string(const torrent::raw_string& key) { - fixed_key_type<64> k; - k.set_c_str(key.data()); - - return find(k); + return find(key_type::from_raw_string(key)); } object_storage::iterator diff --git a/src/rpc/object_storage.h b/src/rpc/object_storage.h index dc70cb8f..3cecaa47 100644 --- a/src/rpc/object_storage.h +++ b/src/rpc/object_storage.h @@ -158,14 +158,7 @@ fixed_key_type::set_data(const value_type* src_data, size_type src_size template inline void fixed_key_type::set_c_str(const value_type* src_data) { - value_type* itr = m_data; - const value_type* last = m_data + max_size; - - while (itr != last && *src_data != '\0') - *itr++ = *src_data++; - - *itr = '\0'; - m_size = std::distance(m_data, itr); + set_c_str(src_data, std::strlen(src_data)); } template inline void diff --git a/test/rpc/test_object_storage.cc b/test/rpc/test_object_storage.cc index 3284c7ba..f4ac9c56 100644 --- a/test/rpc/test_object_storage.cc +++ b/test/rpc/test_object_storage.cc @@ -59,6 +59,23 @@ TestObjectStorage::test_validate_keys() { // The over-long key must not have been stored as the empty key. CPPUNIT_ASSERT(m_storage.find_raw_string(torrent::raw_string::from_c_str("")) == m_storage.end()); + // An over-long key must not be truncated into a match either. + CPPUNIT_ASSERT(m_storage.find_raw_string(torrent::raw_string::from_string(key_max + 'k')) == m_storage.end()); + + // set_c_str puts the terminating nul at m_data[size()], so size() has to + // stay below max_size for that write to land inside the array. + rpc::object_storage::key_type key_long; + key_long.set_c_str(std::string(rpc::object_storage::key_size + 1, 'k').c_str()); + + CPPUNIT_ASSERT(key_long.size() < rpc::object_storage::key_size); + + m_storage.clear(); + m_storage.insert_str("test_5", torrent::Object("a"), rpc::object_storage::flag_string_type); + + // insert rejects a key holding a nul-char, so a lookup must not match past one. + CPPUNIT_ASSERT(m_storage.find_raw_string(torrent::raw_string("test_5\0x", 8)) == m_storage.end()); + CPPUNIT_ASSERT(m_storage.find_raw_string(torrent::raw_string::from_c_str("test_5")) != m_storage.end()); + m_storage.clear(); }