$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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 ();