Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r79588 - in trunk: boost/algorithm libs/algorithm/test
From: marshall_at_[hidden]
Date: 2012-07-18 14:16:39


Author: marshall
Date: 2012-07-18 14:16:39 EDT (Wed, 18 Jul 2012)
New Revision: 79588
URL: http://svn.boost.org/trac/boost/changeset/79588

Log:
fixed a bug in boost::algorithm::unhex(T*,) where it was throwing the wrong exception on short input
Text files modified:
   trunk/boost/algorithm/hex.hpp | 36 ++++++++++++++----------------------
   trunk/libs/algorithm/test/hex_test4.cpp | 32 ++++++++++++++++----------------
   2 files changed, 30 insertions(+), 38 deletions(-)

Modified: trunk/boost/algorithm/hex.hpp
==============================================================================
--- trunk/boost/algorithm/hex.hpp (original)
+++ trunk/boost/algorithm/hex.hpp 2012-07-18 14:16:39 EDT (Wed, 18 Jul 2012)
@@ -110,33 +110,25 @@
       typedef T value_type;
   };
 
-// Output Iterators have a value type of 'void'. Kinda sucks.
-// We special case some output iterators, but we can't enumerate them all.
-// If we can't figure it out, we assume that you want to output chars.
-// If you don't, pass in an iterator with a real value_type.
- template <typename T> struct value_type_or_char { typedef T value_type; };
- template <> struct value_type_or_char<void> { typedef char value_type; };
-
-// All in one step
- template <typename Iterator>
- struct iterator_value_type {
-// typedef typename value_type_or_char<typename hex_iterator_traits<Iterator>::value_type>::value_type value_type;
- typedef typename hex_iterator_traits<Iterator>::value_type value_type;
- };
-
+ template <typename Iterator>
+ bool iter_end ( Iterator current, Iterator last ) { return current == last; }
+
+ template <typename T>
+ bool ptr_end ( const T* ptr, const T* /*end*/ ) { return *ptr == '\0'; }
+
 // What can we assume here about the inputs?
 // is std::iterator_traits<InputIterator>::value_type always 'char' ?
 // Could it be wchar_t, say? Does it matter?
 // We are assuming ASCII for the values - but what about the storage?
- template <typename InputIterator, typename OutputIterator>
- typename boost::enable_if<boost::is_integral<typename iterator_value_type<OutputIterator>::value_type>, OutputIterator>::type
- decode_one ( InputIterator &first, InputIterator last, OutputIterator out ) {
- typedef typename iterator_value_type<OutputIterator>::value_type T;
+ template <typename InputIterator, typename OutputIterator, typename EndPred>
+ typename boost::enable_if<boost::is_integral<typename hex_iterator_traits<OutputIterator>::value_type>, OutputIterator>::type
+ decode_one ( InputIterator &first, InputIterator last, OutputIterator out, EndPred pred ) {
+ typedef typename hex_iterator_traits<OutputIterator>::value_type T;
         T res (0);
 
     // Need to make sure that we get can read that many chars here.
         for ( std::size_t i = 0; i < 2 * sizeof ( T ); ++i, ++first ) {
- if ( first == last )
+ if ( pred ( first, last ))
                 BOOST_THROW_EXCEPTION (not_enough_input ());
             res = ( 16 * res ) + hex_char_to_int (static_cast<char> (*first));
             }
@@ -205,7 +197,7 @@
 template <typename InputIterator, typename OutputIterator>
 OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ) {
     while ( first != last )
- out = detail::decode_one ( first, last, out );
+ out = detail::decode_one ( first, last, out, detail::iter_end<InputIterator> );
     return out;
     }
 
@@ -219,12 +211,12 @@
 /// \note Based on the MySQL function of the same name
 template <typename T, typename OutputIterator>
 OutputIterator unhex ( const T *ptr, OutputIterator out ) {
- typedef typename detail::iterator_value_type<OutputIterator>::value_type OutputType;
+ typedef typename detail::hex_iterator_traits<OutputIterator>::value_type OutputType;
 // If we run into the terminator while decoding, we will throw a
 // malformed input exception. It would be nicer to throw a 'Not enough input'
 // exception - but how much extra work would that require?
     while ( *ptr )
- out = detail::decode_one ( ptr, (const T *) NULL, out );
+ out = detail::decode_one ( ptr, (const T *) NULL, out, detail::ptr_end<T> );
     return out;
     }
 

Modified: trunk/libs/algorithm/test/hex_test4.cpp
==============================================================================
--- trunk/libs/algorithm/test/hex_test4.cpp (original)
+++ trunk/libs/algorithm/test/hex_test4.cpp 2012-07-18 14:16:39 EDT (Wed, 18 Jul 2012)
@@ -56,12 +56,25 @@
         BOOST_CHECK ( false );
         }
 
+// Make sure that the right thing is thrown
+void test_short_input5 () {
+ std::string s;
+
+ try { ba::unhex ( "A", std::back_inserter(s)); }
+ catch ( const ba::non_hex_input &ex ) { BOOST_CHECK ( false ); }
+ catch ( const ba::not_enough_input &ex ) { return; }
+ catch ( ... ) { BOOST_CHECK ( false ); }
+ BOOST_CHECK ( false );
+ }
+
+
 void test_short_input () {
 // BOOST_TEST_MESSAGE ( "Short input tests for boost::algorithm::unhex" );
         test_short_input1 ();
         test_short_input2 ();
         test_short_input3 ();
         test_short_input4 ();
+ test_short_input5 ();
         }
 
 
@@ -73,6 +86,7 @@
                 BOOST_CHECK ( 'G' == *boost::get_error_info<ba::bad_char>(ex));
                 return;
                 }
+ catch ( ... ) {}
         BOOST_TEST_MESSAGE ( "Failed to catch std::exception in test_nonhex_input1" );
         BOOST_CHECK ( false );
         }
@@ -85,6 +99,7 @@
                 BOOST_CHECK ( 'Z' == *boost::get_error_info<ba::bad_char>(ex));
                 return;
                 }
+ catch ( ... ) {}
         BOOST_TEST_MESSAGE ( "Failed to catch ba::hex_decode_error in test_nonhex_input2" );
         BOOST_CHECK ( false );
         }
@@ -97,6 +112,7 @@
                 BOOST_CHECK ( 'Q' == *boost::get_error_info<ba::bad_char>(ex));
                 return;
                 }
+ catch ( ... ) {}
         BOOST_TEST_MESSAGE ( "Failed to catch ba::non_hex_input in test_nonhex_input3" );
         BOOST_CHECK ( false );
         }
@@ -112,30 +128,14 @@
         BOOST_CHECK ( false );
         }
 
-// Make sure that the right thing is thrown
-void test_nonhex_input5 () {
- std::string s;
-
- try { ba::unhex ( "012", std::back_inserter(s)); }
- catch ( const ba::non_hex_input &ex ) {
- BOOST_CHECK ( '\000' == *boost::get_error_info<ba::bad_char>(ex));
- return;
- }
- BOOST_TEST_MESSAGE ( "Failed to catch ba::non_hex_input in test_nonhex_input4" );
- BOOST_CHECK ( false );
- }
-
 void test_nonhex_input () {
 // BOOST_TEST_MESSAGE ( "Non hex input tests for for boost::algorithm::unhex" );
         test_nonhex_input1 ();
         test_nonhex_input2 ();
         test_nonhex_input3 ();
         test_nonhex_input4 ();
- test_nonhex_input5 ();
         }
 
-
-
 int test_main( int , char* [] )
 {
         test_short_input ();


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk