Commit 33a192fc authored by Davis King's avatar Davis King

Fixed a bug pointed out by Joel Nelson in the version of md5() that took an

istream.  The bug caused the function to crash on strings longer than 56
characters.
parent 9f44528d
......@@ -6,6 +6,7 @@
#include "../uintn.h"
#include <sstream>
#include <cstring>
namespace dlib
{
......@@ -461,6 +462,7 @@ namespace dlib
bool write_length = false;
bool at_end = false;
std::streambuf& inputbuf = *input.rdbuf();
while(!at_end)
......@@ -473,7 +475,12 @@ namespace dlib
{
at_end = true;
unsigned char* temp2 = temp;
unsigned char* end = temp+56;
unsigned char* end;
if (num < 56)
end = temp+56;
else
end = temp+64;
temp2 += num;
// apply padding
......@@ -486,38 +493,42 @@ namespace dlib
}
// make len the number of bits in the original message
// but first multiply len by 8 and since len is only 32 bits the number might
// overflow so we will carry out the multiplication manually and end up with
// the result in the base 65536 number with three digits
// result = low + high*65536 + upper*65536*65536
unsigned long low = len & 0xFFFF;
unsigned long high = len >> 16;
unsigned long upper;
unsigned long tmp;
tmp = low * 8;
low = tmp & 0xFFFF;
tmp = high * 8 + (tmp>>16);
high = tmp & 0xFFFF;
upper = tmp >> 16;
// append the length
*temp2 = static_cast<unsigned char>(low&0xFF);
++temp2;
*temp2 = static_cast<unsigned char>((low>>8)&0xFF);
++temp2;
*temp2 = static_cast<unsigned char>((high)&0xFF);
++temp2;
*temp2 = static_cast<unsigned char>((high>>8)&0xFF);
++temp2;
*temp2 = static_cast<unsigned char>((upper)&0xFF);;
++temp2;
*temp2 = static_cast<unsigned char>((upper>>8)&0xFF);;
++temp2;
*temp2 = 0;
++temp2;
*temp2 = 0;
if (num < 56)
{
write_length = true;
// make len the number of bits in the original message
// but first multiply len by 8 and since len is only 32 bits the number might
// overflow so we will carry out the multiplication manually and end up with
// the result in the base 65536 number with three digits
// result = low + high*65536 + upper*65536*65536
unsigned long low = len & 0xFFFF;
unsigned long high = len >> 16;
unsigned long upper;
unsigned long tmp;
tmp = low * 8;
low = tmp & 0xFFFF;
tmp = high * 8 + (tmp>>16);
high = tmp & 0xFFFF;
upper = tmp >> 16;
// append the length
*temp2 = static_cast<unsigned char>(low&0xFF);
++temp2;
*temp2 = static_cast<unsigned char>((low>>8)&0xFF);
++temp2;
*temp2 = static_cast<unsigned char>((high)&0xFF);
++temp2;
*temp2 = static_cast<unsigned char>((high>>8)&0xFF);
++temp2;
*temp2 = static_cast<unsigned char>((upper)&0xFF);;
++temp2;
*temp2 = static_cast<unsigned char>((upper>>8)&0xFF);;
++temp2;
*temp2 = 0;
++temp2;
*temp2 = 0;
}
}
......@@ -551,6 +562,29 @@ namespace dlib
}
if (!write_length)
{
uint64 temp = len*8;
uint32 aa = a;
uint32 bb = b;
uint32 cc = c;
uint32 dd = d;
std::memset(x, 0, sizeof(x));
x[15] = (temp>>32);
x[14] = (temp&0xFFFFFFFF);
scramble_block(a,b,c,d,x);
a = a + aa;
b = b + bb;
c = c + cc;
d = d + dd;
}
// put a, b, c, and d into output
output[0] = static_cast<unsigned char>((a) &0xFF);
......
......@@ -35,6 +35,16 @@ namespace
DLIB_TEST(md5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") == "d174ab98d277d9f5a5611c2c9f419d9f");
DLIB_TEST(md5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") == "57edf4a22be3c955ac49da2e2107b67a");
// make sure the two versions of md5() always agree
for (int num = 0; num < 2000; ++num)
{
std::string temp;
for (int i = 0; i < num; ++i)
temp += 'a';
istringstream str(temp);
DLIB_TEST(md5(temp) == md5(str));
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment