js/src/tests/ecma_3/Function/regress-58274.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /*
michael@0 7 *
michael@0 8 * Date: 15 July 2002
michael@0 9 * SUMMARY: Testing functions with double-byte names
michael@0 10 * See http://bugzilla.mozilla.org/show_bug.cgi?id=58274
michael@0 11 *
michael@0 12 * Here is a sample of the problem:
michael@0 13 *
michael@0 14 * js> function f\u02B1 () {}
michael@0 15 *
michael@0 16 * js> f\u02B1.toSource();
michael@0 17 * function f¦() {}
michael@0 18 *
michael@0 19 * js> f\u02B1.toSource().toSource();
michael@0 20 * (new String("function f\xB1() {}"))
michael@0 21 *
michael@0 22 *
michael@0 23 * See how the high-byte information (the 02) has been lost?
michael@0 24 * The same thing was happening with the toString() method:
michael@0 25 *
michael@0 26 * js> f\u02B1.toString();
michael@0 27 *
michael@0 28 * function f¦() {
michael@0 29 * }
michael@0 30 *
michael@0 31 * js> f\u02B1.toString().toSource();
michael@0 32 * (new String("\nfunction f\xB1() {\n}\n"))
michael@0 33 *
michael@0 34 */
michael@0 35 //-----------------------------------------------------------------------------
michael@0 36 var UBound = 0;
michael@0 37 var BUGNUMBER = 58274;
michael@0 38 var summary = 'Testing functions with double-byte names';
michael@0 39 var ERR = 'UNEXPECTED ERROR! \n';
michael@0 40 var ERR_MALFORMED_NAME = ERR + 'Could not find function name in: \n\n';
michael@0 41 var status = '';
michael@0 42 var statusitems = [];
michael@0 43 var actual = '';
michael@0 44 var actualvalues = [];
michael@0 45 var expect= '';
michael@0 46 var expectedvalues = [];
michael@0 47 var sEval;
michael@0 48 var sName;
michael@0 49
michael@0 50
michael@0 51 sEval = "function f\u02B2() {return 42;}";
michael@0 52 eval(sEval);
michael@0 53 sName = getFunctionName(f\u02B2);
michael@0 54
michael@0 55 // Test function call -
michael@0 56 status = inSection(1);
michael@0 57 actual = f\u02B2();
michael@0 58 expect = 42;
michael@0 59 addThis();
michael@0 60
michael@0 61 // Test both characters of function name -
michael@0 62 status = inSection(2);
michael@0 63 actual = sName[0];
michael@0 64 expect = sEval[9];
michael@0 65 addThis();
michael@0 66
michael@0 67 status = inSection(3);
michael@0 68 actual = sName[1];
michael@0 69 expect = sEval[10];
michael@0 70 addThis();
michael@0 71
michael@0 72
michael@0 73
michael@0 74 sEval = "function f\u02B2\u0AAA () {return 84;}";
michael@0 75 eval(sEval);
michael@0 76 sName = getFunctionName(f\u02B2\u0AAA);
michael@0 77
michael@0 78 // Test function call -
michael@0 79 status = inSection(4);
michael@0 80 actual = f\u02B2\u0AAA();
michael@0 81 expect = 84;
michael@0 82 addThis();
michael@0 83
michael@0 84 // Test all three characters of function name -
michael@0 85 status = inSection(5);
michael@0 86 actual = sName[0];
michael@0 87 expect = sEval[9];
michael@0 88 addThis();
michael@0 89
michael@0 90 status = inSection(6);
michael@0 91 actual = sName[1];
michael@0 92 expect = sEval[10];
michael@0 93 addThis();
michael@0 94
michael@0 95 status = inSection(7);
michael@0 96 actual = sName[2];
michael@0 97 expect = sEval[11];
michael@0 98 addThis();
michael@0 99
michael@0 100
michael@0 101
michael@0 102
michael@0 103 //-----------------------------------------------------------------------------
michael@0 104 test();
michael@0 105 //-----------------------------------------------------------------------------
michael@0 106
michael@0 107
michael@0 108
michael@0 109 /*
michael@0 110 * Goal: test that f.toString() contains the proper function name.
michael@0 111 *
michael@0 112 * Note, however, f.toString() is implementation-independent. For example,
michael@0 113 * it may begin with '\nfunction' instead of 'function'. Therefore we use
michael@0 114 * a regexp to make sure we extract the name properly.
michael@0 115 *
michael@0 116 * Here we assume that f has been defined by means of a function statement,
michael@0 117 * and not a function expression (where it wouldn't have to have a name).
michael@0 118 *
michael@0 119 * Rhino uses a Unicode representation for f.toString(); whereas
michael@0 120 * SpiderMonkey uses an ASCII representation, putting escape sequences
michael@0 121 * for non-ASCII characters. For example, if a function is called f\u02B1,
michael@0 122 * then in Rhino the toString() method will present a 2-character Unicode
michael@0 123 * string for its name, whereas SpiderMonkey will present a 7-character
michael@0 124 * ASCII string for its name: the string literal 'f\u02B1'.
michael@0 125 *
michael@0 126 * So we force the lexer to condense the string before using it.
michael@0 127 * This will give uniform results in Rhino and SpiderMonkey.
michael@0 128 */
michael@0 129 function getFunctionName(f)
michael@0 130 {
michael@0 131 var s = condenseStr(f.toString());
michael@0 132 var re = /\s*function\s+(\S+)\s*\(/;
michael@0 133 var arr = s.match(re);
michael@0 134
michael@0 135 if (!(arr && arr[1]))
michael@0 136 return ERR_MALFORMED_NAME + s;
michael@0 137 return arr[1];
michael@0 138 }
michael@0 139
michael@0 140
michael@0 141 /*
michael@0 142 * This function is the opposite of functions like escape(), which take
michael@0 143 * Unicode characters and return escape sequences for them. Here, we force
michael@0 144 * the lexer to turn escape sequences back into single characters.
michael@0 145 *
michael@0 146 * Note we can't simply do |eval(str)|, since in practice |str| will be an
michael@0 147 * identifier somewhere in the program (e.g. a function name); thus |eval(str)|
michael@0 148 * would return the object that the identifier represents: not what we want.
michael@0 149 *
michael@0 150 * So we surround |str| lexicographically with quotes to force the lexer to
michael@0 151 * evaluate it as a string. Have to strip out any linefeeds first, however -
michael@0 152 */
michael@0 153 function condenseStr(str)
michael@0 154 {
michael@0 155 /*
michael@0 156 * You won't be able to do the next step if |str| has
michael@0 157 * any carriage returns or linefeeds in it. For example:
michael@0 158 *
michael@0 159 * js> eval("'" + '\nHello' + "'");
michael@0 160 * 1: SyntaxError: unterminated string literal:
michael@0 161 * 1: '
michael@0 162 * 1: ^
michael@0 163 *
michael@0 164 * So replace them with the empty string -
michael@0 165 */
michael@0 166 str = str.replace(/[\r\n]/g, '')
michael@0 167 return eval("'" + str + "'");
michael@0 168 }
michael@0 169
michael@0 170
michael@0 171 function addThis()
michael@0 172 {
michael@0 173 statusitems[UBound] = status;
michael@0 174 actualvalues[UBound] = actual;
michael@0 175 expectedvalues[UBound] = expect;
michael@0 176 UBound++;
michael@0 177 }
michael@0 178
michael@0 179
michael@0 180 function test()
michael@0 181 {
michael@0 182 enterFunc('test');
michael@0 183 printBugNumber(BUGNUMBER);
michael@0 184 printStatus(summary);
michael@0 185
michael@0 186 for (var i=0; i<UBound; i++)
michael@0 187 {
michael@0 188 reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
michael@0 189 }
michael@0 190
michael@0 191 exitFunc ('test');
michael@0 192 }

mercurial