Missing handle check. Triggers bug if the runtime stack overflows and it is detected...
authorlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 13 Feb 2009 09:40:15 +0000 (09:40 +0000)
committerlrn@chromium.org <lrn@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 13 Feb 2009 09:40:15 +0000 (09:40 +0000)
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1263 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/jsregexp.cc
src/jsregexp.h
test/mjsunit/regress/regress-233.js [new file with mode: 0644]

index 717a66b..3ca7139 100644 (file)
@@ -298,7 +298,7 @@ Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
       return AtomExec(regexp, subject, index);
     case JSRegExp::IRREGEXP: {
       Handle<Object> result = IrregexpExec(regexp, subject, index);
-      if (result.is_null()) ASSERT(Top::has_pending_exception());
+      ASSERT(!result.is_null() || Top::has_pending_exception());
       return result;
     }
     case JSRegExp::JSCRE:
@@ -317,7 +317,7 @@ Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp,
       return AtomExecGlobal(regexp, subject);
     case JSRegExp::IRREGEXP: {
       Handle<Object> result = IrregexpExecGlobal(regexp, subject);
-      if (result.is_null()) ASSERT(Top::has_pending_exception());
+      ASSERT(!result.is_null() || Top::has_pending_exception());
       return result;
     }
     case JSRegExp::JSCRE:
@@ -823,6 +823,11 @@ Handle<Object> RegExpImpl::IrregexpExecGlobal(Handle<JSRegExp> regexp,
                                  offsets.vector(),
                                  offsets.length());
 
+      if (matches.is_null()) {
+        ASSERT(Top::has_pending_exception());
+        return matches;
+      }
+
       if (matches->IsJSArray()) {
         SetElement(result, i, matches);
         i++;
@@ -830,10 +835,9 @@ Handle<Object> RegExpImpl::IrregexpExecGlobal(Handle<JSRegExp> regexp,
         if (offsets.vector()[0] == offsets.vector()[1]) {
           previous_index++;
         }
-      } else if (matches->IsNull()) {
-        return result;
       } else {
-        return matches;
+        ASSERT(matches->IsNull());
+        return result;
       }
     }
   }
index 67018af..270cadd 100644 (file)
@@ -55,7 +55,6 @@ class RegExpImpl {
                                 Handle<String> pattern,
                                 Handle<String> flags);
 
-  // Implements RegExp.prototype.exec(string) function.
   // See ECMA-262 section 15.10.6.2.
   // This function calls the garbage collector if necessary.
   static Handle<Object> Exec(Handle<JSRegExp> regexp,
@@ -155,6 +154,9 @@ class RegExpImpl {
                                       int* ovector,
                                       int ovector_length);
 
+  // On a successful match, the result is a JSArray containing
+  // captured positions. On a failure, the result is the null value.
+  // Returns an empty handle in case of an exception.
   static Handle<Object> IrregexpExecOnce(Handle<FixedArray> regexp,
                                          int num_captures,
                                          Handle<String> subject16,
diff --git a/test/mjsunit/regress/regress-233.js b/test/mjsunit/regress/regress-233.js
new file mode 100644 (file)
index 0000000..8723679
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// See issue 233 <URL: http://code.google.com/p/v8/issues/detail?id=233 >
+// A stack overflow detected by a global regexp match wasn't handled correctly.
+
+// This code shouldn't segmentation fault.
+function loop(s) {
+  loop(s.replace(/\s/g, ""));
+}
+try {
+  loop("No");
+} catch(e) {
+  // Stack overflow caught.
+}