Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r76405 - branches/release/boost/uuid
From: atompkins_at_[hidden]
Date: 2012-01-10 23:11:51


Author: atompkins
Date: 2012-01-10 23:11:49 EST (Tue, 10 Jan 2012)
New Revision: 76405
URL: http://svn.boost.org/trac/boost/changeset/76405

Log:
fixed ticket #5325
Text files modified:
   branches/release/boost/uuid/sha1.hpp | 53 +++++++++++++++++++++++++--------------
   1 files changed, 34 insertions(+), 19 deletions(-)

Modified: branches/release/boost/uuid/sha1.hpp
==============================================================================
--- branches/release/boost/uuid/sha1.hpp (original)
+++ branches/release/boost/uuid/sha1.hpp 2012-01-10 23:11:49 EST (Tue, 10 Jan 2012)
@@ -8,15 +8,16 @@
 // Revision History
 // 29 May 2007 - Initial Revision
 // 25 Feb 2008 - moved to namespace boost::uuids::detail
+// 10 Jan 2012 - can now handle the full size of messages (2^64 - 1 bits)
 
 // This is a byte oriented implementation
-// Note: this implementation does not handle message longer than
-// 2^32 bytes.
 
 #ifndef BOOST_UUID_SHA1_H
 #define BOOST_UUID_SHA1_H
 
 #include <boost/static_assert.hpp>
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
 #include <cstddef>
 
 #ifdef BOOST_NO_STDC_NAMESPACE
@@ -54,6 +55,7 @@
 
 private:
     void process_block();
+ void process_byte_impl(unsigned char byte);
 
 private:
     unsigned int h_[5];
@@ -61,7 +63,8 @@
     unsigned char block_[64];
 
     std::size_t block_byte_index_;
- std::size_t byte_count_;
+ std::size_t bit_count_low;
+ std::size_t bit_count_high;
 };
 
 inline sha1::sha1()
@@ -78,13 +81,27 @@
     h_[4] = 0xC3D2E1F0;
 
     block_byte_index_ = 0;
- byte_count_ = 0;
+ bit_count_low = 0;
+ bit_count_high = 0;
 }
 
 inline void sha1::process_byte(unsigned char byte)
 {
+ process_byte_impl(byte);
+
+ bit_count_low += 8;
+ if (bit_count_low == 0) {
+ ++bit_count_high;
+ if (bit_count_high == 0) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("sha1 too many bytes"));
+ }
+ }
+}
+
+inline void sha1::process_byte_impl(unsigned char byte)
+{
     block_[block_byte_index_++] = byte;
- ++byte_count_;
+
     if (block_byte_index_ == 64) {
         block_byte_index_ = 0;
         process_block();
@@ -160,10 +177,8 @@
 
 inline void sha1::get_digest(digest_type digest)
 {
- std::size_t bit_count = byte_count_*8;
-
     // append the bit '1' to the message
- process_byte(0x80);
+ process_byte_impl(0x80);
 
     // append k bits '0', where k is the minimum number >= 0
     // such that the resulting message length is congruent to 56 (mod 64)
@@ -171,29 +186,29 @@
     if (block_byte_index_ > 56) {
         // finish this block
         while (block_byte_index_ != 0) {
- process_byte(0);
+ process_byte_impl(0);
         }
 
         // one more block
         while (block_byte_index_ < 56) {
- process_byte(0);
+ process_byte_impl(0);
         }
     } else {
         while (block_byte_index_ < 56) {
- process_byte(0);
+ process_byte_impl(0);
         }
     }
 
     // append length of message (before pre-processing)
     // as a 64-bit big-endian integer
- process_byte(0);
- process_byte(0);
- process_byte(0);
- process_byte(0);
- process_byte( static_cast<unsigned char>((bit_count>>24) & 0xFF));
- process_byte( static_cast<unsigned char>((bit_count>>16) & 0xFF));
- process_byte( static_cast<unsigned char>((bit_count>>8 ) & 0xFF));
- process_byte( static_cast<unsigned char>((bit_count) & 0xFF));
+ process_byte_impl( static_cast<unsigned char>((bit_count_high>>24) & 0xFF) );
+ process_byte_impl( static_cast<unsigned char>((bit_count_high>>16) & 0xFF) );
+ process_byte_impl( static_cast<unsigned char>((bit_count_high>>8 ) & 0xFF) );
+ process_byte_impl( static_cast<unsigned char>((bit_count_high) & 0xFF) );
+ process_byte_impl( static_cast<unsigned char>((bit_count_low>>24) & 0xFF) );
+ process_byte_impl( static_cast<unsigned char>((bit_count_low>>16) & 0xFF) );
+ process_byte_impl( static_cast<unsigned char>((bit_count_low>>8 ) & 0xFF) );
+ process_byte_impl( static_cast<unsigned char>((bit_count_low) & 0xFF) );
 
     // get final digest
     digest[0] = h_[0];


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