Harden builtins BuildResultFromMatchInfo and URIDecodeOctets
authorjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 16 May 2014 13:43:19 +0000 (13:43 +0000)
committerjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 16 May 2014 13:43:19 +0000 (13:43 +0000)
R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/286203010

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21343 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen.cc
src/regexp.js
src/uri.js
tools/generate-runtime-tests.py

index 7c8c0560664056249ddfce0ef1cbd918b8de8fbe..9c782f2967bc143464ea2760a1ae9897cd1da296 100644 (file)
@@ -1535,12 +1535,14 @@ HValue* HGraphBuilder::BuildRegExpConstructResult(HValue* length,
 
   // Compute the size of the RegExpResult followed by FixedArray with length.
   HValue* size = length;
-  size = AddUncasted<HShl>(size, Add<HConstant>(kPointerSizeLog2));
-  size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
-              JSRegExpResult::kSize + FixedArray::kHeaderSize)));
+  // Make sure size does not exceed max regular heap object size.
+  const int kHeaderSize = JSRegExpResult::kSize + FixedArray::kHeaderSize;
+  const int kMaxLength =
+      (Page::kMaxRegularHeapObjectSize - kHeaderSize) >> kPointerSizeLog2;
+  Add<HBoundsCheck>(size, Add<HConstant>(kMaxLength));
 
-  // Make sure size does not exceeds max regular heap object size.
-  Add<HBoundsCheck>(size, Add<HConstant>(Page::kMaxRegularHeapObjectSize));
+  size = AddUncasted<HShl>(size, Add<HConstant>(kPointerSizeLog2));
+  size = AddUncasted<HAdd>(size, Add<HConstant>(kHeaderSize));
 
   // Allocate the JSRegExpResult and the FixedArray in one step.
   HValue* result = Add<HAllocate>(
index d58ca2634bd03f313e1326ca2c5b5542dbb00139..76d6a9649c191bc057fccdc5d702c5fd8a47e2e6 100644 (file)
@@ -108,23 +108,26 @@ function DoRegExpExec(regexp, string, index) {
 }
 
 
-function BuildResultFromMatchInfo(lastMatchInfo, s) {
-  var numResults = NUMBER_OF_CAPTURES(lastMatchInfo) >> 1;
-  var start = lastMatchInfo[CAPTURE0];
-  var end = lastMatchInfo[CAPTURE1];
-  var result = %_RegExpConstructResult(numResults, start, s);
-  result[0] = %_SubString(s, start, end);
+// This is kind of performance sensitive, so we want to avoid unnecessary
+// type checks on inputs. But we also don't want to inline it several times
+// manually, so we use a macro :-)
+macro RETURN_NEW_RESULT_FROM_MATCH_INFO(MATCHINFO, STRING)
+  var numResults = NUMBER_OF_CAPTURES(MATCHINFO) >> 1;
+  var start = MATCHINFO[CAPTURE0];
+  var end = MATCHINFO[CAPTURE1];
+  var result = %_RegExpConstructResult(numResults, start, STRING);
+  result[0] = %_SubString(STRING, start, end);
   var j = REGEXP_FIRST_CAPTURE + 2;
   for (var i = 1; i < numResults; i++) {
-    start = lastMatchInfo[j++];
+    start = MATCHINFO[j++];
     if (start != -1) {
-      end = lastMatchInfo[j];
-      result[i] = %_SubString(s, start, end);
+      end = MATCHINFO[j];
+      result[i] = %_SubString(STRING, start, end);
     }
     j++;
   }
   return result;
-}
+endmacro
 
 
 function RegExpExecNoTests(regexp, string, start) {
@@ -132,7 +135,7 @@ function RegExpExecNoTests(regexp, string, start) {
   var matchInfo = %_RegExpExec(regexp, string, start, lastMatchInfo);
   if (matchInfo !== null) {
     lastMatchInfoOverride = null;
-    return BuildResultFromMatchInfo(matchInfo, string);
+    RETURN_NEW_RESULT_FROM_MATCH_INFO(matchInfo, string);
   }
   regexp.lastIndex = 0;
   return null;
@@ -175,7 +178,7 @@ function RegExpExec(string) {
   if (global) {
     this.lastIndex = lastMatchInfo[CAPTURE1];
   }
-  return BuildResultFromMatchInfo(matchIndices, string);
+  RETURN_NEW_RESULT_FROM_MATCH_INFO(matchIndices, string);
 }
 
 
index 3cc1fe4755816ba93293ed241d5e5d90e217ec90..fb9742fa873d30ebccc7dae2560bdb89cc434ef8 100644 (file)
@@ -84,6 +84,7 @@ function URIHexCharsToCharCode(highChar, lowChar) {
 
 
 function URIDecodeOctets(octets, result, index) {
+  if (!IS_STRING(result)) throw new $URIError("Internal error");
   var value;
   var o0 = octets[0];
   if (o0 < 0x80) {
@@ -148,9 +149,15 @@ function URIDecodeOctets(octets, result, index) {
     throw new $URIError("URI malformed");
   }
   if (value < 0x10000) {
+    if (index < 0 || index >= result.length) {
+      throw new $URIError("Internal error");
+    }
     %_TwoByteSeqStringSetChar(result, index++, value);
     return index;
   } else {
+    if (index < 0 || index >= result.length - 1) {
+      throw new $URIError("Internal error");
+    }
     %_TwoByteSeqStringSetChar(result, index++, (value >> 10) + 0xd7c0);
     %_TwoByteSeqStringSetChar(result, index++, (value & 0x3ff) + 0xdc00);
     return index;
index 429271a1d193ed0453692f88309a93546c51adf4..487b7973e7954ad42a3bf9e49dd18f0a54e83265 100755 (executable)
@@ -51,7 +51,7 @@ EXPECTED_FUNCTION_COUNT = 362
 EXPECTED_FUZZABLE_COUNT = 329
 EXPECTED_CCTEST_COUNT = 6
 EXPECTED_UNKNOWN_COUNT = 5
-EXPECTED_BUILTINS_COUNT = 827
+EXPECTED_BUILTINS_COUNT = 826
 
 
 # Don't call these at all.