On Sun, Apr 04, 2010 at 09:47:36PM +0200, sean finney wrote:
> fixing both of these doesn't fix the problem, though the protoc program
> does get a tiny bit further before abort()ing.

also, ConsumeSignedInteger (text_format.cc), usage of enum WireType,
(wire_format_lite.h), FastUInt32ToBufferLeft (strutil.cc).  there are
definitely more, but these combined with a non-overflowing fix for the
previous two hashing functions gets the test suite passing, anyway.

diff --git a/src/google/protobuf/stubs/strutil.cc 
b/src/google/protobuf/stubs/strutil.cc
index bb658ba..b0efbc7 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -746,7 +746,7 @@ char* FastUInt32ToBufferLeft(uint32 u, char* buffer) {
     buffer[1] = ASCII_digits[1];
     buffer += 2;
 sublt100_000_000:
-    u -= digits * 100000000;  // 100,000,000
+    u -= (unsigned)digits * 100000000;  // 100,000,000
 lt100_000_000:
     digits = u / 1000000;  // 1,000,000
     ASCII_digits = two_ASCII_digits[digits];
@@ -754,7 +754,7 @@ lt100_000_000:
     buffer[1] = ASCII_digits[1];
     buffer += 2;
 sublt1_000_000:
-    u -= digits * 1000000;  // 1,000,000
+    u -= (unsigned)digits * 1000000;  // 1,000,000
 lt1_000_000:
     digits = u / 10000;  // 10,000
     ASCII_digits = two_ASCII_digits[digits];
@@ -762,7 +762,7 @@ lt1_000_000:
     buffer[1] = ASCII_digits[1];
     buffer += 2;
 sublt10_000:
-    u -= digits * 10000;  // 10,000
+    u -= (unsigned)digits * 10000;  // 10,000
 lt10_000:
     digits = u / 100;
     ASCII_digits = two_ASCII_digits[digits];
@@ -770,7 +770,7 @@ lt10_000:
     buffer[1] = ASCII_digits[1];
     buffer += 2;
 sublt100:
-    u -= digits * 100;
+    u -= (unsigned)digits * 100;
 lt100:
     digits = u;
     ASCII_digits = two_ASCII_digits[digits];
diff --git a/src/google/protobuf/text_format.cc 
b/src/google/protobuf/text_format.cc
index 137cbce..8e6ef86 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -523,7 +523,8 @@ class TextFormat::Parser::ParserImpl {
 
     *value = static_cast<int64>(unsigned_value);
 
-    if (negative) {
+    // if value is LONG_MIN don't negate it, lest u overflow.
+    if (negative && (uint64)*value != 0x8000000000000000ULL) {
       *value = -*value;
     }
 
diff --git a/src/google/protobuf/wire_format_lite.h 
b/src/google/protobuf/wire_format_lite.h
index e3d5b2d..2e7db30 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -86,6 +86,7 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
   // unrecognized fields for forwards compatibility.
 
   enum WireType {
+    WIRETYPE_INVALID          = -1,
     WIRETYPE_VARINT           = 0,
     WIRETYPE_FIXED64          = 1,
     WIRETYPE_LENGTH_DELIMITED = 2,


-- 

Attachment: signature.asc
Description: Digital signature

Reply via email to