$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Paul Giaccone (paulg_at_[hidden])
Date: 2006-01-19 13:06:50
Paul Giaccone wrote:
>How can you deal with a corrupt file when using filters?
>
>I have a chain of filters that includes a bzip2 and multichar filter 
>have written myself.  If the read() function fails to find what it 
>expects in the file, it returns 0 (meaning "no characters read").  
>Otherwise it returns the number of characters read (which should be 
>equal to the number of characters requested in the third function 
>parameter) or -1 if the end of the file is reached.
>
>This works fine if the file is as is required, but if it is corrupted in 
>any way, the program either hangs or crashes at
>
>   if (s->strm != strm) return BZ_PARAM_ERROR;
>
>in bzlib.c, with s as a pointer that cannot be read (set to 0xcdcdcdcd).
>
>I'm working in Microsoft Visual C++ and gcc 3.2.3.
>
>How should this be handled?  I haven't seen anything about it in the 
>documentation.  I imagine I should throw an exception instead of 
>returning 0 (perhaps an iostreams exception?).  Given that the crash is 
>the bzip2 (bzip2 being the first operation done when deserialising the 
>file), where would I put the associated catch block?
>
OK, I throw an exception if my filter finds an error, but the error is 
clearly being caused at the bzip stage.  How can I trap that?
Here's a summary of what I am doing:
Filter chain:
    try
    {
        boost::iostreams::filtering_istream in;
        in.push(boost::iostreams::bzip2_decompressor());
        in.push(InputEncryptionFilter());
        in.push(boost::iostreams::bzip2_decompressor());
        in.push(boost::iostreams::file_source(filename, BOOST_IOS::in | 
BOOST_IOS::binary));
        assert(in.is_complete());
        boost::archive::xml_iarchive input_archive(in);
        my_data >> BOOST_SERIALIZATION_NVP(my_object);
        return;
    }
    catch (MyException e)
    {
        std::cerr << "Error reading archive file " << filename << ": " 
<< e.what() << std::endl;
    }
    catch (boost::archive::archive_exception e)
    {
        std::cerr << "Error decoding archive file " << filename << ": " 
<< e.what() << std::endl;
    }
    catch (std::ios_base::failure e)
    {
        std::cerr << "Error reading from file " << filename << ": " << 
e.what() << std::endl;
    }
I am deliberatively providing the above with a corrupted file that bzip2 
will not be able to understand.  None of the "catch"es above are executed.
So how can I catch a problem at the bzip2 stage?
Paul Giaccone