2 *******************************************************************************
4 * Copyright (C) 2003-2014, 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
49 toASCIILower(UChar ch
){
50 if(CAPITAL_A
<= ch
&& ch
<= CAPITAL_Z
){
51 return ch
+ LOWER_CASE_DELTA
;
57 startsWithPrefix(const UChar
* src
, int32_t srcLength
){
58 UBool startsWithPrefix
= TRUE
;
60 if(srcLength
< ACE_PREFIX_LENGTH
){
64 for(int8_t i
=0; i
< ACE_PREFIX_LENGTH
; i
++){
65 if(toASCIILower(src
[i
]) != ACE_PREFIX
[i
]){
66 startsWithPrefix
= FALSE
;
69 return startsWithPrefix
;
74 compareCaseInsensitiveASCII(const UChar
* s1
, int32_t s1Len
,
75 const UChar
* s2
, int32_t s2Len
){
80 // are we comparing different lengths?
90 // ok the lengths are equal
98 for(int32_t i
=0;/* no condition */;i
++) {
100 /* If we reach the ends of both strings then they match */
108 /* Case-insensitive comparison */
110 rc
=(int32_t)toASCIILower(c1
)-(int32_t)toASCIILower(c2
);
122 * Ascertain if the given code point is a label separator as
123 * defined by the IDNA RFC
125 * @param ch The code point to be ascertained
126 * @return true if the char is a label separator
129 static inline UBool
isLabelSeparator(UChar ch
){
141 // returns the length of the label excluding the separator
142 // if *limit == separator then the length returned does not include
144 static inline int32_t
145 getNextSeparator(UChar
*src
, int32_t srcLength
,
146 UChar
**limit
, UBool
*done
){
151 *limit
= src
+ i
; // point to null
155 if(isLabelSeparator(src
[i
])){
156 *limit
= src
+ (i
+1); // go past the delimiter
163 for(i
=0;i
<srcLength
;i
++){
164 if(isLabelSeparator(src
[i
])){
165 *limit
= src
+ (i
+1); // go past the delimiter
169 // we have not found the delimiter
171 *limit
= src
+srcLength
;
177 static inline UBool
isLDHChar(UChar ch
){
182 //[\\u002D \\u0030-\\u0039 \\u0041-\\u005A \\u0061-\\u007A]
184 (0x0030 <= ch
&& ch
<= 0x0039) ||
185 (0x0041 <= ch
&& ch
<= 0x005A) ||
186 (0x0061 <= ch
&& ch
<= 0x007A)
194 _internal_toASCII(const UChar
* src
, int32_t srcLength
,
195 UChar
* dest
, int32_t destCapacity
,
197 UStringPrepProfile
* nameprep
,
198 UParseError
* parseError
,
202 // TODO Revisit buffer handling. The label should not be over 63 ASCII characters. ICU4J may need to be updated too.
203 UChar b1Stack
[MAX_LABEL_BUFFER_SIZE
], b2Stack
[MAX_LABEL_BUFFER_SIZE
];
204 //initialize pointers to stack buffers
205 UChar
*b1
= b1Stack
, *b2
= b2Stack
;
206 int32_t b1Len
=0, b2Len
,
207 b1Capacity
= MAX_LABEL_BUFFER_SIZE
,
208 b2Capacity
= MAX_LABEL_BUFFER_SIZE
,
211 int32_t namePrepOptions
= ((options
& UIDNA_ALLOW_UNASSIGNED
) != 0) ? USPREP_ALLOW_UNASSIGNED
: 0;
212 UBool
* caseFlags
= NULL
;
214 // the source contains all ascii codepoints
215 UBool srcIsASCII
= TRUE
;
216 // assume the source contains all LDH codepoints
217 UBool srcIsLDH
= TRUE
;
222 UBool useSTD3ASCIIRules
= (UBool
)((options
& UIDNA_USE_STD3_RULES
) != 0);
224 int32_t failPos
= -1;
227 srcLength
= u_strlen(src
);
230 if(srcLength
> b1Capacity
){
231 b1
= (UChar
*) uprv_malloc(srcLength
* U_SIZEOF_UCHAR
);
233 *status
= U_MEMORY_ALLOCATION_ERROR
;
236 b1Capacity
= srcLength
;
240 for( j
=0;j
<srcLength
;j
++){
244 b1
[b1Len
++] = src
[j
];
247 // step 2 is performed only if the source contains non ASCII
248 if(srcIsASCII
== FALSE
){
251 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Capacity
, namePrepOptions
, parseError
, status
);
253 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
254 // redo processing of string
255 // we do not have enough room so grow the buffer
259 b1
= (UChar
*) uprv_malloc(b1Len
* U_SIZEOF_UCHAR
);
261 *status
= U_MEMORY_ALLOCATION_ERROR
;
265 *status
= U_ZERO_ERROR
; // reset error
267 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Len
, namePrepOptions
, parseError
, status
);
271 if(U_FAILURE(*status
)){
275 *status
= U_IDNA_ZERO_LENGTH_LABEL_ERROR
;
281 for( j
=0;j
<b1Len
;j
++){
282 // check if output of usprep_prepare is all ASCII
285 }else if(isLDHChar(b1
[j
])==FALSE
){ // if the char is in ASCII range verify that it is an LDH character
290 if(useSTD3ASCIIRules
== TRUE
){
292 // 3(a) Verify the absence of non-LDH ASCII code points; that is, the
293 // absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F.
294 // 3(b) Verify the absence of leading and trailing hyphen-minus; that
295 // is, the absence of U+002D at the beginning and end of the
297 if( srcIsLDH
== FALSE
/* source at this point should not contain anyLDH characters */
298 || b1
[0] == HYPHEN
|| b1
[b1Len
-1] == HYPHEN
){
299 *status
= U_IDNA_STD3_ASCII_RULES_ERROR
;
301 /* populate the parseError struct */
303 // failPos is always set the index of failure
304 uprv_syntaxError(b1
,failPos
, b1Len
,parseError
);
305 }else if(b1
[0] == HYPHEN
){
306 // fail position is 0
307 uprv_syntaxError(b1
,0,b1Len
,parseError
);
309 // the last index in the source is always length-1
310 uprv_syntaxError(b1
, (b1Len
>0) ? b1Len
-1 : b1Len
, b1Len
,parseError
);
316 // Step 4: if the source is ASCII then proceed to step 8
318 if(b1Len
<= destCapacity
){
319 uprv_memmove(dest
, b1
, b1Len
* U_SIZEOF_UCHAR
);
326 // step 5 : verify the sequence does not begin with ACE prefix
327 if(!startsWithPrefix(b1
,b1Len
)){
329 //step 6: encode the sequence with punycode
331 // do not preserve the case flags for now!
332 // TODO: Preserve the case while implementing the RFE
333 // caseFlags = (UBool*) uprv_malloc(b1Len * sizeof(UBool));
334 // uprv_memset(caseFlags,TRUE,b1Len);
336 b2Len
= u_strToPunycode(b1
,b1Len
,b2
,b2Capacity
,caseFlags
, status
);
338 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
339 // redo processing of string
340 /* we do not have enough room so grow the buffer*/
341 b2
= (UChar
*) uprv_malloc(b2Len
* U_SIZEOF_UCHAR
);
343 *status
= U_MEMORY_ALLOCATION_ERROR
;
347 *status
= U_ZERO_ERROR
; // reset error
349 b2Len
= u_strToPunycode(b1
,b1Len
,b2
,b2Len
,caseFlags
, status
);
352 if(U_FAILURE(*status
)){
355 // TODO : Reconsider while implementing the case preserve RFE
356 // convert all codepoints to lower case ASCII
357 // toASCIILower(b2,b2Len);
358 reqLength
= b2Len
+ACE_PREFIX_LENGTH
;
360 if(reqLength
> destCapacity
){
361 *status
= U_BUFFER_OVERFLOW_ERROR
;
364 //Step 7: prepend the ACE prefix
365 uprv_memcpy(dest
,ACE_PREFIX
,ACE_PREFIX_LENGTH
* U_SIZEOF_UCHAR
);
366 //Step 6: copy the contents in b2 into dest
367 uprv_memcpy(dest
+ACE_PREFIX_LENGTH
, b2
, b2Len
* U_SIZEOF_UCHAR
);
370 *status
= U_IDNA_ACE_PREFIX_ERROR
;
371 //position of failure is 0
372 uprv_syntaxError(b1
,0,b1Len
,parseError
);
376 // step 8: verify the length of label
377 if(reqLength
> MAX_LABEL_LENGTH
){
378 *status
= U_IDNA_LABEL_TOO_LONG_ERROR
;
388 uprv_free(caseFlags
);
390 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
394 _internal_toUnicode(const UChar
* src
, int32_t srcLength
,
395 UChar
* dest
, int32_t destCapacity
,
397 UStringPrepProfile
* nameprep
,
398 UParseError
* parseError
,
403 //UBool useSTD3ASCIIRules = (UBool)((options & UIDNA_USE_STD3_RULES) != 0);
404 int32_t namePrepOptions
= ((options
& UIDNA_ALLOW_UNASSIGNED
) != 0) ? USPREP_ALLOW_UNASSIGNED
: 0;
406 // TODO Revisit buffer handling. The label should not be over 63 ASCII characters. ICU4J may need to be updated too.
407 UChar b1Stack
[MAX_LABEL_BUFFER_SIZE
], b2Stack
[MAX_LABEL_BUFFER_SIZE
], b3Stack
[MAX_LABEL_BUFFER_SIZE
];
409 //initialize pointers to stack buffers
410 UChar
*b1
= b1Stack
, *b2
= b2Stack
, *b1Prime
=NULL
, *b3
=b3Stack
;
411 int32_t b1Len
= 0, b2Len
, b1PrimeLen
, b3Len
,
412 b1Capacity
= MAX_LABEL_BUFFER_SIZE
,
413 b2Capacity
= MAX_LABEL_BUFFER_SIZE
,
414 b3Capacity
= MAX_LABEL_BUFFER_SIZE
,
417 UBool
* caseFlags
= NULL
;
419 UBool srcIsASCII
= TRUE
;
420 /*UBool srcIsLDH = TRUE;
421 int32_t failPos =0;*/
423 // step 1: find out if all the codepoints in src are ASCII
426 for(;src
[srcLength
]!=0;){
427 if(src
[srcLength
]> 0x7f){
429 }/*else if(isLDHChar(src[srcLength])==FALSE){
430 // here we do not assemble surrogates
431 // since we know that LDH code points
432 // are in the ASCII range only
438 }else if(srcLength
> 0){
439 for(int32_t j
=0; j
<srcLength
; j
++){
442 }/*else if(isLDHChar(src[j])==FALSE){
443 // here we do not assemble surrogates
444 // since we know that LDH code points
445 // are in the ASCII range only
454 if(srcIsASCII
== FALSE
){
455 // step 2: process the string
456 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Capacity
, namePrepOptions
, parseError
, status
);
457 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
458 // redo processing of string
459 /* we do not have enough room so grow the buffer*/
460 b1
= (UChar
*) uprv_malloc(b1Len
* U_SIZEOF_UCHAR
);
462 *status
= U_MEMORY_ALLOCATION_ERROR
;
466 *status
= U_ZERO_ERROR
; // reset error
468 b1Len
= usprep_prepare(nameprep
, src
, srcLength
, b1
, b1Len
, namePrepOptions
, parseError
, status
);
471 if(U_FAILURE(*status
)){
476 //just point src to b1
481 // The RFC states that
483 // ToUnicode never fails. If any step fails, then the original input
484 // is returned immediately in that step.
487 //step 3: verify ACE Prefix
488 if(startsWithPrefix(b1
,b1Len
)){
490 //step 4: Remove the ACE Prefix
491 b1Prime
= b1
+ ACE_PREFIX_LENGTH
;
492 b1PrimeLen
= b1Len
- ACE_PREFIX_LENGTH
;
494 //step 5: Decode using punycode
495 b2Len
= u_strFromPunycode(b1Prime
, b1PrimeLen
, b2
, b2Capacity
, caseFlags
,status
);
497 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
498 // redo processing of string
499 /* we do not have enough room so grow the buffer*/
500 b2
= (UChar
*) uprv_malloc(b2Len
* U_SIZEOF_UCHAR
);
502 *status
= U_MEMORY_ALLOCATION_ERROR
;
506 *status
= U_ZERO_ERROR
; // reset error
508 b2Len
= u_strFromPunycode(b1Prime
, b1PrimeLen
, b2
, b2Len
, caseFlags
, status
);
512 //step 6:Apply toASCII
513 b3Len
= uidna_toASCII(b2
, b2Len
, b3
, b3Capacity
, options
, parseError
, status
);
515 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
516 // redo processing of string
517 /* we do not have enough room so grow the buffer*/
518 b3
= (UChar
*) uprv_malloc(b3Len
* U_SIZEOF_UCHAR
);
520 *status
= U_MEMORY_ALLOCATION_ERROR
;
524 *status
= U_ZERO_ERROR
; // reset error
526 b3Len
= uidna_toASCII(b2
,b2Len
,b3
,b3Len
,options
,parseError
, status
);
530 if(U_FAILURE(*status
)){
535 if(compareCaseInsensitiveASCII(b1
, b1Len
, b3
, b3Len
) !=0){
536 // Cause the original to be returned.
537 *status
= U_IDNA_VERIFICATION_ERROR
;
541 //step 8: return output of step 5
543 if(b2Len
<= destCapacity
) {
544 uprv_memmove(dest
, b2
, b2Len
* U_SIZEOF_UCHAR
);
548 // See the start of this if statement for why this is commented out.
549 // verify that STD3 ASCII rules are satisfied
550 /*if(useSTD3ASCIIRules == TRUE){
551 if( srcIsLDH == FALSE // source contains some non-LDH characters
552 || src[0] == HYPHEN || src[srcLength-1] == HYPHEN){
553 *status = U_IDNA_STD3_ASCII_RULES_ERROR;
555 // populate the parseError struct
557 // failPos is always set the index of failure
558 uprv_syntaxError(src,failPos, srcLength,parseError);
559 }else if(src[0] == HYPHEN){
560 // fail position is 0
561 uprv_syntaxError(src,0,srcLength,parseError);
563 // the last index in the source is always length-1
564 uprv_syntaxError(src, (srcLength>0) ? srcLength-1 : srcLength, srcLength,parseError);
570 // just return the source
571 //copy the source to destination
572 if(srcLength
<= destCapacity
){
573 uprv_memmove(dest
,src
,srcLength
* U_SIZEOF_UCHAR
);
575 reqLength
= srcLength
;
581 if(b1
!= b1Stack
&& b1
!=src
){
587 uprv_free(caseFlags
);
589 // The RFC states that
591 // ToUnicode never fails. If any step fails, then the original input
592 // is returned immediately in that step.
594 // So if any step fails lets copy source to destination
595 if(U_FAILURE(*status
)){
596 //copy the source to destination
597 if(dest
&& srcLength
<= destCapacity
){
598 // srcLength should have already been set earlier.
599 U_ASSERT(srcLength
>= 0);
600 uprv_memmove(dest
,src
,srcLength
* U_SIZEOF_UCHAR
);
602 reqLength
= srcLength
;
603 *status
= U_ZERO_ERROR
;
606 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
609 U_CAPI
int32_t U_EXPORT2
610 uidna_toASCII(const UChar
* src
, int32_t srcLength
,
611 UChar
* dest
, int32_t destCapacity
,
613 UParseError
* parseError
,
616 if(status
== NULL
|| U_FAILURE(*status
)){
619 if((src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
620 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
624 UStringPrepProfile
* nameprep
= usprep_openByType(USPREP_RFC3491_NAMEPREP
, status
);
626 if(U_FAILURE(*status
)){
630 int32_t retLen
= _internal_toASCII(src
, srcLength
, dest
, destCapacity
, options
, nameprep
, parseError
, status
);
632 /* close the profile*/
633 usprep_close(nameprep
);
638 U_CAPI
int32_t U_EXPORT2
639 uidna_toUnicode(const UChar
* src
, int32_t srcLength
,
640 UChar
* dest
, int32_t destCapacity
,
642 UParseError
* parseError
,
645 if(status
== NULL
|| U_FAILURE(*status
)){
648 if( (src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
649 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
653 UStringPrepProfile
* nameprep
= usprep_openByType(USPREP_RFC3491_NAMEPREP
, status
);
655 if(U_FAILURE(*status
)){
659 int32_t retLen
= _internal_toUnicode(src
, srcLength
, dest
, destCapacity
, options
, nameprep
, parseError
, status
);
661 usprep_close(nameprep
);
667 U_CAPI
int32_t U_EXPORT2
668 uidna_IDNToASCII( const UChar
*src
, int32_t srcLength
,
669 UChar
* dest
, int32_t destCapacity
,
671 UParseError
*parseError
,
674 if(status
== NULL
|| U_FAILURE(*status
)){
677 if((src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
678 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
682 int32_t reqLength
= 0;
684 UStringPrepProfile
* nameprep
= usprep_openByType(USPREP_RFC3491_NAMEPREP
, status
);
686 if(U_FAILURE(*status
)){
690 //initialize pointers
691 UChar
*delimiter
= (UChar
*)src
;
692 UChar
*labelStart
= (UChar
*)src
;
693 UChar
*currentDest
= (UChar
*) dest
;
694 int32_t remainingLen
= srcLength
;
695 int32_t remainingDestCapacity
= destCapacity
;
696 int32_t labelLen
= 0, labelReqLength
= 0;
702 labelLen
= getNextSeparator(labelStart
,remainingLen
, &delimiter
,&done
);
704 if(!(labelLen
==0 && done
)){// make sure this is not a root label separator.
706 labelReqLength
= _internal_toASCII( labelStart
, labelLen
,
707 currentDest
, remainingDestCapacity
,
711 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
713 *status
= U_ZERO_ERROR
; // reset error
714 remainingDestCapacity
= 0;
719 if(U_FAILURE(*status
)){
723 reqLength
+=labelReqLength
;
724 // adjust the destination pointer
725 if(labelReqLength
< remainingDestCapacity
){
726 currentDest
= currentDest
+ labelReqLength
;
727 remainingDestCapacity
-= labelReqLength
;
729 // should never occur
730 remainingDestCapacity
= 0;
737 // add the label separator
738 if(remainingDestCapacity
> 0){
739 *currentDest
++ = FULL_STOP
;
740 remainingDestCapacity
--;
744 labelStart
= delimiter
;
745 if(remainingLen
>0 ){
746 remainingLen
= (int32_t)(srcLength
- (delimiter
- src
));
751 if(reqLength
> MAX_DOMAIN_NAME_LENGTH
){
752 *status
= U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR
;
755 usprep_close(nameprep
);
757 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
760 U_CAPI
int32_t U_EXPORT2
761 uidna_IDNToUnicode( const UChar
* src
, int32_t srcLength
,
762 UChar
* dest
, int32_t destCapacity
,
764 UParseError
* parseError
,
767 if(status
== NULL
|| U_FAILURE(*status
)){
770 if((src
==NULL
) || (srcLength
< -1) || (destCapacity
<0) || (!dest
&& destCapacity
> 0)){
771 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
775 int32_t reqLength
= 0;
777 UStringPrepProfile
* nameprep
= usprep_openByType(USPREP_RFC3491_NAMEPREP
, status
);
779 if(U_FAILURE(*status
)){
783 //initialize pointers
784 UChar
*delimiter
= (UChar
*)src
;
785 UChar
*labelStart
= (UChar
*)src
;
786 UChar
*currentDest
= (UChar
*) dest
;
787 int32_t remainingLen
= srcLength
;
788 int32_t remainingDestCapacity
= destCapacity
;
789 int32_t labelLen
= 0, labelReqLength
= 0;
794 labelLen
= getNextSeparator(labelStart
,remainingLen
, &delimiter
,&done
);
796 // The RFC states that
798 // ToUnicode never fails. If any step fails, then the original input
799 // is returned immediately in that step.
801 // _internal_toUnicode will copy the label.
802 /*if(labelLen==0 && done==FALSE){
803 *status = U_IDNA_ZERO_LENGTH_LABEL_ERROR;
807 labelReqLength
= _internal_toUnicode(labelStart
, labelLen
,
808 currentDest
, remainingDestCapacity
,
812 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
813 *status
= U_ZERO_ERROR
; // reset error
814 remainingDestCapacity
= 0;
817 if(U_FAILURE(*status
)){
821 reqLength
+=labelReqLength
;
822 // adjust the destination pointer
823 if(labelReqLength
< remainingDestCapacity
){
824 currentDest
= currentDest
+ labelReqLength
;
825 remainingDestCapacity
-= labelReqLength
;
827 // should never occur
828 remainingDestCapacity
= 0;
835 // add the label separator
836 // Unlike the ToASCII operation we don't normalize the label separators
837 if(remainingDestCapacity
> 0){
838 *currentDest
++ = *(labelStart
+ labelLen
);
839 remainingDestCapacity
--;
843 labelStart
= delimiter
;
844 if(remainingLen
>0 ){
845 remainingLen
= (int32_t)(srcLength
- (delimiter
- src
));
850 if(reqLength
> MAX_DOMAIN_NAME_LENGTH
){
851 *status
= U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR
;
854 usprep_close(nameprep
);
856 return u_terminateUChars(dest
, destCapacity
, reqLength
, status
);
859 U_CAPI
int32_t U_EXPORT2
860 uidna_compare( const UChar
*s1
, int32_t length1
,
861 const UChar
*s2
, int32_t length2
,
865 if(status
== NULL
|| U_FAILURE(*status
)){
869 UChar b1Stack
[MAX_IDN_BUFFER_SIZE
], b2Stack
[MAX_IDN_BUFFER_SIZE
];
870 UChar
*b1
= b1Stack
, *b2
= b2Stack
;
871 int32_t b1Len
, b2Len
, b1Capacity
= MAX_IDN_BUFFER_SIZE
, b2Capacity
= MAX_IDN_BUFFER_SIZE
;
874 UParseError parseError
;
876 b1Len
= uidna_IDNToASCII(s1
, length1
, b1
, b1Capacity
, options
, &parseError
, status
);
877 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
878 // redo processing of string
879 b1
= (UChar
*) uprv_malloc(b1Len
* U_SIZEOF_UCHAR
);
881 *status
= U_MEMORY_ALLOCATION_ERROR
;
885 *status
= U_ZERO_ERROR
; // reset error
887 b1Len
= uidna_IDNToASCII(s1
,length1
,b1
,b1Len
, options
, &parseError
, status
);
891 b2Len
= uidna_IDNToASCII(s2
,length2
, b2
,b2Capacity
, options
, &parseError
, status
);
892 if(*status
== U_BUFFER_OVERFLOW_ERROR
){
893 // redo processing of string
894 b2
= (UChar
*) uprv_malloc(b2Len
* U_SIZEOF_UCHAR
);
896 *status
= U_MEMORY_ALLOCATION_ERROR
;
900 *status
= U_ZERO_ERROR
; // reset error
902 b2Len
= uidna_IDNToASCII(s2
, length2
, b2
, b2Len
, options
, &parseError
, status
);
905 // when toASCII is applied all label separators are replaced with FULL_STOP
906 result
= compareCaseInsensitiveASCII(b1
,b1Len
,b2
,b2Len
);
920 #endif /* #if !UCONFIG_NO_IDNA */