Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2607)

Unified Diff: runtime/vm/bigint_operations.cc

Issue 23754006: Catch potential integer overflows in bigint operations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/bigint_operations.cc
diff --git a/runtime/vm/bigint_operations.cc b/runtime/vm/bigint_operations.cc
index b7c7a69ff6ff2ea7e4b2e4c1b6ab191066b233eb..0c5299777cb26f50704219714cac00c3571cb917 100644
--- a/runtime/vm/bigint_operations.cc
+++ b/runtime/vm/bigint_operations.cc
@@ -2,6 +2,7 @@
#include "vm/bigint_operations.h"
+#include "platform/assert.h"
#include "platform/utils.h"
#include "vm/double_internals.h"
@@ -106,7 +107,9 @@ RawBigint* BigintOperations::NewFromCString(const char* str,
return result.raw();
}
- intptr_t str_length = strlen(str);
+ // No overflow check needed since overflowing str_length implies that we take
+ // the branch to FromDecimalCString() which contains a check itself.
+ const intptr_t str_length = strlen(str);
if ((str_length > 2) &&
(str[0] == '0') &&
((str[1] == 'x') || (str[1] == 'X'))) {
@@ -121,7 +124,11 @@ RawBigint* BigintOperations::NewFromCString(const char* str,
intptr_t BigintOperations::ComputeChunkLength(const char* hex_string) {
ASSERT(kDigitBitSize % 4 == 0);
- intptr_t hex_length = strlen(hex_string);
+ const intptr_t hex_length = strlen(hex_string);
+ if (hex_length < 0) {
+ FATAL("Fatal error in BigintOperations::ComputeChunkLength: "
+ "string too long");
+ }
// Round up.
intptr_t bigint_length = ((hex_length - 1) / kHexCharsPerDigit) + 1;
return bigint_length;
@@ -158,7 +165,11 @@ RawBigint* BigintOperations::FromDecimalCString(const char* str,
const Chunk kTenMultiplier = 100000000;
ASSERT(kDigitBitSize >= 27);
- intptr_t str_length = strlen(str);
+ const intptr_t str_length = strlen(str);
+ if (str_length < 0) {
+ FATAL("Fatal error in BigintOperations::FromDecimalCString: "
+ "string too long");
+ }
intptr_t str_pos = 0;
// Read first digit separately. This avoids a multiplication and addition.
@@ -247,11 +258,21 @@ const char* BigintOperations::ToHexCString(intptr_t length,
ASSERT(kDigitBitSize % 4 == 0);
- intptr_t chunk_length = length;
+ // Conservative maximum chunk length.
+ const intptr_t kMaxChunkLen =
+ (kIntptrMax - 2 /* 0x */
+ - 1 /* trailing '\0' */
+ - 1 /* leading '-' */) / kHexCharsPerDigit;
+ const intptr_t chunk_length = length;
+ // Conservative check assuming leading bigint-digit also takes up
+ // kHexCharsPerDigit.
+ if (chunk_length > kMaxChunkLen) {
+ FATAL("Fatal error in BigintOperations::ToHexCString: string too long");
+ }
Chunk* chunk_data = reinterpret_cast<Chunk*>(data);
if (length == 0) {
const char* zero = "0x0";
- const int kLength = strlen(zero);
+ const intptr_t kLength = strlen(zero);
char* result = reinterpret_cast<char*>(allocator(kLength + 1));
ASSERT(result != NULL);
memmove(result, zero, kLength);
@@ -330,7 +351,7 @@ const char* BigintOperations::ToDecimalCString(
const intptr_t kMaxAllowedDigitLength =
(kIntptrMax - 10) / kLog2Dividend / kDigitBitSize * kLog2Divisor;
- intptr_t length = bigint.Length();
+ const intptr_t length = bigint.Length();
Isolate* isolate = Isolate::Current();
if (length >= kMaxAllowedDigitLength) {
// Use the preallocated out of memory exception to avoid calling
@@ -1341,7 +1362,10 @@ void BigintOperations::FromHexCString(const char* hex_string,
// given string has it's lsd at the last position.
// The hex_i index, pointing into the string, starts therefore at the end,
// whereas the bigint-index (i) starts at 0.
- intptr_t hex_length = strlen(hex_string);
+ const intptr_t hex_length = strlen(hex_string);
+ if (hex_length < 0) {
+ FATAL("Fatal error in BigintOperations::FromHexCString: string too long");
+ }
intptr_t hex_i = hex_length - 1;
for (intptr_t i = 0; i < bigint_length; i++) {
Chunk digit = 0;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698