Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>Research</h2> <p><strong>std::ios_base::failure</strong> is the "the base class for the types of all objects thrown as exceptions, by functions in the Iostreams library, to report errors detected during stream buffer operations."</p> <p><a href="http://www.boost.org/doc/libs/1_43_0/libs/iostreams/doc/index.html" rel="nofollow noreferrer">Looking</a> at the boost docs:</p> <pre><code>class bzip2_error : public std::ios_base::failure { public: bzip2_error(int error); int error() const; }; </code></pre> <p><strong>bzip2_error</strong> is a specific exception thrown when using the bzip2 filter, which inherits from <strong>std::ios_base::failure</strong>. As you can see, it is constructed by passing in an integer representing the error code. It also has a method <strong>error()</strong> which returns the error code it was constructed with.<br> The docs list bzip2 error codes as the following:</p> <ul> <li><strong>data_error</strong> - Indicates that the compressed data stream is corrupted. Equal to BZ_DATA_ERROR.</li> <li><strong>data_error_magic</strong> - Indicates that the compressed data stream does not begin with the 'magic' sequence 'B' 'Z' 'h'. Equal to BZ_DATA_ERROR_MAGIC.</li> <li><strong>config_error</strong> - Indicates that libbzip2 has been improperly configured for the current platform. Equal to BZ_CONFIG_ERROR.</li> </ul> <h2>Code</h2> <p><strong>EDIT</strong> I also want to clarify that boost::iostreams::copy() will not be the one throwing the exception here, but the bzip2 filter. Only the iostream or filters will throw exceptions, copy just <em>uses</em> the iostream/filter which may cause the iostream/filter to throw an exception.</p> <p>**EDIT 2 ** It appears the problem is with bzip2_decompressor_impl as you have expected. I have replicated the endless spinning loop when the bz2 file is empty. It took me a little while to figure out how to build boost and link with bzip2, zlib, and iostreams library to see if I could replicate your results. </p> <pre><code>g++ test.cpp -lz -lbz2 boostinstall/boost/bin.v2/libs/iostreams/build/darwin-4.2.1/release/link-static/threading-multi/libboost_iostreams.a -Lboostinstall/boost/bin.v2/libs/ -Iboost/include/boost-1_42 -g </code></pre> <p>test.cpp:</p> <pre><code>#include &lt;fstream&gt; #include &lt;iostream&gt; #include &lt;boost/iostreams/filtering_streambuf.hpp&gt; #include &lt;boost/iostreams/copy.hpp&gt; #include &lt;boost/iostreams/filter/bzip2.hpp&gt; int main() { using namespace std; using namespace boost::iostreams; try { ifstream file("hello.bz2", ios_base::in | ios_base::binary); filtering_streambuf&lt;input&gt; in; in.push(bzip2_decompressor()); in.push(file); boost::iostreams::copy(in, cout); } catch(const bzip2_error&amp; exception) { int error = exception.error(); if(error == boost::iostreams::bzip2::data_error) { // compressed data stream is corrupted cout &lt;&lt; "compressed data stream is corrupted"; } else if(error == boost::iostreams::bzip2::data_error_magic) { // compressed data stream does not begin with the 'magic' sequence 'B' 'Z' 'h' cout &lt;&lt; "compressed data stream does not begin with the 'magic' sequence 'B' 'Z' 'h'"; } else if(boost::iostreams::bzip2::config_error) { // libbzip2 has been improperly configured for the current platform cout &lt;&lt; "libbzip2 has been improperly configured for the current platform"; } } } </code></pre> <p>debugging:</p> <pre><code>gdb a.out (gdb) b bzip2.hpp:344 </code></pre> <p>There is a loop that drives the bzip2's uncompression in symmetric.hpp:109 :</p> <pre><code> while (true) { // Invoke filter if there are unconsumed characters in buffer or if // filter must be flushed. bool flush = status == f_eof; if (buf.ptr() != buf.eptr() || flush) { const char_type* next = buf.ptr(); bool done = !filter().filter(next, buf.eptr(), next_s, end_s, flush); buf.ptr() = buf.data() + (next - buf.data()); if (done) return detail::check_eof( static_cast&lt;std::streamsize&gt;(next_s - s) ); } // If no more characters are available without blocking, or // if read request has been satisfied, return. if ( (status == f_would_block &amp;&amp; buf.ptr() == buf.eptr()) || next_s == end_s ) { return static_cast&lt;std::streamsize&gt;(next_s - s); } // Fill buffer. if (status == f_good) status = fill(src); } </code></pre> <p>bzip2_decompressor_impl's filter method bzip2.hpp:344 gets called on symmetric.hpp:117 :</p> <pre><code>template&lt;typename Alloc&gt; bool bzip2_decompressor_impl&lt;Alloc&gt;::filter ( const char*&amp; src_begin, const char* src_end, char*&amp; dest_begin, char* dest_end, bool /* flush */ ) { if (!ready()) init(); if (eof_) return false; before(src_begin, src_end, dest_begin, dest_end); int result = decompress(); after(src_begin, dest_begin); bzip2_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); return !(eof_ = result == bzip2::stream_end); } </code></pre> <p>I think the problem is simple, the bzip2_decompressor_impl's eof_ flag never gets set. Unless it's suppose to happen in some magic way I don't understand, it's owned by the bzip2_decompressor_impl class and it's only ever being set to false. So when we do this:</p> <pre><code>cat /dev/null &gt; hello.bz2 </code></pre> <p>We get a spinning loop that never ends, we don't break when an EOF is hit. This is certainly a bug, because other programs (like vim) would have no problem opening a text file created in a similar manner. However I am able to get the filter to throw when the bz2 file is "corrupted":</p> <pre><code>echo "other corrupt" &gt; hello.bz2 ./a.out compressed data stream does not begin with the 'magic' sequence 'B' 'Z' 'h' </code></pre> <p>Sometimes you have to take open source code with a grain of salt. It will be more likely that your bz2's will be corrupted and properly throw. However, the /dev/null case is a serious bug. We should submit it to the boost dev so they can fix it.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload