Boost logo

Boost :

Subject: Re: [boost] [serialization] Reading newer archives - was throwing unsupported_class_version, now crashes
From: Robert Ramey (ramey_at_[hidden])
Date: 2012-05-11 02:06:42


Nikolay Mladenov wrote:
> 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()
> )
> );
>
> ......
>

Your right about this and your proposal is a worthy one though I think
there's a simpler way to do it.. I'll look into this.

As to why it's this way, the answer is pretty simple. The original
version of the library has some errors. Problem is, fixing them
is much harder than with other libraries because of the requirement
to maintain the ability to read archives created with previous versions.

Robert Ramey

> Thanks in advance,
>
> Nikolay Mladenov
> Sitius Automation Inc.
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost


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