16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (C) 2003-2011, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ******************************************************************************* 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * file name: idnaref.cpp 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * encoding: US-ASCII 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * tab size: 8 (not used) 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * indentation:4 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * created on: 2003feb1 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * created by: Ram Viswanadha 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_IDNA && !UCONFIG_NO_TRANSLITERATION 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "idnaref.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "punyref.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ustr_imp.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "sprpimpl.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "nptrans.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "testidna.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "punycode.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* it is official IDNA ACE Prefix is "xn--" */ 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ACE_PREFIX[] ={ 0x0078,0x006E,0x002d,0x002d } ; 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define ACE_PREFIX_LENGTH 4 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MAX_LABEL_LENGTH 63 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define HYPHEN 0x002D 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* The Max length of the labels should not be more than 64 */ 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MAX_LABEL_BUFFER_SIZE 100 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MAX_IDN_BUFFER_SIZE 300 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define CAPITAL_A 0x0041 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define CAPITAL_Z 0x005A 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LOWER_CASE_DELTA 0x0020 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define FULL_STOP 0x002E 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orginline static UBool 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstartsWithPrefix(const UChar* src , int32_t srcLength){ 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool startsWithPrefix = TRUE; 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength < ACE_PREFIX_LENGTH){ 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(int8_t i=0; i< ACE_PREFIX_LENGTH; i++){ 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(u_tolower(src[i]) != ACE_PREFIX[i]){ 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org startsWithPrefix = FALSE; 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return startsWithPrefix; 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orginline static UChar 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtoASCIILower(UChar ch){ 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(CAPITAL_A <= ch && ch <= CAPITAL_Z){ 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ch + LOWER_CASE_DELTA; 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ch; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orginline static int32_t 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcompareCaseInsensitiveASCII(const UChar* s1, int32_t s1Len, 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* s2, int32_t s2Len){ 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(s1Len != s2Len){ 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (s1Len > s2Len) ? s1Len : s2Len; 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar c1,c2; 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t rc; 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(int32_t i =0;/* no condition */;i++) { 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* If we reach the ends of both strings then they match */ 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i == s1Len) { 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c1 = s1[i]; 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org c2 = s2[i]; 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Case-insensitive comparison */ 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(c1!=c2) { 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rc=(int32_t)toASCIILower(c1)-(int32_t)toASCIILower(c2); 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(rc!=0) { 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return rc; 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UErrorCode getError(enum punycode_status status){ 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(status){ 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case punycode_success: 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return U_ZERO_ERROR; 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case punycode_bad_input: /* Input is invalid. */ 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return U_INVALID_CHAR_FOUND; 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case punycode_big_output: /* Output would exceed the space provided. */ 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return U_BUFFER_OVERFLOW_ERROR; 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case punycode_overflow : /* Input requires wider integers to process. */ 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return U_INDEX_OUTOFBOUNDS_ERROR; 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return U_INTERNAL_PROGRAM_ERROR; 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline int32_t convertASCIIToUChars(const char* src,UChar* dest, int32_t length){ 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int i; 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0;i<length;i++){ 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dest[i] = src[i]; 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return i; 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic inline int32_t convertUCharsToASCII(const UChar* src,char* dest, int32_t length){ 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int i; 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0;i<length;i++){ 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dest[i] = (char)src[i]; 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return i; 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// wrapper around the reference Punycode implementation 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t convertToPuny(const UChar* src, int32_t srcLength, 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* dest, int32_t destCapacity, 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status){ 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t b1Stack[MAX_LABEL_BUFFER_SIZE]; 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b1Len = 0, b1Capacity = MAX_LABEL_BUFFER_SIZE; 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t* b1 = b1Stack; 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char b2Stack[MAX_LABEL_BUFFER_SIZE]; 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char* b2 = b2Stack; 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b2Len =MAX_LABEL_BUFFER_SIZE ; 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org punycode_status error; 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned char* caseFlags = NULL; 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_strToUTF32((UChar32*)b1,b1Capacity,&b1Len,src,srcLength,&status); 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == U_BUFFER_OVERFLOW_ERROR){ 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1 = (uint32_t*) uprv_malloc(b1Len * sizeof(uint32_t)); 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1==NULL){ 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; // reset error 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_strToUTF32((UChar32*)b1,b1Len,&b1Len,src,srcLength,&status); 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(status)){ 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //caseFlags = (unsigned char*) uprv_malloc(b1Len *sizeof(unsigned char)); 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org error = punycode_encode(b1Len,b1,caseFlags, (uint32_t*)&b2Len, b2); 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = getError(error); 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == U_BUFFER_OVERFLOW_ERROR){ 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2 = (char*) uprv_malloc( b2Len * sizeof(char)); 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2==NULL){ 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ZERO_ERROR; // reset error 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org punycode_status error = punycode_encode(b1Len,b1,caseFlags, (uint32_t*)&b2Len, b2); 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = getError(error); 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(status)){ 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2Len < destCapacity){ 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org convertASCIIToUChars(b2,dest,b2Len); 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status =U_BUFFER_OVERFLOW_ERROR; 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCLEANUP: 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1Stack != b1){ 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b1); 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2Stack != b2){ 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b2); 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(caseFlags); 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return b2Len; 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t convertFromPuny( const UChar* src, int32_t srcLength, 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* dest, int32_t destCapacity, 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status){ 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char b1Stack[MAX_LABEL_BUFFER_SIZE]; 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org char* b1 = b1Stack; 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t destLen =0; 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org convertUCharsToASCII(src, b1,srcLength); 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t b2Stack[MAX_LABEL_BUFFER_SIZE]; 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t* b2 = b2Stack; 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b2Len =MAX_LABEL_BUFFER_SIZE; 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org unsigned char* caseFlags = NULL; //(unsigned char*) uprv_malloc(srcLength * sizeof(unsigned char*)); 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org punycode_status error = punycode_decode(srcLength,b1,(uint32_t*)&b2Len,b2,caseFlags); 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = getError(error); 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == U_BUFFER_OVERFLOW_ERROR){ 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2 = (uint32_t*) uprv_malloc(b2Len * sizeof(uint32_t)); 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2 == NULL){ 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org error = punycode_decode(srcLength,b1,(uint32_t*)&b2Len,b2,caseFlags); 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = getError(error); 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(status)){ 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org u_strFromUTF32(dest,destCapacity,&destLen,(UChar32*)b2,b2Len,&status); 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCLEANUP: 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1Stack != b1){ 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b1); 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2Stack != b2){ 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b2); 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(caseFlags); 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return destLen; 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC int32_t U_EXPORT2 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgidnaref_toASCII(const UChar* src, int32_t srcLength, 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* dest, int32_t destCapacity, 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t options, 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError* parseError, 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* status){ 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == NULL || U_FAILURE(*status)){ 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((src == NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ILLEGAL_ARGUMENT_ERROR; 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar b1Stack[MAX_LABEL_BUFFER_SIZE], b2Stack[MAX_LABEL_BUFFER_SIZE]; 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //initialize pointers to stack buffers 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *b1 = b1Stack, *b2 = b2Stack; 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b1Len=0, b2Len=0, 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Capacity = MAX_LABEL_BUFFER_SIZE, 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2Capacity = MAX_LABEL_BUFFER_SIZE , 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength=0; 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //get the options 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool allowUnassigned = (UBool)((options & IDNAREF_ALLOW_UNASSIGNED) != 0); 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool useSTD3ASCIIRules = (UBool)((options & IDNAREF_USE_STD3_RULES) != 0); 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool* caseFlags = NULL; 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // assume the source contains all ascii codepoints 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool srcIsASCII = TRUE; 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // assume the source contains all LDH codepoints 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool srcIsLDH = TRUE; 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t j=0; 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength == -1){ 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLength = u_strlen(src); 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // step 1 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for( j=0;j<srcLength;j++){ 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(src[j] > 0x7F){ 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcIsASCII = FALSE; 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1[b1Len++] = src[j]; 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NamePrepTransform* prep = TestIDNA::getInstance(*status); 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // step 2 is performed only if the source contains non ASCII 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!srcIsASCII) { 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = prep->process(src,srcLength,b1, b1Capacity,allowUnassigned,parseError,*status); 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1==NULL){ 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = prep->process(src,srcLength,b1, b1Len,allowUnassigned, parseError, *status); 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // error bail out 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1Len == 0){ 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR; 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcIsASCII = TRUE; 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // step 3 & 4 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for( j=0;j<b1Len;j++){ 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1[j] > 0x7F){// check if output of usprep_prepare is all ASCII 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcIsASCII = FALSE; 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else if(prep->isLDHChar(b1[j])==FALSE){ // if the char is in ASCII range verify that it is an LDH character{ 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcIsLDH = FALSE; 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(useSTD3ASCIIRules == TRUE){ 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // verify 3a and 3b 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( srcIsLDH == FALSE /* source contains some non-LDH characters */ 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || b1[0] == HYPHEN || b1[b1Len-1] == HYPHEN){ 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_IDNA_STD3_ASCII_RULES_ERROR; 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcIsASCII){ 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1Len <= destCapacity){ 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(dest, b1, b1Len * U_SIZEOF_UCHAR); 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = b1Len; 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = b1Len; 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // step 5 : verify the sequence does not begin with ACE prefix 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!startsWithPrefix(b1,b1Len)){ 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //step 6: encode the sequence with punycode 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //caseFlags = (UBool*) uprv_malloc(b1Len * sizeof(UBool)); 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2Len = convertToPuny(b1,b1Len, b2,b2Capacity,*status); 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //b2Len = u_strToPunycode(b2,b2Capacity,b1,b1Len, caseFlags, status); 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR); 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2 == NULL){ 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2Len = convertToPuny(b1, b1Len, b2, b2Len, *status); 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //b2Len = u_strToPunycode(b2,b2Len,b1,b1Len, caseFlags, status); 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //error bail out 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = b2Len+ACE_PREFIX_LENGTH; 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(reqLength > destCapacity){ 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_BUFFER_OVERFLOW_ERROR; 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //Step 7: prepend the ACE prefix 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(dest,ACE_PREFIX,ACE_PREFIX_LENGTH * U_SIZEOF_UCHAR); 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //Step 6: copy the contents in b2 into dest 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(dest+ACE_PREFIX_LENGTH, b2, b2Len * U_SIZEOF_UCHAR); 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_IDNA_ACE_PREFIX_ERROR; 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(reqLength > MAX_LABEL_LENGTH){ 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_IDNA_LABEL_TOO_LONG_ERROR; 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCLEANUP: 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1 != b1Stack){ 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b1); 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2 != b2Stack){ 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b2); 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(caseFlags); 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// delete prep; 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateUChars(dest, destCapacity, reqLength, status); 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC int32_t U_EXPORT2 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgidnaref_toUnicode(const UChar* src, int32_t srcLength, 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* dest, int32_t destCapacity, 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t options, 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError* parseError, 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* status){ 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == NULL || U_FAILURE(*status)){ 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((src == NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ILLEGAL_ARGUMENT_ERROR; 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar b1Stack[MAX_LABEL_BUFFER_SIZE], b2Stack[MAX_LABEL_BUFFER_SIZE], b3Stack[MAX_LABEL_BUFFER_SIZE]; 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //initialize pointers to stack buffers 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *b1 = b1Stack, *b2 = b2Stack, *b1Prime=NULL, *b3=b3Stack; 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b1Len, b2Len, b1PrimeLen, b3Len, 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Capacity = MAX_LABEL_BUFFER_SIZE, 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2Capacity = MAX_LABEL_BUFFER_SIZE, 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b3Capacity = MAX_LABEL_BUFFER_SIZE, 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength=0; 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// UParseError parseError; 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NamePrepTransform* prep = TestIDNA::getInstance(*status); 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = 0; 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool* caseFlags = NULL; 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //get the options 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool allowUnassigned = (UBool)((options & IDNAREF_ALLOW_UNASSIGNED) != 0); 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool useSTD3ASCIIRules = (UBool)((options & IDNAREF_USE_STD3_RULES) != 0); 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool srcIsASCII = TRUE; 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool srcIsLDH = TRUE; 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t failPos =0; 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // step 1: find out if all the codepoints in src are ASCII 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength==-1){ 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLength = 0; 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;src[srcLength]!=0;){ 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(src[srcLength]> 0x7f){ 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcIsASCII = FALSE; 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }if(prep->isLDHChar(src[srcLength])==FALSE){ 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // here we do not assemble surrogates 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // since we know that LDH code points 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // are in the ASCII range only 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcIsLDH = FALSE; 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org failPos = srcLength; 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcLength++; 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(int32_t j=0; j<srcLength; j++){ 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(src[j]> 0x7f){ 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcIsASCII = FALSE; 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else if(prep->isLDHChar(src[j])==FALSE){ 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // here we do not assemble surrogates 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // since we know that LDH code points 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // are in the ASCII range only 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org srcIsLDH = FALSE; 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org failPos = j; 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcIsASCII == FALSE){ 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // step 2: process the string 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = prep->process(src,srcLength,b1,b1Capacity,allowUnassigned, parseError, *status); 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1==NULL){ 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = prep->process(src,srcLength,b1, b1Len,allowUnassigned, parseError, *status); 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //bail out on error 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // copy everything to b1 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength < b1Capacity){ 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(b1,src, srcLength * U_SIZEOF_UCHAR); 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1 = (UChar*) uprv_malloc(srcLength * U_SIZEOF_UCHAR); 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1==NULL){ 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(b1,src, srcLength * U_SIZEOF_UCHAR); 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = srcLength; 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //step 3: verify ACE Prefix 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(startsWithPrefix(src,srcLength)){ 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //step 4: Remove the ACE Prefix 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Prime = b1 + ACE_PREFIX_LENGTH; 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1PrimeLen = b1Len - ACE_PREFIX_LENGTH; 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //step 5: Decode using punycode 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2Len = convertFromPuny(b1Prime,b1PrimeLen, b2, b2Capacity, *status); 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //b2Len = u_strFromPunycode(b2, b2Capacity,b1Prime,b1PrimeLen, caseFlags, status); 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR); 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2==NULL){ 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2Len = convertFromPuny(b1Prime,b1PrimeLen, b2, b2Len, *status); 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //b2Len = u_strFromPunycode(b2, b2Len,b1Prime,b1PrimeLen,caseFlags, status); 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //step 6:Apply toASCII 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b3Len = idnaref_toASCII(b2,b2Len,b3,b3Capacity,options,parseError, status); 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b3 = (UChar*) uprv_malloc(b3Len * U_SIZEOF_UCHAR); 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b3==NULL){ 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b3Len = idnaref_toASCII(b2,b2Len,b3,b3Len, options, parseError, status); 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //bail out on error 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //step 7: verify 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(compareCaseInsensitiveASCII(b1, b1Len, b3, b3Len) !=0){ 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_IDNA_VERIFICATION_ERROR; 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //step 8: return output of step 5 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = b2Len; 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2Len <= destCapacity) { 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(dest, b2, b2Len * U_SIZEOF_UCHAR); 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // verify that STD3 ASCII rules are satisfied 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(useSTD3ASCIIRules == TRUE){ 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( srcIsLDH == FALSE /* source contains some non-LDH characters */ 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org || src[0] == HYPHEN || src[srcLength-1] == HYPHEN){ 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_IDNA_STD3_ASCII_RULES_ERROR; 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* populate the parseError struct */ 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcIsLDH==FALSE){ 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // failPos is always set the index of failure 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_syntaxError(src,failPos, srcLength,parseError); 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else if(src[0] == HYPHEN){ 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // fail position is 0 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_syntaxError(src,0,srcLength,parseError); 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the last index in the source is always length-1 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_syntaxError(src, (srcLength>0) ? srcLength-1 : srcLength, srcLength,parseError); 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //copy the source to destination 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength <= destCapacity){ 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(dest,src,srcLength * U_SIZEOF_UCHAR); 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = srcLength; 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCLEANUP: 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1 != b1Stack){ 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b1); 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2 != b2Stack){ 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b2); 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(caseFlags); 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The RFC states that 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // <quote> 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // ToUnicode never fails. If any step fails, then the original input 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // is returned immediately in that step. 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // </quote> 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // So if any step fails lets copy source to destination 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //copy the source to destination 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(dest && srcLength <= destCapacity){ 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength == -1) { 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(dest,src,u_strlen(src)* U_SIZEOF_UCHAR); 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(dest,src,srcLength * U_SIZEOF_UCHAR); 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = srcLength; 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateUChars(dest, destCapacity, reqLength, status); 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orggetNextSeparator(UChar *src,int32_t srcLength,NamePrepTransform* prep, 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar **limit, 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool *done, 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *status){ 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength == -1){ 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0 ; ;i++){ 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(src[i] == 0){ 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *limit = src + i; // point to null 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *done = TRUE; 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return i; 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(prep->isLabelSeparator(src[i],*status)){ 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *limit = src + (i+1); // go past the delimiter 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return i; 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i; 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0;i<srcLength;i++){ 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(prep->isLabelSeparator(src[i],*status)){ 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *limit = src + (i+1); // go past the delimiter 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return i; 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // we have not found the delimiter 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(i==srcLength){ 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *limit = src+srcLength; 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *done = TRUE; 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return i; 6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC int32_t U_EXPORT2 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgidnaref_IDNToASCII( const UChar* src, int32_t srcLength, 6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* dest, int32_t destCapacity, 6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t options, 6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError* parseError, 6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* status){ 6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == NULL || U_FAILURE(*status)){ 6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((src == NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ 6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ILLEGAL_ARGUMENT_ERROR; 6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t reqLength = 0; 6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// UParseError parseError; 6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NamePrepTransform* prep = TestIDNA::getInstance(*status); 6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //initialize pointers to stack buffers 6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar b1Stack[MAX_LABEL_BUFFER_SIZE]; 6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *b1 = b1Stack; 7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b1Len, labelLen; 7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* delimiter = (UChar*)src; 7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* labelStart = (UChar*)src; 7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t remainingLen = srcLength; 7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b1Capacity = MAX_LABEL_BUFFER_SIZE; 7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //get the options 7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// UBool allowUnassigned = (UBool)((options & IDNAREF_ALLOW_UNASSIGNED) != 0); 7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// UBool useSTD3ASCIIRules = (UBool)((options & IDNAREF_USE_STD3_RULES) != 0); 7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool done = FALSE; 7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength == -1){ 7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;){ 7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*delimiter == 0){ 7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org labelLen = getNextSeparator(labelStart, -1, prep, &delimiter, &done, status); 7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = 0; 7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!(labelLen==0 && done)){// make sure this is not a root label separator. 7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_toASCII(labelStart, labelLen, b1, b1Capacity, 7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org options, parseError, status); 7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1==NULL){ 7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_toASCII(labelStart, labelLen, b1, b1Len, 7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org options, parseError, status); 7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tempLen = (reqLength + b1Len ); 7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // copy to dest 7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( tempLen< destCapacity){ 7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(dest+reqLength, b1, b1Len * U_SIZEOF_UCHAR); 7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = tempLen; 7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // add the label separator 7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(done == FALSE){ 7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(reqLength < destCapacity){ 7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dest[reqLength] = FULL_STOP; 7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength++; 7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org labelStart = delimiter; 7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;){ 7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(delimiter == src+srcLength){ 7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org labelLen = getNextSeparator(labelStart, remainingLen, prep, &delimiter, &done, status); 7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_toASCII(labelStart, labelLen, b1, b1Capacity, 7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org options,parseError, status); 7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1==NULL){ 7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_toASCII(labelStart, labelLen, b1, b1Len, 7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org options, parseError, status); 7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tempLen = (reqLength + b1Len ); 8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // copy to dest 8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( tempLen< destCapacity){ 8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(dest+reqLength, b1, b1Len * U_SIZEOF_UCHAR); 8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = tempLen; 8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // add the label separator 8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(done == FALSE){ 8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(reqLength < destCapacity){ 8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dest[reqLength] = FULL_STOP; 8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength++; 8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org labelStart = delimiter; 8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org remainingLen = srcLength - (delimiter - src); 8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCLEANUP: 8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1 != b1Stack){ 8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b1); 8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// delete prep; 8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateUChars(dest, destCapacity, reqLength, status); 8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC int32_t U_EXPORT2 8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgidnaref_IDNToUnicode( const UChar* src, int32_t srcLength, 8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* dest, int32_t destCapacity, 8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t options, 8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError* parseError, 8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* status){ 8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == NULL || U_FAILURE(*status)){ 8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((src == NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ 8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ILLEGAL_ARGUMENT_ERROR; 8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t reqLength = 0; 8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool done = FALSE; 8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NamePrepTransform* prep = TestIDNA::getInstance(*status); 8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //initialize pointers to stack buffers 8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar b1Stack[MAX_LABEL_BUFFER_SIZE]; 8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *b1 = b1Stack; 8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b1Len, labelLen; 8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* delimiter = (UChar*)src; 8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* labelStart = (UChar*)src; 8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t remainingLen = srcLength; 8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b1Capacity = MAX_LABEL_BUFFER_SIZE; 8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //get the options 8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// UBool allowUnassigned = (UBool)((options & IDNAREF_ALLOW_UNASSIGNED) != 0); 8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// UBool useSTD3ASCIIRules = (UBool)((options & IDNAREF_USE_STD3_RULES) != 0); 8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(srcLength == -1){ 8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;){ 8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*delimiter == 0){ 8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org labelLen = getNextSeparator(labelStart, -1, prep, &delimiter, &done, status); 8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(labelLen==0 && done==FALSE){ 8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR; 8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_toUnicode(labelStart, labelLen, b1, b1Capacity, 8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org options, parseError, status); 8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1==NULL){ 8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_toUnicode( labelStart, labelLen, b1, b1Len, 8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org options, parseError, status); 8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tempLen = (reqLength + b1Len ); 9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // copy to dest 9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( tempLen< destCapacity){ 9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(dest+reqLength, b1, b1Len * U_SIZEOF_UCHAR); 9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = tempLen; 9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // add the label separator 9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(done == FALSE){ 9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(reqLength < destCapacity){ 9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dest[reqLength] = FULL_STOP; 9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength++; 9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org labelStart = delimiter; 9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;){ 9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(delimiter == src+srcLength){ 9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org labelLen = getNextSeparator(labelStart, remainingLen, prep, &delimiter, &done, status); 9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(labelLen==0 && done==FALSE){ 9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR; 9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_toUnicode( labelStart,labelLen, b1, b1Capacity, 9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org options, parseError, status); 9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1==NULL){ 9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_toUnicode( labelStart, labelLen, b1, b1Len, 9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org options, parseError, status); 9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*status)){ 9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t tempLen = (reqLength + b1Len ); 9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // copy to dest 9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( tempLen< destCapacity){ 9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(dest+reqLength, b1, b1Len * U_SIZEOF_UCHAR); 9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength = tempLen; 9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // add the label separator 9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(done == FALSE){ 9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(reqLength < destCapacity){ 9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dest[reqLength] = FULL_STOP; 9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org reqLength++; 9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org labelStart = delimiter; 9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org remainingLen = srcLength - (delimiter - src); 9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCLEANUP: 9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1 != b1Stack){ 9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b1); 9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// delete prep; 9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return u_terminateUChars(dest, destCapacity, reqLength, status); 9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC int32_t U_EXPORT2 9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgidnaref_compare( const UChar *s1, int32_t length1, 9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *s2, int32_t length2, 9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t options, 9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode* status){ 9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(status == NULL || U_FAILURE(*status)){ 9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar b1Stack[MAX_IDN_BUFFER_SIZE], b2Stack[MAX_IDN_BUFFER_SIZE]; 9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar *b1 = b1Stack, *b2 = b2Stack; 10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t b1Len, b2Len, b1Capacity = MAX_IDN_BUFFER_SIZE, b2Capacity = MAX_IDN_BUFFER_SIZE; 10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t result = -1; 10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError parseError; 10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_IDNToASCII(s1, length1, b1, b1Capacity, options, &parseError, status); 10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1==NULL){ 10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b1Len = idnaref_IDNToASCII(s1,length1,b1,b1Len, options, &parseError, status); 10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2Len = idnaref_IDNToASCII(s2,length2,b2,b2Capacity,options, &parseError, status); 10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(*status == U_BUFFER_OVERFLOW_ERROR){ 10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // redo processing of string 10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we do not have enough room so grow the buffer*/ 10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR); 10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2==NULL){ 10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_MEMORY_ALLOCATION_ERROR; 10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto CLEANUP; 10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *status = U_ZERO_ERROR; // reset error 10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b2Len = idnaref_IDNToASCII(s2,length2,b2,b2Len,options, &parseError, status); 10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // when toASCII is applied all label separators are replaced with FULL_STOP 10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result = compareCaseInsensitiveASCII(b1,b1Len,b2,b2Len); 10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCLEANUP: 10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b1 != b1Stack){ 10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b1); 10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(b2 != b2Stack){ 10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(b2); 10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_IDNA */ 1051