regress-130451.js (4047B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* 7 * 8 * Date: 25 Mar 2002 9 * SUMMARY: Array.prototype.sort() should not (re-)define .length 10 * See http://bugzilla.mozilla.org/show_bug.cgi?id=130451 11 * 12 * From the ECMA-262 Edition 3 Final spec: 13 * 14 * NOTE: The sort function is intentionally generic; it does not require that 15 * its |this| value be an Array object. Therefore, it can be transferred to 16 * other kinds of objects for use as a method. Whether the sort function can 17 * be applied successfully to a host object is implementation-dependent. 18 * 19 * The interesting parts of this testcase are the contrasting expectations for 20 * Brendan's test below, when applied to Array objects vs. non-Array objects. 21 * 22 */ 23 //----------------------------------------------------------------------------- 24 var UBound = 0; 25 var BUGNUMBER = 130451; 26 var summary = 'Array.prototype.sort() should not (re-)define .length'; 27 var status = ''; 28 var statusitems = []; 29 var actual = ''; 30 var actualvalues = []; 31 var expect= ''; 32 var expectedvalues = []; 33 var arr = []; 34 var cmp = new Function(); 35 36 37 /* 38 * First: test Array.prototype.sort() on Array objects 39 */ 40 status = inSection(1); 41 arr = [0,1,2,3]; 42 cmp = function(x,y) {return x-y;}; 43 actual = arr.sort(cmp).length; 44 expect = 4; 45 addThis(); 46 47 status = inSection(2); 48 arr = [0,1,2,3]; 49 cmp = function(x,y) {return y-x;}; 50 actual = arr.sort(cmp).length; 51 expect = 4; 52 addThis(); 53 54 status = inSection(3); 55 arr = [0,1,2,3]; 56 cmp = function(x,y) {return x-y;}; 57 arr.length = 1; 58 actual = arr.sort(cmp).length; 59 expect = 1; 60 addThis(); 61 62 /* 63 * This test is by Brendan. Setting arr.length to 64 * 2 and then 4 should cause elements to be deleted. 65 */ 66 arr = [0,1,2,3]; 67 cmp = function(x,y) {return x-y;}; 68 arr.sort(cmp); 69 70 status = inSection(4); 71 actual = arr.join(); 72 expect = '0,1,2,3'; 73 addThis(); 74 75 status = inSection(5); 76 actual = arr.length; 77 expect = 4; 78 addThis(); 79 80 status = inSection(6); 81 arr.length = 2; 82 actual = arr.join(); 83 expect = '0,1'; 84 addThis(); 85 86 status = inSection(7); 87 arr.length = 4; 88 actual = arr.join(); 89 expect = '0,1,,'; //<---- see how 2,3 have been lost 90 addThis(); 91 92 93 94 /* 95 * Now test Array.prototype.sort() on non-Array objects 96 */ 97 status = inSection(8); 98 var obj = new Object(); 99 obj.sort = Array.prototype.sort; 100 obj.length = 4; 101 obj[0] = 0; 102 obj[1] = 1; 103 obj[2] = 2; 104 obj[3] = 3; 105 cmp = function(x,y) {return x-y;}; 106 actual = obj.sort(cmp).length; 107 expect = 4; 108 addThis(); 109 110 111 /* 112 * Here again is Brendan's test. Unlike the array case 113 * above, the setting of obj.length to 2 and then 4 114 * should NOT cause elements to be deleted 115 */ 116 obj = new Object(); 117 obj.sort = Array.prototype.sort; 118 obj.length = 4; 119 obj[0] = 3; 120 obj[1] = 2; 121 obj[2] = 1; 122 obj[3] = 0; 123 cmp = function(x,y) {return x-y;}; 124 obj.sort(cmp); //<---- this is what triggered the buggy behavior below 125 obj.join = Array.prototype.join; 126 127 status = inSection(9); 128 actual = obj.join(); 129 expect = '0,1,2,3'; 130 addThis(); 131 132 status = inSection(10); 133 actual = obj.length; 134 expect = 4; 135 addThis(); 136 137 status = inSection(11); 138 obj.length = 2; 139 actual = obj.join(); 140 expect = '0,1'; 141 addThis(); 142 143 /* 144 * Before this bug was fixed, |actual| held the value '0,1,,' 145 * as in the Array-object case at top. This bug only occurred 146 * if Array.prototype.sort() had been applied to |obj|, 147 * as we have done higher up. 148 */ 149 status = inSection(12); 150 obj.length = 4; 151 actual = obj.join(); 152 expect = '0,1,2,3'; 153 addThis(); 154 155 156 157 158 //----------------------------------------------------------------------------- 159 test(); 160 //----------------------------------------------------------------------------- 161 162 163 164 function addThis() 165 { 166 statusitems[UBound] = status; 167 actualvalues[UBound] = actual; 168 expectedvalues[UBound] = expect; 169 UBound++; 170 } 171 172 173 function test() 174 { 175 printBugNumber(BUGNUMBER); 176 printStatus(summary); 177 178 for (var i=0; i<UBound; i++) 179 { 180 reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]); 181 } 182 }