Boost logo

Boost :

Subject: [boost] [serialization] Reading newer archives - was throwing unsupported_class_version, now crashes
From: Nikolay Mladenov (nikolay.mladenov_at_[hidden])
Date: 2012-05-10 23:32:18


Hi Robert,

I remember that in the past the serialization library was throwing
unsupported_class_version exception when reading of archives with future
class versions.
This no longer seems to be the case. We had older version of software crash
when reading newer archive.

The only place that I found to mention unsupported_class_version is
commented out and I do not understand the attached note:

BOOST_DLLEXPORT void iserializer<Archive, T>::load_object_data(
    basic_iarchive & ar,
    void *x,
    const unsigned int file_version
) const {
    // note: we now comment this out. Before we permited archive
    // version # to be very large. Now we don't. To permit
    // readers of these old archives, we have to suppress this
    // code. Perhaps in the future we might re-enable it but
    // permit its suppression with a runtime switch.
    #if 0
    // trap case where the program cannot handle the current version
    if(file_version > static_cast<const unsigned int>(version()))
        boost::serialization::throw_exception(
            archive::archive_exception(

boost::archive::archive_exception::unsupported_class_version,
                get_debug_info()
            )
        );
    #endif
    // make sure call is routed through the higest interface that might
    // be specialized by the user.
    boost::serialization::serialize_adl(
        boost::serialization::smart_cast_reference<Archive &>(ar),
        * static_cast<T *>(x),
        file_version
    );
}

To allow class to read serialized objects of newer version by default seems
very dangerous.
I generally requires extra work from the class author and without it will
most likely crash.

So isn't it better to have an additional trait that a class author needs to
define, if a class should be allowed read future versions?

something like

namespace boost{ namespace serialization
{
  template<class T> struct allow_future_versions : mpl::false_ {};
}}

#define BOOST_SERIALIZATION_ALLOW_FUTURE_VERSIONS(T) \
namespace boost{ namespace serialization \
{ \
  template<> struct allow_future_versions<T> : mpl::true_ {}; \
}}

and change the code above to:

BOOST_DLLEXPORT void iserializer<Archive, T>::load_object_data(
    basic_iarchive & ar,
    void *x,
    const unsigned int file_version
) const {
    // trap case where the program cannot handle the current version
    if( ! boost::serialization::allow_future_versions<T>::value &&
file_version > static_cast<const unsigned int>(version()))
        boost::serialization::throw_exception(
            archive::archive_exception(

boost::archive::archive_exception::unsupported_class_version,
                get_debug_info()
            )
        );

......

Thanks in advance,

Nikolay Mladenov
Sitius Automation Inc.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk