diff --git a/faiss/svs/IndexSVSFlat.cpp b/faiss/svs/IndexSVSFlat.cpp index 7b6cf6382..271e35fa8 100644 --- a/faiss/svs/IndexSVSFlat.cpp +++ b/faiss/svs/IndexSVSFlat.cpp @@ -107,11 +107,11 @@ void IndexSVSFlat::serialize_impl(std::ostream& out) const { void IndexSVSFlat::deserialize_impl(std::istream& in) { FAISS_THROW_IF_MSG(impl, "Cannot deserialize: SVS index already loaded."); auto metric = to_svs_metric(metric_type); - auto status = impl->load(&impl, in, metric); + auto status = svs_runtime::FlatIndex::load(&impl, in, metric); if (!status.ok()) { FAISS_THROW_MSG(status.message()); } - FAISS_THROW_IF_NOT(impl); + FAISS_THROW_IF_NOT_MSG(impl, "Failed to load SVS Flat index."); } } // namespace faiss diff --git a/faiss/svs/IndexSVSVamana.cpp b/faiss/svs/IndexSVSVamana.cpp index 15fedcffc..64d1b2767 100644 --- a/faiss/svs/IndexSVSVamana.cpp +++ b/faiss/svs/IndexSVSVamana.cpp @@ -236,10 +236,12 @@ void IndexSVSVamana::deserialize_impl(std::istream& in) { FAISS_THROW_IF_MSG(impl, "Cannot deserialize: SVS index already loaded."); auto svs_metric = to_svs_metric(metric_type); auto svs_storage_kind = to_svs_storage_kind(storage_kind); - auto status = impl->load(&impl, in, svs_metric, svs_storage_kind); + auto status = svs_runtime::DynamicVamanaIndex::load( + &impl, in, svs_metric, svs_storage_kind); if (!status.ok()) { FAISS_THROW_MSG(status.message()); } + FAISS_THROW_IF_NOT_MSG(impl, "Failed to load SVS Vamana index."); } } // namespace faiss diff --git a/tests/test_read_index_deserialize.cpp b/tests/test_read_index_deserialize.cpp index 5341cd5d6..d2ece1c67 100644 --- a/tests/test_read_index_deserialize.cpp +++ b/tests/test_read_index_deserialize.cpp @@ -2966,3 +2966,80 @@ TEST(ReadIndexDeserialize, IndexRQFastScanAQDimensionMismatch) { expect_read_throws_with(buf, "does not match index d"); } + +// ============================================================ +// SVS fourcc rejection / deserialization safety (Group F: T262015608) +// ============================================================ + +#ifdef FAISS_ENABLE_SVS + +// When SVS is enabled, deserializing an SVS Vamana index with invalid SVS +// stream data should throw a FaissException (from the SVS runtime load +// failure) rather than crashing with a null-pointer dereference. +// Previously, deserialize_impl called impl->load() on a null impl pointer. +TEST(ReadIndexDeserialize, SVSVamanaInvalidStreamThrows) { + std::vector buf; + push_fourcc(buf, "ISVD"); + push_index_header(buf, 8, 0); + // SVS Vamana deserialization fields: + push_val(buf, 32); // graph_max_degree + push_val(buf, 1.2f); // alpha + push_val(buf, 10); // search_window_size + push_val(buf, 10); // search_buffer_capacity + push_val(buf, 64); // construction_window_size + push_val(buf, 750); // max_candidate_pool_size + push_val(buf, 28); // prune_to + push_val(buf, false); // use_full_search_history + push_val(buf, 0); // storage_kind (SVS_Float16) + push_val(buf, true); // initialized = true → triggers deserialize_impl + // Provide garbage SVS stream data — load should fail gracefully. + for (int i = 0; i < 256; i++) { + push_val(buf, 0); + } + + // Should throw from SVS runtime load failure, NOT crash with SIGSEGV. + EXPECT_THROW( + { + auto reader = faiss::VectorIOReader(); + reader.data = buf; + faiss::read_index(&reader); + }, + faiss::FaissException); +} + +// Same test for SVS Flat index. +TEST(ReadIndexDeserialize, SVSFlatInvalidStreamThrows) { + std::vector buf; + push_fourcc(buf, "ISVF"); + push_index_header(buf, 8, 0); + push_val(buf, true); // initialized = true → triggers deserialize_impl + // Provide garbage SVS stream data. + for (int i = 0; i < 256; i++) { + push_val(buf, 0); + } + + EXPECT_THROW( + { + auto reader = faiss::VectorIOReader(); + reader.data = buf; + faiss::read_index(&reader); + }, + faiss::FaissException); +} + +#else // !FAISS_ENABLE_SVS + +// When SVS is not enabled, attempting to read an index with an SVS fourcc +// should fail with an "unknown fourcc" error rather than crashing. +TEST(ReadIndexDeserialize, SVSVamanaFourccRejected) { + std::vector buf; + push_fourcc(buf, "ISVD"); + push_index_header(buf, 8, 0); + for (int i = 0; i < 128; i++) { + push_val(buf, 0); + } + + expect_read_throws_with(buf, "fourcc"); +} + +#endif // FAISS_ENABLE_SVS