1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
6 * Copyright (C) 2003-2014, International Business Machines
7 * Corporation and others. All Rights Reserved.
9 *******************************************************************************
10 * file name: uidna.cpp
12 * tab size: 8 (not used)
15 * created on: 2003feb1
16 * created by: Ram Viswanadha
19 #include "unicode/utypes.h"
23 #include "unicode/uidna.h"
24 #include "unicode/ustring.h"
25 #include "unicode/usprep.h"
32 /* it is official IDNA ACE Prefix is "xn--" */
33 static const UChar ACE_PREFIX
[] ={ 0x0078,0x006E,0x002d,0x002d } ;
34 #define ACE_PREFIX_LENGTH 4
36 #define MAX_LABEL_LENGTH 63
37 /* The Max length of the labels should not be more than MAX_LABEL_LENGTH */
38 #define MAX_LABEL_BUFFER_SIZE 100
40 #define MAX_DOMAIN_NAME_LENGTH 255
41 /* The Max length of the domain names should not be more than MAX_DOMAIN_NAME_LENGTH */
42 #define MAX_IDN_BUFFER_SIZE MAX_DOMAIN_NAME_LENGTH+1
44 #define LOWER_CASE_DELTA 0x0020
46 #define FULL_STOP 0x002E
47 #define CAPITAL_A 0x0041
48 #define CAPITAL_Z 0x005A
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 u_memmove(dest
, b1
, b1Len
);
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 u_memcpy(dest
, ACE_PREFIX
, ACE_PREFIX_LENGTH
);
368 //Step 6: copy the contents in b2 into dest
369 u_memcpy(dest
+ACE_PREFIX_LENGTH
, b2
, b2Len
);
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
= 0, b2Len
, b1PrimeLen
, b3Len
,
414 b1Capacity
= MAX_LABEL_BUFFER_SIZE
,
415 b2Capacity
= MAX_LABEL_BUFFER_SIZE
,
416 b3Capacity
= MAX_LABEL_BUFFER_SIZE
,
419 UBool
* caseFlags
= NULL
;
421 UBool srcIsASCII
= TRUE
;
422 /*UBool srcIsLDH = TRUE;
423 int32_t failPos =0;*/
425 // step 1: find out if all the codepoints in src are ASCII
428 for(;src
[srcLength
]!=0;){
429 if(src
[srcLength
]> 0x7f){
431 }/*else if(isLDHChar(src[srcLength])==FALSE){
432 // here we do not assemble surrogates
433 // since we know that LDH code points
434 // are in the ASCII range only
440 }else if(srcLength
> 0){
441 for(int32_t j
=0; j
<srcLength
; j
++){
444 }/*else if(isLDHChar(src[j])==FALSE){
445 // here we do not assemble surrogates
446 // since we know that LDH code points
447 // are in the ASCII range only
456 if(srcIsASCII
== FALSE
){
457 // step 2: process the string
458 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Capacity
, namePrepOptions
, parseError
, status
);
459 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
460 // redo processing of string
461 /* we do not have enough room so grow the buffer*/
462 b1
= (UChar
*) uprv_malloc(b1Len
* U_SIZEOF_UCHAR
);
464 *status
= U_MEMORY_ALLOCATION_ERROR
;
468 *status
= U_ZERO_ERROR
; // reset error
470 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Len
, namePrepOptions
, parseError
, status
);
473 if(U_FAILURE(*status
)){
478 //just point src to b1
483 // The RFC states that
485 // ToUnicode never fails. If any step fails, then the original input
486 // is returned immediately in that step.
489 //step 3: verify ACE Prefix
490 if(startsWithPrefix(b1
,b1Len
)){
492 //step 4: Remove the ACE Prefix
493 b1Prime
= b1
+ ACE_PREFIX_LENGTH
;
494 b1PrimeLen
= b1Len
- ACE_PREFIX_LENGTH
;
496 //step 5: Decode using punycode
497 b2Len
= u_strFromPunycode(b1Prime
, b1PrimeLen
, b2
, b2Capacity
, caseFlags
,status
);
499 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
500 // redo processing of string
501 /* we do not have enough room so grow the buffer*/
502 b2
= (UChar
*) uprv_malloc(b2Len
* U_SIZEOF_UCHAR
);
504 *status
= U_MEMORY_ALLOCATION_ERROR
;
508 *status
= U_ZERO_ERROR
; // reset error
510 b2Len
= u_strFromPunycode(b1Prime
, b1PrimeLen
, b2
, b2Len
, caseFlags
, status
);
514 //step 6:Apply toASCII
515 b3Len
= uidna_toASCII(b2
, b2Len
, b3
, b3Capacity
, options
, parseError
, status
);
517 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
518 // redo processing of string
519 /* we do not have enough room so grow the buffer*/
520 b3
= (UChar
*) uprv_malloc(b3Len
* U_SIZEOF_UCHAR
);
522 *status
= U_MEMORY_ALLOCATION_ERROR
;
526 *status
= U_ZERO_ERROR
; // reset error
528 b3Len
= uidna_toASCII(b2
,b2Len
,b3
,b3Len
,options
,parseError
, status
);
532 if(U_FAILURE(*status
)){
537 if(compareCaseInsensitiveASCII(b1
, b1Len
, b3
, b3Len
) !=0){
538 // Cause the original to be returned.
539 *status
= U_IDNA_VERIFICATION_ERROR
;
543 //step 8: return output of step 5
545 if(b2Len
<= destCapacity
) {
546 u_memmove(dest
, b2
, b2Len
);
550 // See the start of this if statement for why this is commented out.
551 // verify that STD3 ASCII rules are satisfied
552 /*if(useSTD3ASCIIRules == TRUE){
553 if( srcIsLDH == FALSE // source contains some non-LDH characters
554 || src[0] == HYPHEN || src[srcLength-1] == HYPHEN){
555 *status = U_IDNA_STD3_ASCII_RULES_ERROR;
557 // populate the parseError struct
559 // failPos is always set the index of failure
560 uprv_syntaxError(src,failPos, srcLength,parseError);
561 }else if(src[0] == HYPHEN){
562 // fail position is 0
563 uprv_syntaxError(src,0,srcLength,parseError);
565 // the last index in the source is always length-1
566 uprv_syntaxError(src, (srcLength>0) ? srcLength-1 : srcLength, srcLength,parseError);
572 // just return the source
573 //copy the source to destination
574 if(srcLength
<= destCapacity
){
575 u_memmove(dest
, src
, srcLength
);
577 reqLength
= srcLength
;
583 if(b1
!= b1Stack
&& b1
!=src
){
589 uprv_free(caseFlags
);
591 // The RFC states that
593 // ToUnicode never fails. If any step fails, then the original input
594 // is returned immediately in that step.
596 // So if any step fails lets copy source to destination
597 if(U_FAILURE(*status
)){
598 //copy the source to destination
599 if(dest
&& srcLength
<= destCapacity
){
600 // srcLength should have already been set earlier.
601 U_ASSERT(srcLength
>= 0);
602 u_memmove(dest
, src
, srcLength
);
604 reqLength
= srcLength
;
605 *status
= U_ZERO_ERROR
;
608 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
611 U_CAPI
int32_t U_EXPORT2
612 uidna_toASCII(const UChar
* src
, int32_t srcLength
,
613 UChar
* dest
, int32_t destCapacity
,
615 UParseError
* parseError
,
618 if(status
== NULL
|| U_FAILURE(*status
)){
621 if((src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
622 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
626 UStringPrepProfile
* nameprep
= usprep_openByType(USPREP_RFC3491_NAMEPREP
, status
);
628 if(U_FAILURE(*status
)){
632 int32_t retLen
= _internal_toASCII(src
, srcLength
, dest
, destCapacity
, options
, nameprep
, parseError
, status
);
634 /* close the profile*/
635 usprep_close(nameprep
);
640 U_CAPI
int32_t U_EXPORT2
641 uidna_toUnicode(const UChar
* src
, int32_t srcLength
,
642 UChar
* dest
, int32_t destCapacity
,
644 UParseError
* parseError
,
647 if(status
== NULL
|| U_FAILURE(*status
)){
650 if( (src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
651 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
655 UStringPrepProfile
* nameprep
= usprep_openByType(USPREP_RFC3491_NAMEPREP
, status
);
657 if(U_FAILURE(*status
)){
661 int32_t retLen
= _internal_toUnicode(src
, srcLength
, dest
, destCapacity
, options
, nameprep
, parseError
, status
);
663 usprep_close(nameprep
);
669 U_CAPI
int32_t U_EXPORT2
670 uidna_IDNToASCII( const UChar
*src
, int32_t srcLength
,
671 UChar
* dest
, int32_t destCapacity
,
673 UParseError
*parseError
,
676 if(status
== NULL
|| U_FAILURE(*status
)){
679 if((src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
680 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
684 int32_t reqLength
= 0;
686 UStringPrepProfile
* nameprep
= usprep_openByType(USPREP_RFC3491_NAMEPREP
, status
);
688 if(U_FAILURE(*status
)){
692 //initialize pointers
693 UChar
*delimiter
= (UChar
*)src
;
694 UChar
*labelStart
= (UChar
*)src
;
695 UChar
*currentDest
= (UChar
*) dest
;
696 int32_t remainingLen
= srcLength
;
697 int32_t remainingDestCapacity
= destCapacity
;
698 int32_t labelLen
= 0, labelReqLength
= 0;
704 labelLen
= getNextSeparator(labelStart
,remainingLen
, &delimiter
,&done
);
706 if(!(labelLen
==0 && done
)){// make sure this is not a root label separator.
708 labelReqLength
= _internal_toASCII( labelStart
, labelLen
,
709 currentDest
, remainingDestCapacity
,
713 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
715 *status
= U_ZERO_ERROR
; // reset error
716 remainingDestCapacity
= 0;
721 if(U_FAILURE(*status
)){
725 reqLength
+=labelReqLength
;
726 // adjust the destination pointer
727 if(labelReqLength
< remainingDestCapacity
){
728 currentDest
= currentDest
+ labelReqLength
;
729 remainingDestCapacity
-= labelReqLength
;
731 // should never occur
732 remainingDestCapacity
= 0;
739 // add the label separator
740 if(remainingDestCapacity
> 0){
741 *currentDest
++ = FULL_STOP
;
742 remainingDestCapacity
--;
746 labelStart
= delimiter
;
747 if(remainingLen
>0 ){
748 remainingLen
= (int32_t)(srcLength
- (delimiter
- src
));
753 if(reqLength
> MAX_DOMAIN_NAME_LENGTH
){
754 *status
= U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR
;
757 usprep_close(nameprep
);
759 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
762 U_CAPI
int32_t U_EXPORT2
763 uidna_IDNToUnicode( const UChar
* src
, int32_t srcLength
,
764 UChar
* dest
, int32_t destCapacity
,
766 UParseError
* parseError
,
769 if(status
== NULL
|| U_FAILURE(*status
)){
772 if((src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
773 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
777 int32_t reqLength
= 0;
779 UStringPrepProfile
* nameprep
= usprep_openByType(USPREP_RFC3491_NAMEPREP
, status
);
781 if(U_FAILURE(*status
)){
785 //initialize pointers
786 UChar
*delimiter
= (UChar
*)src
;
787 UChar
*labelStart
= (UChar
*)src
;
788 UChar
*currentDest
= (UChar
*) dest
;
789 int32_t remainingLen
= srcLength
;
790 int32_t remainingDestCapacity
= destCapacity
;
791 int32_t labelLen
= 0, labelReqLength
= 0;
796 labelLen
= getNextSeparator(labelStart
,remainingLen
, &delimiter
,&done
);
798 // The RFC states that
800 // ToUnicode never fails. If any step fails, then the original input
801 // is returned immediately in that step.
803 // _internal_toUnicode will copy the label.
804 /*if(labelLen==0 && done==FALSE){
805 *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR;
809 labelReqLength
= _internal_toUnicode(labelStart
, labelLen
,
810 currentDest
, remainingDestCapacity
,
814 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
815 *status
= U_ZERO_ERROR
; // reset error
816 remainingDestCapacity
= 0;
819 if(U_FAILURE(*status
)){
823 reqLength
+=labelReqLength
;
824 // adjust the destination pointer
825 if(labelReqLength
< remainingDestCapacity
){
826 currentDest
= currentDest
+ labelReqLength
;
827 remainingDestCapacity
-= labelReqLength
;
829 // should never occur
830 remainingDestCapacity
= 0;
837 // add the label separator
838 // Unlike the ToASCII operation we don't normalize the label separators
839 if(remainingDestCapacity
> 0){
840 *currentDest
++ = *(labelStart
+ labelLen
);
841 remainingDestCapacity
--;
845 labelStart
= delimiter
;
846 if(remainingLen
>0 ){
847 remainingLen
= (int32_t)(srcLength
- (delimiter
- src
));
852 if(reqLength
> MAX_DOMAIN_NAME_LENGTH
){
853 *status
= U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR
;
856 usprep_close(nameprep
);
858 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
861 U_CAPI
int32_t U_EXPORT2
862 uidna_compare( const UChar
*s1
, int32_t length1
,
863 const UChar
*s2
, int32_t length2
,
867 if(status
== NULL
|| U_FAILURE(*status
)){
871 UChar b1Stack
[MAX_IDN_BUFFER_SIZE
], b2Stack
[MAX_IDN_BUFFER_SIZE
];
872 UChar
*b1
= b1Stack
, *b2
= b2Stack
;
873 int32_t b1Len
, b2Len
, b1Capacity
= MAX_IDN_BUFFER_SIZE
, b2Capacity
= MAX_IDN_BUFFER_SIZE
;
876 UParseError parseError
;
878 b1Len
= uidna_IDNToASCII(s1
, length1
, b1
, b1Capacity
, options
, &parseError
, status
);
879 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
880 // redo processing of string
881 b1
= (UChar
*) uprv_malloc(b1Len
* U_SIZEOF_UCHAR
);
883 *status
= U_MEMORY_ALLOCATION_ERROR
;
887 *status
= U_ZERO_ERROR
; // reset error
889 b1Len
= uidna_IDNToASCII(s1
,length1
,b1
,b1Len
, options
, &parseError
, status
);
893 b2Len
= uidna_IDNToASCII(s2
,length2
, b2
,b2Capacity
, options
, &parseError
, status
);
894 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
895 // redo processing of string
896 b2
= (UChar
*) uprv_malloc(b2Len
* U_SIZEOF_UCHAR
);
898 *status
= U_MEMORY_ALLOCATION_ERROR
;
902 *status
= U_ZERO_ERROR
; // reset error
904 b2Len
= uidna_IDNToASCII(s2
, length2
, b2
, b2Len
, options
, &parseError
, status
);
907 // when toASCII is applied all label separators are replaced with FULL_STOP
908 result
= compareCaseInsensitiveASCII(b1
,b1Len
,b2
,b2Len
);
922 #endif /* #if !UCONFIG_NO_IDNA */