1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ******************************************************************************* 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Copyright (C) 2003-2009, International Business Machines 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Corporation and others. All Rights Reserved. 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ******************************************************************************* 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * file name: uidna.cpp 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * encoding: US-ASCII 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * tab size: 8 (not used) 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * indentation:4 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * created on: 2003feb1 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * created by: Ram Viswanadha 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_IDNA 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uidna.h" 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h" 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/usprep.h" 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "punycode.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ustr_imp.h" 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uassert.h" 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "sprpimpl.h" 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* it is official IDNA ACE Prefix is "xn--" */ 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar ACE_PREFIX[] ={ 0x0078,0x006E,0x002d,0x002d } ; 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ACE_PREFIX_LENGTH 4 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_LABEL_LENGTH 63 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* The Max length of the labels should not be more than MAX_LABEL_LENGTH */ 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_LABEL_BUFFER_SIZE 100 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_DOMAIN_NAME_LENGTH 255 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* The Max length of the domain names should not be more than MAX_DOMAIN_NAME_LENGTH */ 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_IDN_BUFFER_SIZE MAX_DOMAIN_NAME_LENGTH+1 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define LOWER_CASE_DELTA 0x0020 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define HYPHEN 0x002D 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define FULL_STOP 0x002E 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define CAPITAL_A 0x0041 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define CAPITAL_Z 0x005A 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)inline static UChar 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)toASCIILower(UChar ch){ 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(CAPITAL_A <= ch && ch <= CAPITAL_Z){ 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ch + LOWER_CASE_DELTA; 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ch; 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)inline static UBool 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)startsWithPrefix(const UChar* src , int32_t srcLength){ 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool startsWithPrefix = TRUE; 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength < ACE_PREFIX_LENGTH){ 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(int8_t i=0; i< ACE_PREFIX_LENGTH; i++){ 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(toASCIILower(src[i]) != ACE_PREFIX[i]){ 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) startsWithPrefix = FALSE; 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return startsWithPrefix; 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)inline static int32_t 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)compareCaseInsensitiveASCII(const UChar* s1, int32_t s1Len, 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar* s2, int32_t s2Len){ 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t minLength; 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t lengthResult; 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // are we comparing different lengths? 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s1Len != s2Len) { 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(s1Len < s2Len) { 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) minLength = s1Len; 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) lengthResult = -1; 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) minLength = s2Len; 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) lengthResult = 1; 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ok the lengths are equal 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) minLength = s1Len; 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) lengthResult = 0; 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar c1,c2; 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t rc; 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(int32_t i =0;/* no condition */;i++) { 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* If we reach the ends of both strings then they match */ 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(i == minLength) { 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return lengthResult; 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c1 = s1[i]; 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c2 = s2[i]; 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Case-insensitive comparison */ 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(c1!=c2) { 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rc=(int32_t)toASCIILower(c1)-(int32_t)toASCIILower(c2); 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(rc!=0) { 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) lengthResult=rc; 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return lengthResult; 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Ascertain if the given code point is a label separator as 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * defined by the IDNA RFC 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @param ch The code point to be ascertained 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @return true if the char is a label separator 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * @stable ICU 2.8 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static inline UBool isLabelSeparator(UChar ch){ 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(ch){ 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0x002e: 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0x3002: 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0xFF0E: 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case 0xFF61: 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// returns the length of the label excluding the separator 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// if *limit == separator then the length returned does not include 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// the separtor. 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static inline int32_t 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)getNextSeparator(UChar *src, int32_t srcLength, 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar **limit, UBool *done){ 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength == -1){ 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0 ; ;i++){ 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(src[i] == 0){ 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *limit = src + i; // point to null 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *done = TRUE; 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return i; 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(isLabelSeparator(src[i])){ 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *limit = src + (i+1); // go past the delimiter 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return i; 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i; 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i=0;i<srcLength;i++){ 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(isLabelSeparator(src[i])){ 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *limit = src + (i+1); // go past the delimiter 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return i; 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we have not found the delimiter 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // if(i==srcLength) 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *limit = src+srcLength; 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *done = TRUE; 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return i; 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static inline UBool isLDHChar(UChar ch){ 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // high runner case 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ch>0x007A){ 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //[\\u002D \\u0030-\\u0039 \\u0041-\\u005A \\u0061-\\u007A] 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( (ch==0x002D) || 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (0x0030 <= ch && ch <= 0x0039) || 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (0x0041 <= ch && ch <= 0x005A) || 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (0x0061 <= ch && ch <= 0x007A) 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ){ 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_internal_toASCII(const UChar* src, int32_t srcLength, 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar* dest, int32_t destCapacity, 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t options, 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UStringPrepProfile* nameprep, 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError* parseError, 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode* status) 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO Revisit buffer handling. The label should not be over 63 ASCII characters. ICU4J may need to be updated too. 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar b1Stack[MAX_LABEL_BUFFER_SIZE], b2Stack[MAX_LABEL_BUFFER_SIZE]; 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //initialize pointers to stack buffers 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *b1 = b1Stack, *b2 = b2Stack; 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t b1Len=0, b2Len, 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Capacity = MAX_LABEL_BUFFER_SIZE, 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2Capacity = MAX_LABEL_BUFFER_SIZE , 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength=0; 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t namePrepOptions = ((options & UIDNA_ALLOW_UNASSIGNED) != 0) ? USPREP_ALLOW_UNASSIGNED: 0; 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool* caseFlags = NULL; 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the source contains all ascii codepoints 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool srcIsASCII = TRUE; 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // assume the source contains all LDH codepoints 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool srcIsLDH = TRUE; 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t j=0; 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //get the options 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool useSTD3ASCIIRules = (UBool)((options & UIDNA_USE_STD3_RULES) != 0); 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t failPos = -1; 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength == -1){ 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength = u_strlen(src); 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength > b1Capacity){ 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1 = (UChar*) uprv_malloc(srcLength * U_SIZEOF_UCHAR); 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1==NULL){ 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Capacity = srcLength; 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step 1 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for( j=0;j<srcLength;j++){ 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(src[j] > 0x7F){ 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIsASCII = FALSE; 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1[b1Len++] = src[j]; 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step 2 is performed only if the source contains non ASCII 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcIsASCII == FALSE){ 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step 2 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Len = usprep_prepare(nameprep, src, srcLength, b1, b1Capacity, namePrepOptions, parseError, status); 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_BUFFER_OVERFLOW_ERROR){ 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // redo processing of string 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we do not have enough room so grow the buffer 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1 != b1Stack){ 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(b1); 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1==NULL){ 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; // reset error 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Len = usprep_prepare(nameprep, src, srcLength, b1, b1Len, namePrepOptions, parseError, status); 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // error bail out 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1Len == 0){ 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR; 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // for step 3 & 4 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIsASCII = TRUE; 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for( j=0;j<b1Len;j++){ 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // check if output of usprep_prepare is all ASCII 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1[j] > 0x7F){ 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIsASCII = FALSE; 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else if(isLDHChar(b1[j])==FALSE){ // if the char is in ASCII range verify that it is an LDH character 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIsLDH = FALSE; 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) failPos = j; 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(useSTD3ASCIIRules == TRUE){ 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // verify 3a and 3b 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 3(a) Verify the absence of non-LDH ASCII code points; that is, the 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F. 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 3(b) Verify the absence of leading and trailing hyphen-minus; that 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // is, the absence of U+002D at the beginning and end of the 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // sequence. 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( srcIsLDH == FALSE /* source at this point should not contain anyLDH characters */ 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) || b1[0] == HYPHEN || b1[b1Len-1] == HYPHEN){ 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_IDNA_STD3_ASCII_RULES_ERROR; 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* populate the parseError struct */ 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcIsLDH==FALSE){ 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // failPos is always set the index of failure 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_syntaxError(b1,failPos, b1Len,parseError); 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else if(b1[0] == HYPHEN){ 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // fail position is 0 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_syntaxError(b1,0,b1Len,parseError); 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the last index in the source is always length-1 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_syntaxError(b1, (b1Len>0) ? b1Len-1 : b1Len, b1Len,parseError); 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Step 4: if the source is ASCII then proceed to step 8 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcIsASCII){ 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1Len <= destCapacity){ 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memmove(dest, b1, b1Len * U_SIZEOF_UCHAR); 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength = b1Len; 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength = b1Len; 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step 5 : verify the sequence does not begin with ACE prefix 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!startsWithPrefix(b1,b1Len)){ 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //step 6: encode the sequence with punycode 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // do not preserve the case flags for now! 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO: Preserve the case while implementing the RFE 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // caseFlags = (UBool*) uprv_malloc(b1Len * sizeof(UBool)); 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // uprv_memset(caseFlags,TRUE,b1Len); 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2Len = u_strToPunycode(b1,b1Len,b2,b2Capacity,caseFlags, status); 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_BUFFER_OVERFLOW_ERROR){ 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // redo processing of string 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we do not have enough room so grow the buffer*/ 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR); 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b2 == NULL){ 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; // reset error 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2Len = u_strToPunycode(b1,b1Len,b2,b2Len,caseFlags, status); 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //error bail out 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO : Reconsider while implementing the case preserve RFE 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // convert all codepoints to lower case ASCII 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // toASCIILower(b2,b2Len); 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength = b2Len+ACE_PREFIX_LENGTH; 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(reqLength > destCapacity){ 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //Step 7: prepend the ACE prefix 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(dest,ACE_PREFIX,ACE_PREFIX_LENGTH * U_SIZEOF_UCHAR); 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //Step 6: copy the contents in b2 into dest 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(dest+ACE_PREFIX_LENGTH, b2, b2Len * U_SIZEOF_UCHAR); 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_IDNA_ACE_PREFIX_ERROR; 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //position of failure is 0 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_syntaxError(b1,0,b1Len,parseError); 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step 8: verify the length of label 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(reqLength > MAX_LABEL_LENGTH){ 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_IDNA_LABEL_TOO_LONG_ERROR; 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CLEANUP: 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1 != b1Stack){ 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(b1); 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b2 != b2Stack){ 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(b2); 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(caseFlags); 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_terminateUChars(dest, destCapacity, reqLength, status); 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)_internal_toUnicode(const UChar* src, int32_t srcLength, 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar* dest, int32_t destCapacity, 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t options, 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UStringPrepProfile* nameprep, 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError* parseError, 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode* status) 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //get the options 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //UBool useSTD3ASCIIRules = (UBool)((options & UIDNA_USE_STD3_RULES) != 0); 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t namePrepOptions = ((options & UIDNA_ALLOW_UNASSIGNED) != 0) ? USPREP_ALLOW_UNASSIGNED: 0; 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO Revisit buffer handling. The label should not be over 63 ASCII characters. ICU4J may need to be updated too. 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar b1Stack[MAX_LABEL_BUFFER_SIZE], b2Stack[MAX_LABEL_BUFFER_SIZE], b3Stack[MAX_LABEL_BUFFER_SIZE]; 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //initialize pointers to stack buffers 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *b1 = b1Stack, *b2 = b2Stack, *b1Prime=NULL, *b3=b3Stack; 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t b1Len, b2Len, b1PrimeLen, b3Len, 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Capacity = MAX_LABEL_BUFFER_SIZE, 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2Capacity = MAX_LABEL_BUFFER_SIZE, 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b3Capacity = MAX_LABEL_BUFFER_SIZE, 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength=0; 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Len = 0; 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool* caseFlags = NULL; 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool srcIsASCII = TRUE; 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*UBool srcIsLDH = TRUE; 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t failPos =0;*/ 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step 1: find out if all the codepoints in src are ASCII 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength==-1){ 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength = 0; 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;src[srcLength]!=0;){ 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(src[srcLength]> 0x7f){ 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIsASCII = FALSE; 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }/*else if(isLDHChar(src[srcLength])==FALSE){ 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // here we do not assemble surrogates 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // since we know that LDH code points 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // are in the ASCII range only 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIsLDH = FALSE; 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) failPos = srcLength; 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }*/ 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength++; 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else if(srcLength > 0){ 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(int32_t j=0; j<srcLength; j++){ 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(src[j]> 0x7f){ 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIsASCII = FALSE; 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }/*else if(isLDHChar(src[j])==FALSE){ 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // here we do not assemble surrogates 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // since we know that LDH code points 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // are in the ASCII range only 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcIsLDH = FALSE; 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) failPos = j; 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }*/ 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcIsASCII == FALSE){ 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // step 2: process the string 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Len = usprep_prepare(nameprep, src, srcLength, b1, b1Capacity, namePrepOptions, parseError, status); 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_BUFFER_OVERFLOW_ERROR){ 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // redo processing of string 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we do not have enough room so grow the buffer*/ 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1==NULL){ 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; // reset error 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Len = usprep_prepare(nameprep, src, srcLength, b1, b1Len, namePrepOptions, parseError, status); 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //bail out on error 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //just point src to b1 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1 = (UChar*) src; 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Len = srcLength; 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The RFC states that 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // <quote> 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ToUnicode never fails. If any step fails, then the original input 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // is returned immediately in that step. 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // </quote> 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //step 3: verify ACE Prefix 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(startsWithPrefix(b1,b1Len)){ 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //step 4: Remove the ACE Prefix 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Prime = b1 + ACE_PREFIX_LENGTH; 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1PrimeLen = b1Len - ACE_PREFIX_LENGTH; 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //step 5: Decode using punycode 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2Len = u_strFromPunycode(b1Prime, b1PrimeLen, b2, b2Capacity, caseFlags,status); 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_BUFFER_OVERFLOW_ERROR){ 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // redo processing of string 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we do not have enough room so grow the buffer*/ 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR); 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b2==NULL){ 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; // reset error 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2Len = u_strFromPunycode(b1Prime, b1PrimeLen, b2, b2Len, caseFlags, status); 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //step 6:Apply toASCII 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b3Len = uidna_toASCII(b2, b2Len, b3, b3Capacity, options, parseError, status); 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_BUFFER_OVERFLOW_ERROR){ 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // redo processing of string 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we do not have enough room so grow the buffer*/ 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b3 = (UChar*) uprv_malloc(b3Len * U_SIZEOF_UCHAR); 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b3==NULL){ 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; // reset error 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b3Len = uidna_toASCII(b2,b2Len,b3,b3Len,options,parseError, status); 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //bail out on error 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //step 7: verify 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(compareCaseInsensitiveASCII(b1, b1Len, b3, b3Len) !=0){ 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Cause the original to be returned. 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_IDNA_VERIFICATION_ERROR; 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //step 8: return output of step 5 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength = b2Len; 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b2Len <= destCapacity) { 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memmove(dest, b2, b2Len * U_SIZEOF_UCHAR); 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else{ 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // See the start of this if statement for why this is commented out. 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // verify that STD3 ASCII rules are satisfied 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*if(useSTD3ASCIIRules == TRUE){ 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( srcIsLDH == FALSE // source contains some non-LDH characters 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) || src[0] == HYPHEN || src[srcLength-1] == HYPHEN){ 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_IDNA_STD3_ASCII_RULES_ERROR; 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // populate the parseError struct 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcIsLDH==FALSE){ 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // failPos is always set the index of failure 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_syntaxError(src,failPos, srcLength,parseError); 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else if(src[0] == HYPHEN){ 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // fail position is 0 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_syntaxError(src,0,srcLength,parseError); 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the last index in the source is always length-1 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_syntaxError(src, (srcLength>0) ? srcLength-1 : srcLength, srcLength,parseError); 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }*/ 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // just return the source 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //copy the source to destination 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength <= destCapacity){ 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memmove(dest,src,srcLength * U_SIZEOF_UCHAR); 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength = srcLength; 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CLEANUP: 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1 != b1Stack && b1!=src){ 583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(b1); 584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b2 != b2Stack){ 586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(b2); 587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(caseFlags); 589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The RFC states that 591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // <quote> 592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ToUnicode never fails. If any step fails, then the original input 593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // is returned immediately in that step. 594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // </quote> 595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // So if any step fails lets copy source to destination 596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //copy the source to destination 598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(dest && srcLength <= destCapacity){ 599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // srcLength should have already been set earlier. 600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_ASSERT(srcLength >= 0); 601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memmove(dest,src,srcLength * U_SIZEOF_UCHAR); 602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength = srcLength; 604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; 605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_terminateUChars(dest, destCapacity, reqLength, status); 608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)uidna_toASCII(const UChar* src, int32_t srcLength, 612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar* dest, int32_t destCapacity, 613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t options, 614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError* parseError, 615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode* status){ 616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(status == NULL || U_FAILURE(*status)){ 618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ 621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UStringPrepProfile* nameprep = usprep_openByType(USPREP_RFC3491_NAMEPREP, status); 626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return -1; 629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t retLen = _internal_toASCII(src, srcLength, dest, destCapacity, options, nameprep, parseError, status); 632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* close the profile*/ 634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) usprep_close(nameprep); 635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return retLen; 637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)uidna_toUnicode(const UChar* src, int32_t srcLength, 641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar* dest, int32_t destCapacity, 642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t options, 643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError* parseError, 644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode* status){ 645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(status == NULL || U_FAILURE(*status)){ 647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( (src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ 650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UStringPrepProfile* nameprep = usprep_openByType(USPREP_RFC3491_NAMEPREP, status); 655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return -1; 658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t retLen = _internal_toUnicode(src, srcLength, dest, destCapacity, options, nameprep, parseError, status); 661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) usprep_close(nameprep); 663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return retLen; 665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)uidna_IDNToASCII( const UChar *src, int32_t srcLength, 670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar* dest, int32_t destCapacity, 671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t options, 672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError *parseError, 673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *status){ 674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(status == NULL || U_FAILURE(*status)){ 676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ 679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t reqLength = 0; 684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UStringPrepProfile* nameprep = usprep_openByType(USPREP_RFC3491_NAMEPREP, status); 686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //initialize pointers 692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *delimiter = (UChar*)src; 693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *labelStart = (UChar*)src; 694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *currentDest = (UChar*) dest; 695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t remainingLen = srcLength; 696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t remainingDestCapacity = destCapacity; 697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t labelLen = 0, labelReqLength = 0; 698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool done = FALSE; 699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;){ 702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) labelLen = getNextSeparator(labelStart,remainingLen, &delimiter,&done); 704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) labelReqLength = 0; 705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!(labelLen==0 && done)){// make sure this is not a root label separator. 706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) labelReqLength = _internal_toASCII( labelStart, labelLen, 708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) currentDest, remainingDestCapacity, 709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) options, nameprep, 710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parseError, status); 711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_BUFFER_OVERFLOW_ERROR){ 713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; // reset error 715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingDestCapacity = 0; 716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength +=labelReqLength; 725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // adjust the destination pointer 726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(labelReqLength < remainingDestCapacity){ 727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) currentDest = currentDest + labelReqLength; 728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingDestCapacity -= labelReqLength; 729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // should never occur 731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingDestCapacity = 0; 732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(done == TRUE){ 735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // add the label separator 739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(remainingDestCapacity > 0){ 740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *currentDest++ = FULL_STOP; 741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingDestCapacity--; 742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength++; 744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) labelStart = delimiter; 746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(remainingLen >0 ){ 747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingLen = (int32_t)(srcLength - (delimiter - src)); 748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(reqLength > MAX_DOMAIN_NAME_LENGTH){ 753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR; 754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) usprep_close(nameprep); 757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_terminateUChars(dest, destCapacity, reqLength, status); 759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)uidna_IDNToUnicode( const UChar* src, int32_t srcLength, 763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar* dest, int32_t destCapacity, 764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t options, 765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError* parseError, 766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode* status){ 767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(status == NULL || U_FAILURE(*status)){ 769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((src==NULL) || (srcLength < -1) || (destCapacity<0) || (!dest && destCapacity > 0)){ 772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t reqLength = 0; 777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UStringPrepProfile* nameprep = usprep_openByType(USPREP_RFC3491_NAMEPREP, status); 779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //initialize pointers 785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *delimiter = (UChar*)src; 786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *labelStart = (UChar*)src; 787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *currentDest = (UChar*) dest; 788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t remainingLen = srcLength; 789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t remainingDestCapacity = destCapacity; 790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t labelLen = 0, labelReqLength = 0; 791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool done = FALSE; 792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(;;){ 794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) labelLen = getNextSeparator(labelStart,remainingLen, &delimiter,&done); 796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The RFC states that 798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // <quote> 799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // ToUnicode never fails. If any step fails, then the original input 800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // is returned immediately in that step. 801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // </quote> 802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // _internal_toUnicode will copy the label. 803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /*if(labelLen==0 && done==FALSE){ 804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR; 805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }*/ 807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) labelReqLength = _internal_toUnicode(labelStart, labelLen, 809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) currentDest, remainingDestCapacity, 810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) options, nameprep, 811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parseError, status); 812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_BUFFER_OVERFLOW_ERROR){ 814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; // reset error 815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingDestCapacity = 0; 816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength +=labelReqLength; 823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // adjust the destination pointer 824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(labelReqLength < remainingDestCapacity){ 825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) currentDest = currentDest + labelReqLength; 826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingDestCapacity -= labelReqLength; 827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // should never occur 829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingDestCapacity = 0; 830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(done == TRUE){ 833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // add the label separator 837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Unlike the ToASCII operation we don't normalize the label separators 838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(remainingDestCapacity > 0){ 839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *currentDest++ = *(labelStart + labelLen); 840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingDestCapacity--; 841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reqLength++; 843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) labelStart = delimiter; 845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(remainingLen >0 ){ 846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) remainingLen = (int32_t)(srcLength - (delimiter - src)); 847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(reqLength > MAX_DOMAIN_NAME_LENGTH){ 852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR; 853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) usprep_close(nameprep); 856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_terminateUChars(dest, destCapacity, reqLength, status); 858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)uidna_compare( const UChar *s1, int32_t length1, 862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *s2, int32_t length2, 863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t options, 864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode* status){ 865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(status == NULL || U_FAILURE(*status)){ 867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return -1; 868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar b1Stack[MAX_IDN_BUFFER_SIZE], b2Stack[MAX_IDN_BUFFER_SIZE]; 871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *b1 = b1Stack, *b2 = b2Stack; 872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t b1Len, b2Len, b1Capacity = MAX_IDN_BUFFER_SIZE, b2Capacity = MAX_IDN_BUFFER_SIZE; 873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t result=-1; 874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError parseError; 876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Len = uidna_IDNToASCII(s1, length1, b1, b1Capacity, options, &parseError, status); 878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_BUFFER_OVERFLOW_ERROR){ 879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // redo processing of string 880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1 = (UChar*) uprv_malloc(b1Len * U_SIZEOF_UCHAR); 881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1==NULL){ 882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; // reset error 887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b1Len = uidna_IDNToASCII(s1,length1,b1,b1Len, options, &parseError, status); 889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2Len = uidna_IDNToASCII(s2,length2, b2,b2Capacity, options, &parseError, status); 893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_BUFFER_OVERFLOW_ERROR){ 894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // redo processing of string 895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2 = (UChar*) uprv_malloc(b2Len * U_SIZEOF_UCHAR); 896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b2==NULL){ 897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto CLEANUP; 899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ZERO_ERROR; // reset error 902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b2Len = uidna_IDNToASCII(s2, length2, b2, b2Len, options, &parseError, status); 904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // when toASCII is applied all label separators are replaced with FULL_STOP 907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = compareCaseInsensitiveASCII(b1,b1Len,b2,b2Len); 908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CLEANUP: 910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b1 != b1Stack){ 911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(b1); 912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(b2 != b2Stack){ 915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(b2); 916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_IDNA */ 922