Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
1 /*
2 *******************************************************************************
3 *
4 * Copyright (C) 2002-2011, International Business Machines
5 * Corporation and others. All Rights Reserved.
6 *
7 *******************************************************************************
8 * file name: punycode.cpp
9 * encoding: US-ASCII
10 * tab size: 8 (not used)
11 * indentation:4
12 *
13 * created on: 2002jan31
14 * created by: Markus W. Scherer
15 */
18 /* This ICU code derived from: */
19 /*
20 punycode.c 0.4.0 (2001-Nov-17-Sat)
21 http://www.cs.berkeley.edu/~amc/idn/
22 Adam M. Costello
23 http://www.nicemice.net/amc/
25 Disclaimer and license
27 Regarding this entire document or any portion of it (including
28 the pseudocode and C code), the author makes no guarantees and
29 is not responsible for any damage resulting from its use. The
30 author grants irrevocable permission to anyone to use, modify,
31 and distribute it in any way that does not diminish the rights
32 of anyone else to use, modify, and distribute it, provided that
33 redistributed derivative works do not contain misleading author or
34 version information. Derivative works need not be licensed under
35 similar terms.
36 */
37 /*
38 * ICU modifications:
39 * - ICU data types and coding conventions
40 * - ICU string buffer handling with implicit source lengths
41 * and destination preflighting
42 * - UTF-16 handling
43 */
45 #include "unicode/utypes.h"
47 #if !UCONFIG_NO_IDNA
49 #include "unicode/ustring.h"
50 #include "unicode/utf.h"
51 #include "unicode/utf16.h"
52 #include "ustr_imp.h"
53 #include "cstring.h"
54 #include "cmemory.h"
55 #include "punycode.h"
56 #include "uassert.h"
59 /* Punycode ----------------------------------------------------------------- */
61 /* Punycode parameters for Bootstring */
62 #define BASE 36
63 #define TMIN 1
64 #define TMAX 26
65 #define SKEW 38
66 #define DAMP 700
67 #define INITIAL_BIAS 72
68 #define INITIAL_N 0x80
70 /* "Basic" Unicode/ASCII code points */
71 #define _HYPHEN 0X2d
72 #define DELIMITER _HYPHEN
74 #define _ZERO_ 0X30
75 #define _NINE 0x39
77 #define _SMALL_A 0X61
78 #define _SMALL_Z 0X7a
80 #define _CAPITAL_A 0X41
81 #define _CAPITAL_Z 0X5a
83 #define IS_BASIC(c) ((c)<0x80)
84 #define IS_BASIC_UPPERCASE(c) (_CAPITAL_A<=(c) && (c)<=_CAPITAL_Z)
86 /**
87 * digitToBasic() returns the basic code point whose value
88 * (when used for representing integers) is d, which must be in the
89 * range 0 to BASE-1. The lowercase form is used unless the uppercase flag is
90 * nonzero, in which case the uppercase form is used.
91 */
92 static inline char
93 digitToBasic(int32_t digit, UBool uppercase) {
94 /* 0..25 map to ASCII a..z or A..Z */
95 /* 26..35 map to ASCII 0..9 */
96 if(digit<26) {
97 if(uppercase) {
98 return (char)(_CAPITAL_A+digit);
99 } else {
100 return (char)(_SMALL_A+digit);
101 }
102 } else {
103 return (char)((_ZERO_-26)+digit);
104 }
105 }
107 /**
108 * basicToDigit[] contains the numeric value of a basic code
109 * point (for use in representing integers) in the range 0 to
110 * BASE-1, or -1 if b is does not represent a value.
111 */
112 static const int8_t
113 basicToDigit[256]={
114 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
115 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
117 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
118 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
120 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
121 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
123 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
124 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
126 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
127 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
129 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
130 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
132 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
133 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
135 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
136 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
137 };
139 static inline char
140 asciiCaseMap(char b, UBool uppercase) {
141 if(uppercase) {
142 if(_SMALL_A<=b && b<=_SMALL_Z) {
143 b-=(_SMALL_A-_CAPITAL_A);
144 }
145 } else {
146 if(_CAPITAL_A<=b && b<=_CAPITAL_Z) {
147 b+=(_SMALL_A-_CAPITAL_A);
148 }
149 }
150 return b;
151 }
153 /* Punycode-specific Bootstring code ---------------------------------------- */
155 /*
156 * The following code omits the {parts} of the pseudo-algorithm in the spec
157 * that are not used with the Punycode parameter set.
158 */
160 /* Bias adaptation function. */
161 static int32_t
162 adaptBias(int32_t delta, int32_t length, UBool firstTime) {
163 int32_t count;
165 if(firstTime) {
166 delta/=DAMP;
167 } else {
168 delta/=2;
169 }
171 delta+=delta/length;
172 for(count=0; delta>((BASE-TMIN)*TMAX)/2; count+=BASE) {
173 delta/=(BASE-TMIN);
174 }
176 return count+(((BASE-TMIN+1)*delta)/(delta+SKEW));
177 }
179 #define MAX_CP_COUNT 200
181 U_CFUNC int32_t
182 u_strToPunycode(const UChar *src, int32_t srcLength,
183 UChar *dest, int32_t destCapacity,
184 const UBool *caseFlags,
185 UErrorCode *pErrorCode) {
187 int32_t cpBuffer[MAX_CP_COUNT];
188 int32_t n, delta, handledCPCount, basicLength, destLength, bias, j, m, q, k, t, srcCPCount;
189 UChar c, c2;
191 /* argument checking */
192 if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
193 return 0;
194 }
196 if(src==NULL || srcLength<-1 || (dest==NULL && destCapacity!=0)) {
197 *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
198 return 0;
199 }
201 /*
202 * Handle the basic code points and
203 * convert extended ones to UTF-32 in cpBuffer (caseFlag in sign bit):
204 */
205 srcCPCount=destLength=0;
206 if(srcLength==-1) {
207 /* NUL-terminated input */
208 for(j=0; /* no condition */; ++j) {
209 if((c=src[j])==0) {
210 break;
211 }
212 if(srcCPCount==MAX_CP_COUNT) {
213 /* too many input code points */
214 *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
215 return 0;
216 }
217 if(IS_BASIC(c)) {
218 cpBuffer[srcCPCount++]=0;
219 if(destLength<destCapacity) {
220 dest[destLength]=
221 caseFlags!=NULL ?
222 asciiCaseMap((char)c, caseFlags[j]) :
223 (char)c;
224 }
225 ++destLength;
226 } else {
227 n=(caseFlags!=NULL && caseFlags[j])<<31L;
228 if(U16_IS_SINGLE(c)) {
229 n|=c;
230 } else if(U16_IS_LEAD(c) && U16_IS_TRAIL(c2=src[j+1])) {
231 ++j;
232 n|=(int32_t)U16_GET_SUPPLEMENTARY(c, c2);
233 } else {
234 /* error: unmatched surrogate */
235 *pErrorCode=U_INVALID_CHAR_FOUND;
236 return 0;
237 }
238 cpBuffer[srcCPCount++]=n;
239 }
240 }
241 } else {
242 /* length-specified input */
243 for(j=0; j<srcLength; ++j) {
244 if(srcCPCount==MAX_CP_COUNT) {
245 /* too many input code points */
246 *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR;
247 return 0;
248 }
249 c=src[j];
250 if(IS_BASIC(c)) {
251 cpBuffer[srcCPCount++]=0;
252 if(destLength<destCapacity) {
253 dest[destLength]=
254 caseFlags!=NULL ?
255 asciiCaseMap((char)c, caseFlags[j]) :
256 (char)c;
257 }
258 ++destLength;
259 } else {
260 n=(caseFlags!=NULL && caseFlags[j])<<31L;
261 if(U16_IS_SINGLE(c)) {
262 n|=c;
263 } else if(U16_IS_LEAD(c) && (j+1)<srcLength && U16_IS_TRAIL(c2=src[j+1])) {
264 ++j;
265 n|=(int32_t)U16_GET_SUPPLEMENTARY(c, c2);
266 } else {
267 /* error: unmatched surrogate */
268 *pErrorCode=U_INVALID_CHAR_FOUND;
269 return 0;
270 }
271 cpBuffer[srcCPCount++]=n;
272 }
273 }
274 }
276 /* Finish the basic string - if it is not empty - with a delimiter. */
277 basicLength=destLength;
278 if(basicLength>0) {
279 if(destLength<destCapacity) {
280 dest[destLength]=DELIMITER;
281 }
282 ++destLength;
283 }
285 /*
286 * handledCPCount is the number of code points that have been handled
287 * basicLength is the number of basic code points
288 * destLength is the number of chars that have been output
289 */
291 /* Initialize the state: */
292 n=INITIAL_N;
293 delta=0;
294 bias=INITIAL_BIAS;
296 /* Main encoding loop: */
297 for(handledCPCount=basicLength; handledCPCount<srcCPCount; /* no op */) {
298 /*
299 * All non-basic code points < n have been handled already.
300 * Find the next larger one:
301 */
302 for(m=0x7fffffff, j=0; j<srcCPCount; ++j) {
303 q=cpBuffer[j]&0x7fffffff; /* remove case flag from the sign bit */
304 if(n<=q && q<m) {
305 m=q;
306 }
307 }
309 /*
310 * Increase delta enough to advance the decoder's
311 * <n,i> state to <m,0>, but guard against overflow:
312 */
313 if(m-n>(0x7fffffff-MAX_CP_COUNT-delta)/(handledCPCount+1)) {
314 *pErrorCode=U_INTERNAL_PROGRAM_ERROR;
315 return 0;
316 }
317 delta+=(m-n)*(handledCPCount+1);
318 n=m;
320 /* Encode a sequence of same code points n */
321 for(j=0; j<srcCPCount; ++j) {
322 q=cpBuffer[j]&0x7fffffff; /* remove case flag from the sign bit */
323 if(q<n) {
324 ++delta;
325 } else if(q==n) {
326 /* Represent delta as a generalized variable-length integer: */
327 for(q=delta, k=BASE; /* no condition */; k+=BASE) {
329 /** RAM: comment out the old code for conformance with draft-ietf-idn-punycode-03.txt
331 t=k-bias;
332 if(t<TMIN) {
333 t=TMIN;
334 } else if(t>TMAX) {
335 t=TMAX;
336 }
337 */
339 t=k-bias;
340 if(t<TMIN) {
341 t=TMIN;
342 } else if(k>=(bias+TMAX)) {
343 t=TMAX;
344 }
346 if(q<t) {
347 break;
348 }
350 if(destLength<destCapacity) {
351 dest[destLength]=digitToBasic(t+(q-t)%(BASE-t), 0);
352 }
353 ++destLength;
354 q=(q-t)/(BASE-t);
355 }
357 if(destLength<destCapacity) {
358 dest[destLength]=digitToBasic(q, (UBool)(cpBuffer[j]<0));
359 }
360 ++destLength;
361 bias=adaptBias(delta, handledCPCount+1, (UBool)(handledCPCount==basicLength));
362 delta=0;
363 ++handledCPCount;
364 }
365 }
367 ++delta;
368 ++n;
369 }
371 return u_terminateUChars(dest, destCapacity, destLength, pErrorCode);
372 }
374 U_CFUNC int32_t
375 u_strFromPunycode(const UChar *src, int32_t srcLength,
376 UChar *dest, int32_t destCapacity,
377 UBool *caseFlags,
378 UErrorCode *pErrorCode) {
379 int32_t n, destLength, i, bias, basicLength, j, in, oldi, w, k, digit, t,
380 destCPCount, firstSupplementaryIndex, cpLength;
381 UChar b;
383 /* argument checking */
384 if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
385 return 0;
386 }
388 if(src==NULL || srcLength<-1 || (dest==NULL && destCapacity!=0)) {
389 *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
390 return 0;
391 }
393 if(srcLength==-1) {
394 srcLength=u_strlen(src);
395 }
397 /*
398 * Handle the basic code points:
399 * Let basicLength be the number of input code points
400 * before the last delimiter, or 0 if there is none,
401 * then copy the first basicLength code points to the output.
402 *
403 * The two following loops iterate backward.
404 */
405 for(j=srcLength; j>0;) {
406 if(src[--j]==DELIMITER) {
407 break;
408 }
409 }
410 destLength=basicLength=destCPCount=j;
411 U_ASSERT(destLength>=0);
413 while(j>0) {
414 b=src[--j];
415 if(!IS_BASIC(b)) {
416 *pErrorCode=U_INVALID_CHAR_FOUND;
417 return 0;
418 }
420 if(j<destCapacity) {
421 dest[j]=(UChar)b;
423 if(caseFlags!=NULL) {
424 caseFlags[j]=IS_BASIC_UPPERCASE(b);
425 }
426 }
427 }
429 /* Initialize the state: */
430 n=INITIAL_N;
431 i=0;
432 bias=INITIAL_BIAS;
433 firstSupplementaryIndex=1000000000;
435 /*
436 * Main decoding loop:
437 * Start just after the last delimiter if any
438 * basic code points were copied; start at the beginning otherwise.
439 */
440 for(in=basicLength>0 ? basicLength+1 : 0; in<srcLength; /* no op */) {
441 /*
442 * in is the index of the next character to be consumed, and
443 * destCPCount is the number of code points in the output array.
444 *
445 * Decode a generalized variable-length integer into delta,
446 * which gets added to i. The overflow checking is easier
447 * if we increase i as we go, then subtract off its starting
448 * value at the end to obtain delta.
449 */
450 for(oldi=i, w=1, k=BASE; /* no condition */; k+=BASE) {
451 if(in>=srcLength) {
452 *pErrorCode=U_ILLEGAL_CHAR_FOUND;
453 return 0;
454 }
456 digit=basicToDigit[(uint8_t)src[in++]];
457 if(digit<0) {
458 *pErrorCode=U_INVALID_CHAR_FOUND;
459 return 0;
460 }
461 if(digit>(0x7fffffff-i)/w) {
462 /* integer overflow */
463 *pErrorCode=U_ILLEGAL_CHAR_FOUND;
464 return 0;
465 }
467 i+=digit*w;
468 /** RAM: comment out the old code for conformance with draft-ietf-idn-punycode-03.txt
469 t=k-bias;
470 if(t<TMIN) {
471 t=TMIN;
472 } else if(t>TMAX) {
473 t=TMAX;
474 }
475 */
476 t=k-bias;
477 if(t<TMIN) {
478 t=TMIN;
479 } else if(k>=(bias+TMAX)) {
480 t=TMAX;
481 }
482 if(digit<t) {
483 break;
484 }
486 if(w>0x7fffffff/(BASE-t)) {
487 /* integer overflow */
488 *pErrorCode=U_ILLEGAL_CHAR_FOUND;
489 return 0;
490 }
491 w*=BASE-t;
492 }
494 /*
495 * Modification from sample code:
496 * Increments destCPCount here,
497 * where needed instead of in for() loop tail.
498 */
499 ++destCPCount;
500 bias=adaptBias(i-oldi, destCPCount, (UBool)(oldi==0));
502 /*
503 * i was supposed to wrap around from (incremented) destCPCount to 0,
504 * incrementing n each time, so we'll fix that now:
505 */
506 if(i/destCPCount>(0x7fffffff-n)) {
507 /* integer overflow */
508 *pErrorCode=U_ILLEGAL_CHAR_FOUND;
509 return 0;
510 }
512 n+=i/destCPCount;
513 i%=destCPCount;
514 /* not needed for Punycode: */
515 /* if (decode_digit(n) <= BASE) return punycode_invalid_input; */
517 if(n>0x10ffff || U_IS_SURROGATE(n)) {
518 /* Unicode code point overflow */
519 *pErrorCode=U_ILLEGAL_CHAR_FOUND;
520 return 0;
521 }
523 /* Insert n at position i of the output: */
524 cpLength=U16_LENGTH(n);
525 if(dest!=NULL && ((destLength+cpLength)<=destCapacity)) {
526 int32_t codeUnitIndex;
528 /*
529 * Handle indexes when supplementary code points are present.
530 *
531 * In almost all cases, there will be only BMP code points before i
532 * and even in the entire string.
533 * This is handled with the same efficiency as with UTF-32.
534 *
535 * Only the rare cases with supplementary code points are handled
536 * more slowly - but not too bad since this is an insertion anyway.
537 */
538 if(i<=firstSupplementaryIndex) {
539 codeUnitIndex=i;
540 if(cpLength>1) {
541 firstSupplementaryIndex=codeUnitIndex;
542 } else {
543 ++firstSupplementaryIndex;
544 }
545 } else {
546 codeUnitIndex=firstSupplementaryIndex;
547 U16_FWD_N(dest, codeUnitIndex, destLength, i-codeUnitIndex);
548 }
550 /* use the UChar index codeUnitIndex instead of the code point index i */
551 if(codeUnitIndex<destLength) {
552 uprv_memmove(dest+codeUnitIndex+cpLength,
553 dest+codeUnitIndex,
554 (destLength-codeUnitIndex)*U_SIZEOF_UCHAR);
555 if(caseFlags!=NULL) {
556 uprv_memmove(caseFlags+codeUnitIndex+cpLength,
557 caseFlags+codeUnitIndex,
558 destLength-codeUnitIndex);
559 }
560 }
561 if(cpLength==1) {
562 /* BMP, insert one code unit */
563 dest[codeUnitIndex]=(UChar)n;
564 } else {
565 /* supplementary character, insert two code units */
566 dest[codeUnitIndex]=U16_LEAD(n);
567 dest[codeUnitIndex+1]=U16_TRAIL(n);
568 }
569 if(caseFlags!=NULL) {
570 /* Case of last character determines uppercase flag: */
571 caseFlags[codeUnitIndex]=IS_BASIC_UPPERCASE(src[in-1]);
572 if(cpLength==2) {
573 caseFlags[codeUnitIndex+1]=FALSE;
574 }
575 }
576 }
577 destLength+=cpLength;
578 U_ASSERT(destLength>=0);
579 ++i;
580 }
582 return u_terminateUChars(dest, destCapacity, destLength, pErrorCode);
583 }
585 /* ### check notes on overflow handling - only necessary if not IDNA? are these Punycode functions to be public? */
587 #endif /* #if !UCONFIG_NO_IDNA */