michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: michael@0: /** michael@0: File Name: 15.1.2.5-3.js michael@0: ECMA Section: 15.1.2.5 Function properties of the global object michael@0: unescape( string ) michael@0: michael@0: Description: michael@0: This tests the cases where one of the four characters following "%u" is michael@0: not a hexidecimal character, or one of the two characters following "%" michael@0: or "%u" is not a hexidecimal character. michael@0: michael@0: The unescape function computes a new version of a string value in which michael@0: each escape sequences of the sort that might be introduced by the escape michael@0: function is replaced with the character that it represents. michael@0: michael@0: When the unescape function is called with one argument string, the michael@0: following steps are taken: michael@0: michael@0: 1. Call ToString(string). michael@0: 2. Compute the number of characters in Result(1). michael@0: 3. Let R be the empty string. michael@0: 4. Let k be 0. michael@0: 5. If k equals Result(2), return R. michael@0: 6. Let c be the character at position k within Result(1). michael@0: 7. If c is not %, go to step 18. michael@0: 8. If k is greater than Result(2)-6, go to step 14. michael@0: 9. If the character at position k+1 within result(1) is not u, go to step michael@0: 14. michael@0: 10. If the four characters at positions k+2, k+3, k+4, and k+5 within michael@0: Result(1) are not all hexadecimal digits, go to step 14. michael@0: 11. Let c be the character whose Unicode encoding is the integer represented michael@0: by the four hexadecimal digits at positions k+2, k+3, k+4, and k+5 michael@0: within Result(1). michael@0: 12. Increase k by 5. michael@0: 13. Go to step 18. michael@0: 14. If k is greater than Result(2)-3, go to step 18. michael@0: 15. If the two characters at positions k+1 and k+2 within Result(1) are not michael@0: both hexadecimal digits, go to step 18. michael@0: 16. Let c be the character whose Unicode encoding is the integer represented michael@0: by two zeroes plus the two hexadecimal digits at positions k+1 and k+2 michael@0: within Result(1). michael@0: 17. Increase k by 2. michael@0: 18. Let R be a new string value computed by concatenating the previous value michael@0: of R and c. michael@0: 19. Increase k by 1. michael@0: 20. Go to step 5. michael@0: Author: christine@netscape.com michael@0: Date: 28 october 1997 michael@0: */ michael@0: michael@0: michael@0: var SECTION = "15.1.2.5-3"; michael@0: var VERSION = "ECMA_1"; michael@0: startTest(); michael@0: var TITLE = "unescape(string)"; michael@0: michael@0: writeHeaderToLog( SECTION + " "+ TITLE); michael@0: michael@0: for ( var CHARCODE = 0, NONHEXCHARCODE = 0; CHARCODE < 256; CHARCODE++, NONHEXCHARCODE++ ) { michael@0: NONHEXCHARCODE = getNextNonHexCharCode( NONHEXCHARCODE ); michael@0: michael@0: new TestCase( SECTION, michael@0: "unescape( %"+ (ToHexString(CHARCODE)).substring(0,1) + michael@0: String.fromCharCode( NONHEXCHARCODE ) +" )" + michael@0: "[where last character is String.fromCharCode("+NONHEXCHARCODE+")]", michael@0: "%"+(ToHexString(CHARCODE)).substring(0,1)+ michael@0: String.fromCharCode( NONHEXCHARCODE ), michael@0: unescape( "%" + (ToHexString(CHARCODE)).substring(0,1)+ michael@0: String.fromCharCode( NONHEXCHARCODE ) ) ); michael@0: } michael@0: for ( var CHARCODE = 0, NONHEXCHARCODE = 0; CHARCODE < 256; CHARCODE++, NONHEXCHARCODE++ ) { michael@0: NONHEXCHARCODE = getNextNonHexCharCode( NONHEXCHARCODE ); michael@0: michael@0: new TestCase( SECTION, michael@0: "unescape( %u"+ (ToHexString(CHARCODE)).substring(0,1) + michael@0: String.fromCharCode( NONHEXCHARCODE ) +" )" + michael@0: "[where last character is String.fromCharCode("+NONHEXCHARCODE+")]", michael@0: "%u"+(ToHexString(CHARCODE)).substring(0,1)+ michael@0: String.fromCharCode( NONHEXCHARCODE ), michael@0: unescape( "%u" + (ToHexString(CHARCODE)).substring(0,1)+ michael@0: String.fromCharCode( NONHEXCHARCODE ) ) ); michael@0: } michael@0: michael@0: for ( var CHARCODE = 0, NONHEXCHARCODE = 0 ; CHARCODE < 65536; CHARCODE+= 54321, NONHEXCHARCODE++ ) { michael@0: NONHEXCHARCODE = getNextNonHexCharCode( NONHEXCHARCODE ); michael@0: michael@0: new TestCase( SECTION, michael@0: "unescape( %u"+ (ToUnicodeString(CHARCODE)).substring(0,3) + michael@0: String.fromCharCode( NONHEXCHARCODE ) +" )" + michael@0: "[where last character is String.fromCharCode("+NONHEXCHARCODE+")]", michael@0: michael@0: String.fromCharCode(eval("0x"+ (ToUnicodeString(CHARCODE)).substring(0,2))) + michael@0: (ToUnicodeString(CHARCODE)).substring(2,3) + michael@0: String.fromCharCode( NONHEXCHARCODE ), michael@0: michael@0: unescape( "%" + (ToUnicodeString(CHARCODE)).substring(0,3)+ michael@0: String.fromCharCode( NONHEXCHARCODE ) ) ); michael@0: } michael@0: michael@0: test(); michael@0: michael@0: function getNextNonHexCharCode( n ) { michael@0: for ( ; n < Math.pow(2,16); n++ ) { michael@0: if ( ( n == 43 || n == 45 || n == 46 || n == 47 || michael@0: (n >= 71 && n <= 90) || (n >= 103 && n <= 122) || michael@0: n == 64 || n == 95 ) ) { michael@0: break; michael@0: } else { michael@0: n = ( n > 122 ) ? 0 : n; michael@0: } michael@0: } michael@0: return n; michael@0: } michael@0: function ToUnicodeString( n ) { michael@0: var string = ToHexString(n); michael@0: michael@0: for ( var PAD = (4 - string.length ); PAD > 0; PAD-- ) { michael@0: string = "0" + string; michael@0: } michael@0: michael@0: return string; michael@0: } michael@0: function ToHexString( n ) { michael@0: var hex = new Array(); michael@0: michael@0: for ( var mag = 1; Math.pow(16,mag) <= n ; mag++ ) { michael@0: ; michael@0: } michael@0: michael@0: for ( index = 0, mag -= 1; mag > 0; index++, mag-- ) { michael@0: hex[index] = Math.floor( n / Math.pow(16,mag) ); michael@0: n -= Math.pow(16,mag) * Math.floor( n/Math.pow(16,mag) ); michael@0: } michael@0: michael@0: hex[hex.length] = n % 16; michael@0: michael@0: var string =""; michael@0: michael@0: for ( var index = 0 ; index < hex.length ; index++ ) { michael@0: switch ( hex[index] ) { michael@0: case 10: michael@0: string += "A"; michael@0: break; michael@0: case 11: michael@0: string += "B"; michael@0: break; michael@0: case 12: michael@0: string += "C"; michael@0: break; michael@0: case 13: michael@0: string += "D"; michael@0: break; michael@0: case 14: michael@0: string += "E"; michael@0: break; michael@0: case 15: michael@0: string += "F"; michael@0: break; michael@0: default: michael@0: string += hex[index]; michael@0: } michael@0: } michael@0: michael@0: if ( string.length == 1 ) { michael@0: string = "0" + string; michael@0: } michael@0: return string; michael@0: }