[iostreams] Error-handling with filters
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? Thanks, Paul
Paul Giaccone wrote:
How can you deal with a corrupt file when using filters?
[...]
This works fine if the file is as is required, but if it is corrupted in any way, the program either hangs or crashes.
[...]
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?
It's OK, I think I've found what I need in the docs to write an exception: section 3.10 of http://boost.org/libs/iostreams/doc/index.html
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
Paul Giaccone wrote:
Paul Giaccone wrote:
How can you deal with a corrupt file when using filters?
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).
So how can I catch a problem at the bzip2 stage?
Is this a bug in the bzip library or in boost::iostreams? The crash is in BZ_API() (), which comes from from bzip.c. This function is being called from bzip2_base::end(), which is part of the boost::iostreams library. If someone would like to test this, I can provide the file that causes the problem. I'd like to know whether I should be posting this problem to the makers of bzip instead. Thanks.
participants (1)
-
Paul Giaccone