From dd09b03d333e9a5d80f2ee49f03ea21171827807 Mon Sep 17 00:00:00 2001 From: Lee Clagett Date: Fri, 4 Aug 2017 23:04:42 -0400 Subject: [PATCH] Fixed bug where pointer iserializer can be NULL --- src/basic_iarchive.cpp | 6 ++++ test/test_unregistered.cpp | 72 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/basic_iarchive.cpp b/src/basic_iarchive.cpp index cdf71b07..a5455a53 100644 --- a/src/basic_iarchive.cpp +++ b/src/basic_iarchive.cpp @@ -459,6 +459,12 @@ basic_iarchive_impl::load_pointer( cobject_id & co = cobject_id_vector[i]; bpis_ptr = co.bpis_ptr; + if (bpis_ptr == NULL) { + boost::serialization::throw_exception( + archive_exception(archive_exception::unregistered_class) + ); + } + load_preamble(ar, co); // extra line to evade borland issue diff --git a/test/test_unregistered.cpp b/test/test_unregistered.cpp index 30951b8f..9236bfa5 100644 --- a/test/test_unregistered.cpp +++ b/test/test_unregistered.cpp @@ -12,6 +12,7 @@ #include // NULL #include // remove +#include // strcmp #include #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{ @@ -54,6 +55,22 @@ class polymorphic_derived2 : public polymorphic_base } }; +struct type1 { + template + void serialize(Archive&, unsigned int ver) { + BOOST_CHECK(ver == 1); + } +}; +struct type2 { + template + void serialize(Archive&, unsigned int ver) { + BOOST_CHECK(ver == 2); + } +}; + +BOOST_CLASS_VERSION(type1, 1); +BOOST_CLASS_VERSION(type2, 2); + // save unregistered polymorphic classes void save_unregistered1(const char *testfile) { @@ -61,7 +78,7 @@ void save_unregistered1(const char *testfile) test_oarchive oa(os, TEST_ARCHIVE_FLAGS); polymorphic_base *rb1 = new polymorphic_derived1; - + // registration IS necessary when serializing a polymorphic class // through pointer to the base class bool except = false; @@ -98,7 +115,7 @@ void load_unregistered1(const char *testfile) BOOST_CATCH(boost::archive::archive_exception aex){ except = true; BOOST_CHECK_MESSAGE( - NULL == rb1, + NULL == rb1, "failed load resulted in a non-null pointer" ); } @@ -227,6 +244,55 @@ void load_registered(const char *testfile) delete rb2; } +// store a pointer from slot0 +void save_unregistered_pointer(const char *testfile) +{ + test_ostream os(testfile, TEST_STREAM_FLAGS); + test_oarchive oa(os, TEST_ARCHIVE_FLAGS); + + oa.register_type(static_cast(NULL)); + + type1 instance1; + type2 *pointer2 = new type2; + + BOOST_TRY { + oa & BOOST_SERIALIZATION_NVP(instance1) & BOOST_SERIALIZATION_NVP(pointer2); + } + BOOST_CATCH(...) { + BOOST_CHECK_MESSAGE(false, "unexpected exception"); + } + BOOST_CATCH_END + + delete pointer2; +} + +// load a pointer from slot0 which has no pointer serializer +void load_unregistered_pointer(const char *testfile) +{ + test_istream is(testfile); + test_iarchive ia(is); + + type1 instance1; + type2 *pointer2(NULL); + + bool except = false; + BOOST_TRY { + ia & BOOST_SERIALIZATION_NVP(instance1) & BOOST_SERIALIZATION_NVP(pointer2); + } + BOOST_CATCH(boost::archive::archive_exception aex){ + except = true; + BOOST_CHECK_MESSAGE( + std::strcmp(aex.what(), "unregistered class") == 0, + "incorrect exception" + ); + } + BOOST_CATCH_END + BOOST_CHECK_MESSAGE(except, "lack of registration not detected !"); + BOOST_CHECK_MESSAGE(NULL == pointer2, "expected failed load"); + + delete pointer2; +} + int test_main( int /* argc */, char* /* argv */[] ) { @@ -238,6 +304,8 @@ test_main( int /* argc */, char* /* argv */[] ) load_unregistered2(testfile); save_registered(testfile); load_registered(testfile); + save_unregistered_pointer(testfile); + load_unregistered_pointer(testfile); std::remove(testfile); return EXIT_SUCCESS; }