1// Copyright 2012 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28// Summary of the spec: lastIndex is reset to 0 if 29// - a regexp fails to match, regardless of global or non-global. 30// - a global regexp is used in a function that returns multiple results, 31// such as String.prototype.replace or String.prototype.match, since it 32// repeats the regexp until it fails to match. 33// Otherwise lastIndex is only set when a global regexp matches, to the index 34// after the match. 35 36// Test Regexp.prototype.exec 37r = /a/; 38r.lastIndex = 1; 39r.exec("zzzz"); 40assertEquals(0, r.lastIndex); 41 42// Test Regexp.prototype.test 43r = /a/; 44r.lastIndex = 1; 45r.test("zzzz"); 46assertEquals(0, r.lastIndex); 47 48// Test String.prototype.match 49r = /a/; 50r.lastIndex = 1; 51"zzzz".match(r); 52assertEquals(0, r.lastIndex); 53 54// Test String.prototype.replace with atomic regexp and empty string. 55r = /a/; 56r.lastIndex = 1; 57"zzzz".replace(r, ""); 58assertEquals(0, r.lastIndex); 59 60// Test String.prototype.replace with non-atomic regexp and empty string. 61r = /\d/; 62r.lastIndex = 1; 63"zzzz".replace(r, ""); 64assertEquals(0, r.lastIndex); 65 66// Test String.prototype.replace with atomic regexp and non-empty string. 67r = /a/; 68r.lastIndex = 1; 69"zzzz".replace(r, "a"); 70assertEquals(0, r.lastIndex); 71 72// Test String.prototype.replace with non-atomic regexp and non-empty string. 73r = /\d/; 74r.lastIndex = 1; 75"zzzz".replace(r, "a"); 76assertEquals(0, r.lastIndex); 77 78// Test String.prototype.replace with replacement function 79r = /a/; 80r.lastIndex = 1; 81"zzzz".replace(r, function() { return ""; }); 82assertEquals(0, r.lastIndex); 83 84// Regexp functions that returns multiple results: 85// A global regexp always resets lastIndex regardless of whether it matches. 86r = /a/g; 87r.lastIndex = -1; 88"0123abcd".replace(r, "x"); 89assertEquals(0, r.lastIndex); 90 91r.lastIndex = -1; 92"01234567".replace(r, "x"); 93assertEquals(0, r.lastIndex); 94 95r.lastIndex = -1; 96"0123abcd".match(r); 97assertEquals(0, r.lastIndex); 98 99r.lastIndex = -1; 100"01234567".match(r); 101assertEquals(0, r.lastIndex); 102 103// A non-global regexp resets lastIndex iff it does not match. 104r = /a/; 105r.lastIndex = -1; 106"0123abcd".replace(r, "x"); 107assertEquals(-1, r.lastIndex); 108 109r.lastIndex = -1; 110"01234567".replace(r, "x"); 111assertEquals(0, r.lastIndex); 112 113r.lastIndex = -1; 114"0123abcd".match(r); 115assertEquals(-1, r.lastIndex); 116 117r.lastIndex = -1; 118"01234567".match(r); 119assertEquals(0, r.lastIndex); 120 121// Also test RegExp.prototype.exec and RegExp.prototype.test 122r = /a/g; 123r.lastIndex = 1; 124r.exec("01234567"); 125assertEquals(0, r.lastIndex); 126 127r.lastIndex = 1; 128r.exec("0123abcd"); 129assertEquals(5, r.lastIndex); 130 131r = /a/; 132r.lastIndex = 1; 133r.exec("01234567"); 134assertEquals(0, r.lastIndex); 135 136r.lastIndex = 1; 137r.exec("0123abcd"); 138assertEquals(1, r.lastIndex); 139 140r = /a/g; 141r.lastIndex = 1; 142r.test("01234567"); 143assertEquals(0, r.lastIndex); 144 145r.lastIndex = 1; 146r.test("0123abcd"); 147assertEquals(5, r.lastIndex); 148 149r = /a/; 150r.lastIndex = 1; 151r.test("01234567"); 152assertEquals(0, r.lastIndex); 153 154r.lastIndex = 1; 155r.test("0123abcd"); 156assertEquals(1, r.lastIndex); 157