1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/tests/ecma_3/RegExp/15.10.6.2-2.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,333 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * 1.11 + * Date: 18 Feb 2002 1.12 + * SUMMARY: Testing re.exec(str) when re.lastIndex is < 0 or > str.length 1.13 + * 1.14 + * Case 1: If re has the global flag set, then re(str) should be null 1.15 + * Case 2: If re doesn't have this set, then re(str) should be unaffected 1.16 + * 1.17 + * See http://bugzilla.mozilla.org/show_bug.cgi?id=76717 1.18 + * 1.19 + * 1.20 + * From the ECMA-262 Final spec: 1.21 + * 1.22 + * 15.10.6.2 RegExp.prototype.exec(string) 1.23 + * Performs a regular expression match of string against the regular 1.24 + * expression and returns an Array object containing the results of 1.25 + * the match, or null if the string did not match. 1.26 + * 1.27 + * The string ToString(string) is searched for an occurrence of the 1.28 + * regular expression pattern as follows: 1.29 + * 1.30 + * 1. Let S be the value of ToString(string). 1.31 + * 2. Let length be the length of S. 1.32 + * 3. Let lastIndex be the value of the lastIndex property. 1.33 + * 4. Let i be the value of ToInteger(lastIndex). 1.34 + * 5. If the global property is false, let i = 0. 1.35 + * 6. If i < 0 or i > length then set lastIndex to 0 and return null. 1.36 + * 7. Call [[Match]], giving it the arguments S and i. 1.37 + * If [[Match]] returned failure, go to step 8; 1.38 + * otherwise let r be its State result and go to step 10. 1.39 + * 8. Let i = i+1. 1.40 + * 9. Go to step 6. 1.41 + * 10. Let e be r's endIndex value. 1.42 + * 11. If the global property is true, set lastIndex to e. 1.43 + * 1.44 + * etc. 1.45 + * 1.46 + * 1.47 + * So: 1.48 + * 1.49 + * A. If the global flag is not set, |lastIndex| is set to 0 1.50 + * before the match is attempted; thus the match is unaffected. 1.51 + * 1.52 + * B. If the global flag IS set and re.lastIndex is >= 0 and <= str.length, 1.53 + * |lastIndex| is incremented every time there is a match; not from 1.54 + * i to i+1, but from i to "endIndex" e: 1.55 + * 1.56 + * e = (index of last input character matched so far by the pattern) + 1 1.57 + * 1.58 + * The match is then attempted from this position in the string (Step 7). 1.59 + * 1.60 + * C. When the global flag IS set and re.lastIndex is < 0 or > str.length, 1.61 + * |lastIndex| is set to 0 and the match returns null. 1.62 + * 1.63 + * 1.64 + * Note the |lastIndex| property is writeable, and may be set arbitrarily 1.65 + * by the programmer - and we will do that below. 1.66 + * 1.67 + */ 1.68 +//----------------------------------------------------------------------------- 1.69 +var i = 0; 1.70 +var BUGNUMBER = 76717; 1.71 +var summary = 'Testing re.exec(str) when re.lastIndex is < 0 or > str.length'; 1.72 +var status = ''; 1.73 +var statusmessages = new Array(); 1.74 +var pattern = ''; 1.75 +var patterns = new Array(); 1.76 +var string = ''; 1.77 +var strings = new Array(); 1.78 +var actualmatch = ''; 1.79 +var actualmatches = new Array(); 1.80 +var expectedmatch = ''; 1.81 +var expectedmatches = new Array(); 1.82 + 1.83 + 1.84 +/****************************************************************************** 1.85 + * 1.86 + * Case 1 : when the global flag is set - 1.87 + * 1.88 + *****************************************************************************/ 1.89 +pattern = /abc/gi; 1.90 +string = 'AbcaBcabC'; 1.91 + 1.92 +status = inSection(1); 1.93 +actualmatch = pattern.exec(string); 1.94 +expectedmatch = Array('Abc'); 1.95 +addThis(); 1.96 + 1.97 +status = inSection(2); 1.98 +actualmatch = pattern.exec(string); 1.99 +expectedmatch = Array('aBc'); 1.100 +addThis(); 1.101 + 1.102 +status = inSection(3); 1.103 +actualmatch = pattern.exec(string); 1.104 +expectedmatch = Array('abC'); 1.105 +addThis(); 1.106 + 1.107 +/* 1.108 + * At this point |lastIndex| is > string.length, so the match should be null - 1.109 + */ 1.110 +status = inSection(4); 1.111 +actualmatch = pattern.exec(string); 1.112 +expectedmatch = null; 1.113 +addThis(); 1.114 + 1.115 +/* 1.116 + * Now let's set |lastIndex| to -1, so the match should again be null - 1.117 + */ 1.118 +status = inSection(5); 1.119 +pattern.lastIndex = -1; 1.120 +actualmatch = pattern.exec(string); 1.121 +expectedmatch = null; 1.122 +addThis(); 1.123 + 1.124 +/* 1.125 + * Now try some edge-case values. Thanks to the work done in 1.126 + * http://bugzilla.mozilla.org/show_bug.cgi?id=124339, |lastIndex| 1.127 + * is now stored as a double instead of a uint32_t (unsigned integer). 1.128 + * 1.129 + * Note 2^32 -1 is the upper bound for uint32's, but doubles can go 1.130 + * all the way up to Number.MAX_VALUE. So that's why we need cases 1.131 + * between those two numbers. 1.132 + */ 1.133 +status = inSection(6); 1.134 +pattern.lastIndex = Math.pow(2,32); 1.135 +actualmatch = pattern.exec(string); 1.136 +expectedmatch = null; 1.137 +addThis(); 1.138 + 1.139 +status = inSection(7); 1.140 +pattern.lastIndex = -Math.pow(2,32); 1.141 +actualmatch = pattern.exec(string); 1.142 +expectedmatch = null; 1.143 +addThis(); 1.144 + 1.145 +status = inSection(8); 1.146 +pattern.lastIndex = Math.pow(2,32) + 1; 1.147 +actualmatch = pattern.exec(string); 1.148 +expectedmatch = null; 1.149 +addThis(); 1.150 + 1.151 +status = inSection(9); 1.152 +pattern.lastIndex = -(Math.pow(2,32) + 1); 1.153 +actualmatch = pattern.exec(string); 1.154 +expectedmatch = null; 1.155 +addThis(); 1.156 + 1.157 +status = inSection(10); 1.158 +pattern.lastIndex = Math.pow(2,32) * 2; 1.159 +actualmatch = pattern.exec(string); 1.160 +expectedmatch = null; 1.161 +addThis(); 1.162 + 1.163 +status = inSection(11); 1.164 +pattern.lastIndex = -Math.pow(2,32) * 2; 1.165 +actualmatch = pattern.exec(string); 1.166 +expectedmatch = null; 1.167 +addThis(); 1.168 + 1.169 +status = inSection(12); 1.170 +pattern.lastIndex = Math.pow(2,40); 1.171 +actualmatch = pattern.exec(string); 1.172 +expectedmatch = null; 1.173 +addThis(); 1.174 + 1.175 +status = inSection(13); 1.176 +pattern.lastIndex = -Math.pow(2,40); 1.177 +actualmatch = pattern.exec(string); 1.178 +expectedmatch = null; 1.179 +addThis(); 1.180 + 1.181 +status = inSection(14); 1.182 +pattern.lastIndex = Number.MAX_VALUE; 1.183 +actualmatch = pattern.exec(string); 1.184 +expectedmatch = null; 1.185 +addThis(); 1.186 + 1.187 +status = inSection(15); 1.188 +pattern.lastIndex = -Number.MAX_VALUE; 1.189 +actualmatch = pattern.exec(string); 1.190 +expectedmatch = null; 1.191 +addThis(); 1.192 + 1.193 + 1.194 + 1.195 +/****************************************************************************** 1.196 + * 1.197 + * Case 2: repeat all the above cases WITHOUT the global flag set. 1.198 + * According to EMCA. |lastIndex| should get set to 0 before the match. 1.199 + * 1.200 + * Therefore re.exec(str) should be unaffected; thus our expected values 1.201 + * below are now DIFFERENT when |lastIndex| is < 0 or > str.length 1.202 + * 1.203 + *****************************************************************************/ 1.204 + 1.205 +pattern = /abc/i; 1.206 +string = 'AbcaBcabC'; 1.207 + 1.208 +status = inSection(16); 1.209 +actualmatch = pattern.exec(string); 1.210 +expectedmatch = Array('Abc'); 1.211 +addThis(); 1.212 + 1.213 +status = inSection(17); 1.214 +actualmatch = pattern.exec(string); 1.215 +expectedmatch = Array('Abc'); // NOT Array('aBc') as before - 1.216 +addThis(); 1.217 + 1.218 +status = inSection(18); 1.219 +actualmatch = pattern.exec(string); 1.220 +expectedmatch = Array('Abc'); // NOT Array('abC') as before - 1.221 +addThis(); 1.222 + 1.223 +/* 1.224 + * At this point above, |lastIndex| WAS > string.length, but not here - 1.225 + */ 1.226 +status = inSection(19); 1.227 +actualmatch = pattern.exec(string); 1.228 +expectedmatch = Array('Abc') // NOT null as before - 1.229 + addThis(); 1.230 + 1.231 +/* 1.232 + * Now let's set |lastIndex| to -1 1.233 + */ 1.234 +status = inSection(20); 1.235 +pattern.lastIndex = -1; 1.236 +actualmatch = pattern.exec(string); 1.237 +expectedmatch = Array('Abc') // NOT null as before - 1.238 + addThis(); 1.239 + 1.240 +/* 1.241 + * Now try some edge-case values. Thanks to the work done in 1.242 + * http://bugzilla.mozilla.org/show_bug.cgi?id=124339, |lastIndex| 1.243 + * is now stored as a double instead of a uint32_t (unsigned integer). 1.244 + * 1.245 + * Note 2^32 -1 is the upper bound for uint32's, but doubles can go 1.246 + * all the way up to Number.MAX_VALUE. So that's why we need cases 1.247 + * between those two numbers. 1.248 + */ 1.249 +status = inSection(21); 1.250 +pattern.lastIndex = Math.pow(2,32); 1.251 +actualmatch = pattern.exec(string); 1.252 +expectedmatch = Array('Abc') // NOT null as before - 1.253 + addThis(); 1.254 + 1.255 +status = inSection(22); 1.256 +pattern.lastIndex = -Math.pow(2,32); 1.257 +actualmatch = pattern.exec(string); 1.258 +expectedmatch = Array('Abc') // NOT null as before - 1.259 + addThis(); 1.260 + 1.261 +status = inSection(23); 1.262 +pattern.lastIndex = Math.pow(2,32) + 1; 1.263 +actualmatch = pattern.exec(string); 1.264 +expectedmatch = Array('Abc') // NOT null as before - 1.265 + addThis(); 1.266 + 1.267 +status = inSection(24); 1.268 +pattern.lastIndex = -(Math.pow(2,32) + 1); 1.269 +actualmatch = pattern.exec(string); 1.270 +expectedmatch = Array('Abc') // NOT null as before - 1.271 + addThis(); 1.272 + 1.273 +status = inSection(25); 1.274 +pattern.lastIndex = Math.pow(2,32) * 2; 1.275 +actualmatch = pattern.exec(string); 1.276 +expectedmatch = Array('Abc') // NOT null as before - 1.277 + addThis(); 1.278 + 1.279 +status = inSection(26); 1.280 +pattern.lastIndex = -Math.pow(2,32) * 2; 1.281 +actualmatch = pattern.exec(string); 1.282 +expectedmatch = Array('Abc') // NOT null as before - 1.283 + addThis(); 1.284 + 1.285 +status = inSection(27); 1.286 +pattern.lastIndex = Math.pow(2,40); 1.287 +actualmatch = pattern.exec(string); 1.288 +expectedmatch = Array('Abc') // NOT null as before -; 1.289 + addThis(); 1.290 + 1.291 +status = inSection(28); 1.292 +pattern.lastIndex = -Math.pow(2,40); 1.293 +actualmatch = pattern.exec(string); 1.294 +expectedmatch = Array('Abc') // NOT null as before - 1.295 + addThis(); 1.296 + 1.297 +status = inSection(29); 1.298 +pattern.lastIndex = Number.MAX_VALUE; 1.299 +actualmatch = pattern.exec(string); 1.300 +expectedmatch = Array('Abc') // NOT null as before - 1.301 + addThis(); 1.302 + 1.303 +status = inSection(30); 1.304 +pattern.lastIndex = -Number.MAX_VALUE; 1.305 +actualmatch = pattern.exec(string); 1.306 +expectedmatch = Array('Abc') // NOT null as before - 1.307 + addThis(); 1.308 + 1.309 + 1.310 + 1.311 + 1.312 +//------------------------------------------------------------------------------------------------- 1.313 +test(); 1.314 +//------------------------------------------------------------------------------------------------- 1.315 + 1.316 + 1.317 + 1.318 +function addThis() 1.319 +{ 1.320 + statusmessages[i] = status; 1.321 + patterns[i] = pattern; 1.322 + strings[i] = string; 1.323 + actualmatches[i] = actualmatch; 1.324 + expectedmatches[i] = expectedmatch; 1.325 + i++; 1.326 +} 1.327 + 1.328 + 1.329 +function test() 1.330 +{ 1.331 + enterFunc ('test'); 1.332 + printBugNumber(BUGNUMBER); 1.333 + printStatus (summary); 1.334 + testRegExp(statusmessages, patterns, strings, actualmatches, expectedmatches); 1.335 + exitFunc ('test'); 1.336 +}