Boost logo

Boost :

Subject: Re: [boost] [serialization] Reading newer archives - was throwing unsupported_class_version, now crashes
From: Nikolay Mladenov (nikolay.mladenov_at_[hidden])
Date: 2012-05-11 08:14:29


On Fri, May 11, 2012 at 2:06 AM, Robert Ramey <ramey_at_[hidden]> wrote:

> 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.
>

I am not sure how to understand this. The commented out code checks for
future versions, not for previous versions?

> Robert Ramey
>
> > Thanks in advance,
> >
> > Nikolay Mladenov
> > Sitius Automation Inc.
>

If I am to avoid the crash when reading future version I seem to have 2
options:
1) add a check in every load/serialize function and throw when future
version is detected
2) add the same check but in the fuction or functions that call the
load/serialize functions

My problem with 1 is that there are many calls that need to be fixed, plus
a new guideline
is needed for future serializable classes. Not to mention that this problem
applies to other people and companies
(https://svn.boost.org/trac/boost/ticket/6856)

And my problem with 2 is that I have to mess up with the serialization
library which I am not so familiar with.

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