2 *******************************************************************************
4 * Copyright (C) 2003-2007, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
10 * tab size: 8 (not used)
13 * created on: 2003feb1
14 * created by: Ram Viswanadha
17 #include "unicode/utypes.h"
21 #include "unicode/uidna.h"
22 #include "unicode/ustring.h"
23 #include "unicode/usprep.h"
30 /* it is official IDNA ACE Prefix is "xn--" */
31 static const UChar ACE_PREFIX
[] ={ 0x0078,0x006E,0x002d,0x002d } ;
32 #define ACE_PREFIX_LENGTH 4
34 #define MAX_LABEL_LENGTH 63
35 /* The Max length of the labels should not be more than MAX_LABEL_LENGTH */
36 #define MAX_LABEL_BUFFER_SIZE 100
38 #define MAX_DOMAIN_NAME_LENGTH 255
39 /* The Max length of the domain names should not be more than MAX_DOMAIN_NAME_LENGTH */
40 #define MAX_IDN_BUFFER_SIZE MAX_DOMAIN_NAME_LENGTH+1
42 #define LOWER_CASE_DELTA 0x0020
44 #define FULL_STOP 0x002E
45 #define CAPITAL_A 0x0041
46 #define CAPITAL_Z 0x005A
48 #define DATA_FILE_NAME "uidna"
51 toASCIILower(UChar ch
){
52 if(CAPITAL_A
<= ch
&& ch
<= CAPITAL_Z
){
53 return ch
+ LOWER_CASE_DELTA
;
59 startsWithPrefix(const UChar
* src
, int32_t srcLength
){
60 UBool startsWithPrefix
= TRUE
;
62 if(srcLength
< ACE_PREFIX_LENGTH
){
66 for(int8_t i
=0; i
< ACE_PREFIX_LENGTH
; i
++){
67 if(toASCIILower(src
[i
]) != ACE_PREFIX
[i
]){
68 startsWithPrefix
= FALSE
;
71 return startsWithPrefix
;
76 compareCaseInsensitiveASCII(const UChar
* s1
, int32_t s1Len
,
77 const UChar
* s2
, int32_t s2Len
){
82 // are we comparing different lengths?
92 // ok the lengths are equal
100 for(int32_t i
=0;/* no condition */;i
++) {
102 /* If we reach the ends of both strings then they match */
110 /* Case-insensitive comparison */
112 rc
=(int32_t)toASCIILower(c1
)-(int32_t)toASCIILower(c2
);
124 * Ascertain if the given code point is a label separator as
125 * defined by the IDNA RFC
127 * @param ch The code point to be ascertained
128 * @return true if the char is a label separator
131 static inline UBool
isLabelSeparator(UChar ch
){
143 // returns the length of the label excluding the separator
144 // if *limit == separator then the length returned does not include
146 static inline int32_t
147 getNextSeparator(UChar
*src
, int32_t srcLength
,
148 UChar
**limit
, UBool
*done
){
153 *limit
= src
+ i
; // point to null
157 if(isLabelSeparator(src
[i
])){
158 *limit
= src
+ (i
+1); // go past the delimiter
165 for(i
=0;i
<srcLength
;i
++){
166 if(isLabelSeparator(src
[i
])){
167 *limit
= src
+ (i
+1); // go past the delimiter
171 // we have not found the delimiter
173 *limit
= src
+srcLength
;
179 static inline UBool
isLDHChar(UChar ch
){
184 //[\\u002D \\u0030-\\u0039 \\u0041-\\u005A \\u0061-\\u007A]
186 (0x0030 <= ch
&& ch
<= 0x0039) ||
187 (0x0041 <= ch
&& ch
<= 0x005A) ||
188 (0x0061 <= ch
&& ch
<= 0x007A)
196 _internal_toASCII(const UChar
* src
, int32_t srcLength
,
197 UChar
* dest
, int32_t destCapacity
,
199 UStringPrepProfile
* nameprep
,
200 UParseError
* parseError
,
204 // TODO Revisit buffer handling. The label should not be over 63 ASCII characters. ICU4J may need to be updated too.
205 UChar b1Stack
[MAX_LABEL_BUFFER_SIZE
], b2Stack
[MAX_LABEL_BUFFER_SIZE
];
206 //initialize pointers to stack buffers
207 UChar
*b1
= b1Stack
, *b2
= b2Stack
;
208 int32_t b1Len
=0, b2Len
,
209 b1Capacity
= MAX_LABEL_BUFFER_SIZE
,
210 b2Capacity
= MAX_LABEL_BUFFER_SIZE
,
213 int32_t namePrepOptions
= ((options
& UIDNA_ALLOW_UNASSIGNED
) != 0) ? USPREP_ALLOW_UNASSIGNED
: 0;
214 UBool
* caseFlags
= NULL
;
216 // the source contains all ascii codepoints
217 UBool srcIsASCII
= TRUE
;
218 // assume the source contains all LDH codepoints
219 UBool srcIsLDH
= TRUE
;
224 UBool useSTD3ASCIIRules
= (UBool
)((options
& UIDNA_USE_STD3_RULES
) != 0);
226 int32_t failPos
= -1;
229 srcLength
= u_strlen(src
);
232 if(srcLength
> b1Capacity
){
233 b1
= (UChar
*) uprv_malloc(srcLength
* U_SIZEOF_UCHAR
);
235 *status
= U_MEMORY_ALLOCATION_ERROR
;
238 b1Capacity
= srcLength
;
242 for( j
=0;j
<srcLength
;j
++){
246 b1
[b1Len
++] = src
[j
];
249 // step 2 is performed only if the source contains non ASCII
250 if(srcIsASCII
== FALSE
){
253 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Capacity
, namePrepOptions
, parseError
, status
);
255 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
256 // redo processing of string
257 // we do not have enough room so grow the buffer
261 b1
= (UChar
*) uprv_malloc(b1Len
* U_SIZEOF_UCHAR
);
263 *status
= U_MEMORY_ALLOCATION_ERROR
;
267 *status
= U_ZERO_ERROR
; // reset error
269 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Len
, namePrepOptions
, parseError
, status
);
273 if(U_FAILURE(*status
)){
277 *status
= U_IDNA_ZERO_LENGTH_LABEL_ERROR
;
283 for( j
=0;j
<b1Len
;j
++){
284 // check if output of usprep_prepare is all ASCII
287 }else if(isLDHChar(b1
[j
])==FALSE
){ // if the char is in ASCII range verify that it is an LDH character
292 if(useSTD3ASCIIRules
== TRUE
){
294 // 3(a) Verify the absence of non-LDH ASCII code points; that is, the
295 // absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F.
296 // 3(b) Verify the absence of leading and trailing hyphen-minus; that
297 // is, the absence of U+002D at the beginning and end of the
299 if( srcIsLDH
== FALSE
/* source at this point should not contain anyLDH characters */
300 || b1
[0] == HYPHEN
|| b1
[b1Len
-1] == HYPHEN
){
301 *status
= U_IDNA_STD3_ASCII_RULES_ERROR
;
303 /* populate the parseError struct */
305 // failPos is always set the index of failure
306 uprv_syntaxError(b1
,failPos
, b1Len
,parseError
);
307 }else if(b1
[0] == HYPHEN
){
308 // fail position is 0
309 uprv_syntaxError(b1
,0,b1Len
,parseError
);
311 // the last index in the source is always length-1
312 uprv_syntaxError(b1
, (b1Len
>0) ? b1Len
-1 : b1Len
, b1Len
,parseError
);
318 // Step 4: if the source is ASCII then proceed to step 8
320 if(b1Len
<= destCapacity
){
321 uprv_memmove(dest
, b1
, b1Len
* U_SIZEOF_UCHAR
);
328 // step 5 : verify the sequence does not begin with ACE prefix
329 if(!startsWithPrefix(b1
,b1Len
)){
331 //step 6: encode the sequence with punycode
333 // do not preserve the case flags for now!
334 // TODO: Preserve the case while implementing the RFE
335 // caseFlags = (UBool*) uprv_malloc(b1Len * sizeof(UBool));
336 // uprv_memset(caseFlags,TRUE,b1Len);
338 b2Len
= u_strToPunycode(b1
,b1Len
,b2
,b2Capacity
,caseFlags
, status
);
340 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
341 // redo processing of string
342 /* we do not have enough room so grow the buffer*/
343 b2
= (UChar
*) uprv_malloc(b2Len
* U_SIZEOF_UCHAR
);
345 *status
= U_MEMORY_ALLOCATION_ERROR
;
349 *status
= U_ZERO_ERROR
; // reset error
351 b2Len
= u_strToPunycode(b1
,b1Len
,b2
,b2Len
,caseFlags
, status
);
354 if(U_FAILURE(*status
)){
357 // TODO : Reconsider while implementing the case preserve RFE
358 // convert all codepoints to lower case ASCII
359 // toASCIILower(b2,b2Len);
360 reqLength
= b2Len
+ACE_PREFIX_LENGTH
;
362 if(reqLength
> destCapacity
){
363 *status
= U_BUFFER_OVERFLOW_ERROR
;
366 //Step 7: prepend the ACE prefix
367 uprv_memcpy(dest
,ACE_PREFIX
,ACE_PREFIX_LENGTH
* U_SIZEOF_UCHAR
);
368 //Step 6: copy the contents in b2 into dest
369 uprv_memcpy(dest
+ACE_PREFIX_LENGTH
, b2
, b2Len
* U_SIZEOF_UCHAR
);
372 *status
= U_IDNA_ACE_PREFIX_ERROR
;
373 //position of failure is 0
374 uprv_syntaxError(b1
,0,b1Len
,parseError
);
378 // step 8: verify the length of label
379 if(reqLength
> MAX_LABEL_LENGTH
){
380 *status
= U_IDNA_LABEL_TOO_LONG_ERROR
;
390 uprv_free(caseFlags
);
392 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
396 _internal_toUnicode(const UChar
* src
, int32_t srcLength
,
397 UChar
* dest
, int32_t destCapacity
,
399 UStringPrepProfile
* nameprep
,
400 UParseError
* parseError
,
405 //UBool useSTD3ASCIIRules = (UBool)((options & UIDNA_USE_STD3_RULES) != 0);
406 int32_t namePrepOptions
= ((options
& UIDNA_ALLOW_UNASSIGNED
) != 0) ? USPREP_ALLOW_UNASSIGNED
: 0;
408 // TODO Revisit buffer handling. The label should not be over 63 ASCII characters. ICU4J may need to be updated too.
409 UChar b1Stack
[MAX_LABEL_BUFFER_SIZE
], b2Stack
[MAX_LABEL_BUFFER_SIZE
], b3Stack
[MAX_LABEL_BUFFER_SIZE
];
411 //initialize pointers to stack buffers
412 UChar
*b1
= b1Stack
, *b2
= b2Stack
, *b1Prime
=NULL
, *b3
=b3Stack
;
413 int32_t b1Len
, b2Len
, b1PrimeLen
, b3Len
,
414 b1Capacity
= MAX_LABEL_BUFFER_SIZE
,
415 b2Capacity
= MAX_LABEL_BUFFER_SIZE
,
416 b3Capacity
= MAX_LABEL_BUFFER_SIZE
,
420 UBool
* caseFlags
= NULL
;
422 UBool srcIsASCII
= TRUE
;
423 /*UBool srcIsLDH = TRUE;
424 int32_t failPos =0;*/
426 // step 1: find out if all the codepoints in src are ASCII
429 for(;src
[srcLength
]!=0;){
430 if(src
[srcLength
]> 0x7f){
432 }/*else if(isLDHChar(src[srcLength])==FALSE){
433 // here we do not assemble surrogates
434 // since we know that LDH code points
435 // are in the ASCII range only
441 }else if(srcLength
> 0){
442 for(int32_t j
=0; j
<srcLength
; j
++){
445 }/*else if(isLDHChar(src[j])==FALSE){
446 // here we do not assemble surrogates
447 // since we know that LDH code points
448 // are in the ASCII range only
457 if(srcIsASCII
== FALSE
){
458 // step 2: process the string
459 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Capacity
, namePrepOptions
, parseError
, status
);
460 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
461 // redo processing of string
462 /* we do not have enough room so grow the buffer*/
463 b1
= (UChar
*) uprv_malloc(b1Len
* U_SIZEOF_UCHAR
);
465 *status
= U_MEMORY_ALLOCATION_ERROR
;
469 *status
= U_ZERO_ERROR
; // reset error
471 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Len
, namePrepOptions
, parseError
, status
);
474 if(U_FAILURE(*status
)){
479 //just point src to b1
484 // The RFC states that
486 // ToUnicode never fails. If any step fails, then the original input
487 // is returned immediately in that step.
490 //step 3: verify ACE Prefix
491 if(startsWithPrefix(b1
,b1Len
)){
493 //step 4: Remove the ACE Prefix
494 b1Prime
= b1
+ ACE_PREFIX_LENGTH
;
495 b1PrimeLen
= b1Len
- ACE_PREFIX_LENGTH
;
497 //step 5: Decode using punycode
498 b2Len
= u_strFromPunycode(b1Prime
, b1PrimeLen
, b2
, b2Capacity
, caseFlags
,status
);
500 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
501 // redo processing of string
502 /* we do not have enough room so grow the buffer*/
503 b2
= (UChar
*) uprv_malloc(b2Len
* U_SIZEOF_UCHAR
);
505 *status
= U_MEMORY_ALLOCATION_ERROR
;
509 *status
= U_ZERO_ERROR
; // reset error
511 b2Len
= u_strFromPunycode(b1Prime
, b1PrimeLen
, b2
, b2Len
, caseFlags
, status
);
515 //step 6:Apply toASCII
516 b3Len
= uidna_toASCII(b2
, b2Len
, b3
, b3Capacity
, options
, parseError
, status
);
518 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
519 // redo processing of string
520 /* we do not have enough room so grow the buffer*/
521 b3
= (UChar
*) uprv_malloc(b3Len
* U_SIZEOF_UCHAR
);
523 *status
= U_MEMORY_ALLOCATION_ERROR
;
527 *status
= U_ZERO_ERROR
; // reset error
529 b3Len
= uidna_toASCII(b2
,b2Len
,b3
,b3Len
,options
,parseError
, status
);
533 if(U_FAILURE(*status
)){
538 if(compareCaseInsensitiveASCII(b1
, b1Len
, b3
, b3Len
) !=0){
539 // Cause the original to be returned.
540 *status
= U_IDNA_VERIFICATION_ERROR
;
544 //step 8: return output of step 5
546 if(b2Len
<= destCapacity
) {
547 uprv_memmove(dest
, b2
, b2Len
* U_SIZEOF_UCHAR
);
551 // See the start of this if statement for why this is commented out.
552 // verify that STD3 ASCII rules are satisfied
553 /*if(useSTD3ASCIIRules == TRUE){
554 if( srcIsLDH == FALSE // source contains some non-LDH characters
555 || src[0] == HYPHEN || src[srcLength-1] == HYPHEN){
556 *status = U_IDNA_STD3_ASCII_RULES_ERROR;
558 // populate the parseError struct
560 // failPos is always set the index of failure
561 uprv_syntaxError(src,failPos, srcLength,parseError);
562 }else if(src[0] == HYPHEN){
563 // fail position is 0
564 uprv_syntaxError(src,0,srcLength,parseError);
566 // the last index in the source is always length-1
567 uprv_syntaxError(src, (srcLength>0) ? srcLength-1 : srcLength, srcLength,parseError);
573 // just return the source
574 //copy the source to destination
575 if(srcLength
<= destCapacity
){
576 uprv_memmove(dest
,src
,srcLength
* U_SIZEOF_UCHAR
);
578 reqLength
= srcLength
;
584 if(b1
!= b1Stack
&& b1
!=src
){
590 uprv_free(caseFlags
);
592 // The RFC states that
594 // ToUnicode never fails. If any step fails, then the original input
595 // is returned immediately in that step.
597 // So if any step fails lets copy source to destination
598 if(U_FAILURE(*status
)){
599 //copy the source to destination
600 if(dest
&& srcLength
<= destCapacity
){
601 // srcLength should have already been set earlier.
602 U_ASSERT(srcLength
>= 0);
603 uprv_memmove(dest
,src
,srcLength
* U_SIZEOF_UCHAR
);
605 reqLength
= srcLength
;
606 *status
= U_ZERO_ERROR
;
609 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
612 U_CAPI
int32_t U_EXPORT2
613 uidna_toASCII(const UChar
* src
, int32_t srcLength
,
614 UChar
* dest
, int32_t destCapacity
,
616 UParseError
* parseError
,
619 if(status
== NULL
|| U_FAILURE(*status
)){
622 if((src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
623 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
627 UStringPrepProfile
* nameprep
= usprep_open(NULL
,DATA_FILE_NAME
, status
);
629 if(U_FAILURE(*status
)){
633 int32_t retLen
= _internal_toASCII(src
, srcLength
, dest
, destCapacity
, options
, nameprep
, parseError
, status
);
635 /* close the profile*/
636 usprep_close(nameprep
);
641 U_CAPI
int32_t U_EXPORT2
642 uidna_toUnicode(const UChar
* src
, int32_t srcLength
,
643 UChar
* dest
, int32_t destCapacity
,
645 UParseError
* parseError
,
648 if(status
== NULL
|| U_FAILURE(*status
)){
651 if( (src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
652 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
656 UStringPrepProfile
* nameprep
= usprep_open(NULL
, DATA_FILE_NAME
, status
);
658 if(U_FAILURE(*status
)){
662 int32_t retLen
= _internal_toUnicode(src
, srcLength
, dest
, destCapacity
, options
, nameprep
, parseError
, status
);
664 usprep_close(nameprep
);
670 U_CAPI
int32_t U_EXPORT2
671 uidna_IDNToASCII( const UChar
*src
, int32_t srcLength
,
672 UChar
* dest
, int32_t destCapacity
,
674 UParseError
*parseError
,
677 if(status
== NULL
|| U_FAILURE(*status
)){
680 if((src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
681 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
685 int32_t reqLength
= 0;
687 UStringPrepProfile
* nameprep
= usprep_open(NULL
, DATA_FILE_NAME
, status
);
689 if(U_FAILURE(*status
)){
693 //initialize pointers
694 UChar
*delimiter
= (UChar
*)src
;
695 UChar
*labelStart
= (UChar
*)src
;
696 UChar
*currentDest
= (UChar
*) dest
;
697 int32_t remainingLen
= srcLength
;
698 int32_t remainingDestCapacity
= destCapacity
;
699 int32_t labelLen
= 0, labelReqLength
= 0;
705 labelLen
= getNextSeparator(labelStart
,remainingLen
, &delimiter
,&done
);
707 if(!(labelLen
==0 && done
)){// make sure this is not a root label separator.
709 labelReqLength
= _internal_toASCII( labelStart
, labelLen
,
710 currentDest
, remainingDestCapacity
,
714 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
716 *status
= U_ZERO_ERROR
; // reset error
717 remainingDestCapacity
= 0;
722 if(U_FAILURE(*status
)){
726 reqLength
+=labelReqLength
;
727 // adjust the destination pointer
728 if(labelReqLength
< remainingDestCapacity
){
729 currentDest
= currentDest
+ labelReqLength
;
730 remainingDestCapacity
-= labelReqLength
;
732 // should never occur
733 remainingDestCapacity
= 0;
740 // add the label separator
741 if(remainingDestCapacity
> 0){
742 *currentDest
++ = FULL_STOP
;
743 remainingDestCapacity
--;
747 labelStart
= delimiter
;
748 if(remainingLen
>0 ){
749 remainingLen
= (int32_t)(srcLength
- (delimiter
- src
));
754 if(reqLength
> MAX_DOMAIN_NAME_LENGTH
){
755 *status
= U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR
;
758 usprep_close(nameprep
);
760 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
763 U_CAPI
int32_t U_EXPORT2
764 uidna_IDNToUnicode( const UChar
* src
, int32_t srcLength
,
765 UChar
* dest
, int32_t destCapacity
,
767 UParseError
* parseError
,
770 if(status
== NULL
|| U_FAILURE(*status
)){
773 if((src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
774 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
778 int32_t reqLength
= 0;
780 UStringPrepProfile
* nameprep
= usprep_open(NULL
, DATA_FILE_NAME
, status
);
782 if(U_FAILURE(*status
)){
786 //initialize pointers
787 UChar
*delimiter
= (UChar
*)src
;
788 UChar
*labelStart
= (UChar
*)src
;
789 UChar
*currentDest
= (UChar
*) dest
;
790 int32_t remainingLen
= srcLength
;
791 int32_t remainingDestCapacity
= destCapacity
;
792 int32_t labelLen
= 0, labelReqLength
= 0;
797 labelLen
= getNextSeparator(labelStart
,remainingLen
, &delimiter
,&done
);
799 // The RFC states that
801 // ToUnicode never fails. If any step fails, then the original input
802 // is returned immediately in that step.
804 // _internal_toUnicode will copy the label.
805 /*if(labelLen==0 && done==FALSE){
806 *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR;
810 labelReqLength
= _internal_toUnicode(labelStart
, labelLen
,
811 currentDest
, remainingDestCapacity
,
815 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
816 *status
= U_ZERO_ERROR
; // reset error
817 remainingDestCapacity
= 0;
820 if(U_FAILURE(*status
)){
824 reqLength
+=labelReqLength
;
825 // adjust the destination pointer
826 if(labelReqLength
< remainingDestCapacity
){
827 currentDest
= currentDest
+ labelReqLength
;
828 remainingDestCapacity
-= labelReqLength
;
830 // should never occur
831 remainingDestCapacity
= 0;
838 // add the label separator
839 // Unlike the ToASCII operation we don't normalize the label separators
840 if(remainingDestCapacity
> 0){
841 *currentDest
++ = *(labelStart
+ labelLen
);
842 remainingDestCapacity
--;
846 labelStart
= delimiter
;
847 if(remainingLen
>0 ){
848 remainingLen
= (int32_t)(srcLength
- (delimiter
- src
));
853 if(reqLength
> MAX_DOMAIN_NAME_LENGTH
){
854 *status
= U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR
;
857 usprep_close(nameprep
);
859 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
862 U_CAPI
int32_t U_EXPORT2
863 uidna_compare( const UChar
*s1
, int32_t length1
,
864 const UChar
*s2
, int32_t length2
,
868 if(status
== NULL
|| U_FAILURE(*status
)){
872 UChar b1Stack
[MAX_IDN_BUFFER_SIZE
], b2Stack
[MAX_IDN_BUFFER_SIZE
];
873 UChar
*b1
= b1Stack
, *b2
= b2Stack
;
874 int32_t b1Len
, b2Len
, b1Capacity
= MAX_IDN_BUFFER_SIZE
, b2Capacity
= MAX_IDN_BUFFER_SIZE
;
877 UParseError parseError
;
879 b1Len
= uidna_IDNToASCII(s1
, length1
, b1
, b1Capacity
, options
, &parseError
, status
);
880 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
881 // redo processing of string
882 b1
= (UChar
*) uprv_malloc(b1Len
* U_SIZEOF_UCHAR
);
884 *status
= U_MEMORY_ALLOCATION_ERROR
;
888 *status
= U_ZERO_ERROR
; // reset error
890 b1Len
= uidna_IDNToASCII(s1
,length1
,b1
,b1Len
, options
, &parseError
, status
);
894 b2Len
= uidna_IDNToASCII(s2
,length2
, b2
,b2Capacity
, options
, &parseError
, status
);
895 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
896 // redo processing of string
897 b2
= (UChar
*) uprv_malloc(b2Len
* U_SIZEOF_UCHAR
);
899 *status
= U_MEMORY_ALLOCATION_ERROR
;
903 *status
= U_ZERO_ERROR
; // reset error
905 b2Len
= uidna_IDNToASCII(s2
, length2
, b2
, b2Len
, options
, &parseError
, status
);
908 // when toASCII is applied all label separators are replaced with FULL_STOP
909 result
= compareCaseInsensitiveASCII(b1
,b1Len
,b2
,b2Len
);
923 #endif /* #if !UCONFIG_NO_IDNA */