Skip to content

Commit 463710f

Browse files
committed
mitigate corrupted caches (#129)
1 parent ce26b33 commit 463710f

2 files changed

Lines changed: 47 additions & 30 deletions

File tree

src/plugins/gta3/std.data/cache.hpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -381,25 +381,30 @@ class data_cache : public modloader::basic_cache
381381
using stream_type = typename std::conditional<Output, std::ofstream, std::ifstream>::type;
382382
using archive_type = typename std::conditional<Output, cereal::BinaryOutputArchive, cereal::BinaryInputArchive>::type;
383383

384-
stream_type ss;
384+
try {
385+
stream_type ss;
385386

386-
std::unique_ptr<char[]> buffer(new char[buffer_size]);
387-
ss.rdbuf()->pubsetbuf(buffer.get(), buffer_size);
387+
std::unique_ptr<char[]> buffer(new char[buffer_size]);
388+
ss.rdbuf()->pubsetbuf(buffer.get(), buffer_size);
388389

389-
ss.open(filepath, std::ios::binary);
390-
if(ss.is_open())
391-
{
392-
uint32_t version = build_identifier(); // This variable won't change in the case of a output stream,
393-
// but will in the case of a input stream, in any case default initialize for the output case
394-
archive_type archive(ss);
395-
archive(version);
396-
if(version == build_identifier()) // Make sure serialization version matches
390+
ss.open(filepath, std::ios::binary);
391+
if(ss.is_open())
397392
{
398-
func(ss, archive);
399-
return true;
393+
uint32_t version = build_identifier(); // This variable won't change in the case of a output stream,
394+
// but will in the case of a input stream, in any case default initialize for the output case
395+
archive_type archive(ss);
396+
archive(version);
397+
if(version == build_identifier()) // Make sure serialization version matches
398+
{
399+
func(ss, archive);
400+
return true;
401+
}
402+
else
403+
plugin_ptr->Log("Warning: Incompatible cache version, a new cache will be generated.");
400404
}
401-
else
402-
plugin_ptr->Log("Warning: Incompatible cache version, a new cache will be generated.");
405+
} catch (const std::exception &e) {
406+
// TODO(#131): fix root cause of these exceptions
407+
plugin_ptr->Log("Error: Failed to perform cache operation: %s on %s", e.what(), filepath.c_str());
403408
}
404409
return false;
405410
}

src/plugins/gta3/std.data/main.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -638,15 +638,21 @@ auto DataPlugin::ReadCachedReadmeListing() -> readme_listing_type
638638
{
639639
readme_listing_type cached_readme_listing;
640640

641-
std::ifstream ss(cache.GetCachePath("readme.ld"), std::ios::binary);
642-
if(ss.is_open())
643-
{
644-
cereal::BinaryInputArchive archive(ss);
645-
if(VerifyCachedReadme(ss, archive))
641+
try {
642+
std::ifstream ss(cache.GetCachePath("readme.ld"), std::ios::binary);
643+
if(ss.is_open())
646644
{
647-
block_reader listing_block(ss);
648-
archive(cached_readme_listing);
645+
cereal::BinaryInputArchive archive(ss);
646+
if(VerifyCachedReadme(ss, archive))
647+
{
648+
block_reader listing_block(ss);
649+
archive(cached_readme_listing);
650+
}
649651
}
652+
} catch(const std::exception& e) {
653+
// TODO(#131): fix root cause of these exceptions
654+
this->Log("Error: Failed to read cached readme listing: %s", e.what());
655+
cached_readme_listing.clear();
650656
}
651657
return cached_readme_listing;
652658
}
@@ -659,16 +665,22 @@ auto DataPlugin::ReadCachedReadmeStore() -> readme_data_store
659665
{
660666
readme_data_store store_lines;
661667

662-
std::ifstream ss(cache.GetCachePath("readme.ld"), std::ios::binary);
663-
if(ss.is_open())
664-
{
665-
cereal::BinaryInputArchive archive(ss);
666-
if(VerifyCachedReadme(ss, archive))
668+
try {
669+
std::ifstream ss(cache.GetCachePath("readme.ld"), std::ios::binary);
670+
if(ss.is_open())
667671
{
668-
block_reader::skip(ss); // skip listing block
669-
block_reader lines_block(ss);
670-
archive(store_lines);
672+
cereal::BinaryInputArchive archive(ss);
673+
if(VerifyCachedReadme(ss, archive))
674+
{
675+
block_reader::skip(ss); // skip listing block
676+
block_reader lines_block(ss);
677+
archive(store_lines);
678+
}
671679
}
680+
} catch(const std::exception& e) {
681+
// TODO(#131): fix root cause of these exceptions
682+
this->Log("Error: Failed to read cached readme store: %s", e.what());
683+
store_lines.clear();
672684
}
673685
return store_lines;
674686
}

0 commit comments

Comments
 (0)