doc:添加有关strverscmp修复的新闻条目。
[libidn.git]/图书馆/idna。c(c)
1/*idna.c——国际化域名库原型。
2版权所有(C)2002-2024 Simon Josefsson
4此文件是GNU Libidn的一部分。
5
6GNU Libidn是自由软件:你可以重新发布它和/或
7根据以下任一条款对其进行修改:
8
9*由Free发布的GNU Lesser General Public License
10软件基础;许可证的版本3,或(位于
11您的选项)任何更高版本。
12
13
14
15*由Free发布的GNU通用公共许可证
16软件基础;许可证的版本2,或(位于
17您的选项)任何更高版本。
18
19或者两者并行,比如这里。
20
21GNU Libidn的发布是为了希望它有用,
22但无任何保证;甚至没有
23适销性或特定用途的适用性。参见GNU
24通用公共许可证了解更多详细信息。
25
26您应该已经收到GNU通用公共许可证的副本,并且
27GNU Lesser通用公共许可证以及本程序。如果
28不是,请参阅<https://www.gnu.org/licenses网站/>. */
29
30#如果定义为HAVE_CONFIG_H
31#包括“config.h”
32#结尾
33
34#包括<stdlib.h>
35#包括<string.h>
36#包括<stringprep.h>
37#包括<punycode.h>
38
39#包括“idna.h”
40
41/*获取c_strcasecmp。 */
42#包括<c-strcase.h>
43
44#定义DOTP(c)((c)==0x002E||(c)==0x3002||\
45(c)==0xFF0E||(c)==0xFF61)
46
47/*核心功能*/
48
49/**
50*idna_to_ascii_4i:
51*@in:带有unicode代码点的输入数组。
52*@inlen:带有unicode代码点的输入数组的长度。
53*@out:输出以零结尾的字符串,该字符串必须有at的空间
54*至少63个字符加上终止零。
55*@flags:#Idna_flags值,例如,%Idna_ALLOW_UNASSIGNED或
56*%IDNA_USE_STD3_ASCII_RULES。
57 *
58*ToASCII操作采用一系列Unicode代码点
59*组成一个域标签并将其转换为一系列代码
60ASCII范围内的*点(0..7F)。如果ToASCII成功
61*原始序列和结果序列是等效的标签。
62 *
63*需要注意的是,ToASCII操作可能会失败。ToASCII码
64*如果任何步骤失败,则失败。如果ToASCII操作的任何步骤
65*在域名的任何标签上都失败,该域名不得使用
66*作为国际化域名。用这个消亡的方法
67*故障取决于应用程序。
68 *
69*ToASCII的输入是一系列代码点,即AllowUnassigned
70*标志和UseSTD3ASCIIRules标志。ToASCII的输出是
71*ASCII码点序列或故障条件。
72 *
73*ToASCII从不改变ASCII中的代码点序列
74*范围开始(尽管可能会失败)。应用ToASCII
75*多次操作与仅应用效果完全相同
76*一次。
77 *
78*返回值:成功时返回0,或返回#Idna_rc错误代码。
79 */
80整数
81idna_to_ascii4i(const uint32_t*in,size_t inlen,char*out,int标志)
82{
83size_t长度,outlen;
84uint32_t*src;/*XXX不需要复制数据? */
85整数rc;
86
87  /*
88*ToASCII由以下步骤组成:
89   *
90*1。如果序列中的所有代码点都在ASCII范围内(0..7F)
91*然后跳到步骤3。
92   */
93
94  {
95大小_ i;
96int-inasciirange;
97
98inasciirange=1;
99对于(i=0;i<入口;i++)
100如果(in[i]>0x7F)
101inasciirange=0;
102if(inasciirange)
103      {
104src=malloc(大小(in[0])*(入口+1));
105如果(src==NULL)
106返回IDNA_MALLOC_ERROR;
107
108memcpy(src,in,sizeof(in[0])*入口);
109src[入口]=0;
110
111转到步骤3;
112      }
113  }
114
115/*
116*2.执行[NAMEPREP]中指定的步骤,如果有则失败
117*错误。[NAMEPREP]中使用了AllowUnassigned标志。
118   */
119
120  {
121字符*p;
122
123p=字符串rep_ucs4_to_utf8(in,(ssize_t)inlen,NULL,NULL);
124如果(p==空)
125返回IDNA_MALLOC_ERROR;
126
127len=斯特伦(p);
128
129      {
130char*newp;
131
132len=2*len+10;/*XXX最好猜猜? */
133newp=重新分配(p,len);
134if(newp==NULL)
135{
136自由(p);
137返回IDNA_MALLOC_ERROR;
138          }
139p=新p;
140
141if(标志&IDNA_ALLOW_UNASSIGNED)
142rc=字符串rep_nameprep(p,len);
143其他
144rc=字符串rep_nameprep_no_unassigned(p,len);
145      }
146同时(rc==STRINGPREP_TOO_SMALL_BUFFER);
147
148if(rc!=字符串PREP_OK)
149      {
150自由(p);
151返回IDNA_STRINGPREP_ERROR;
152      }
153
154src=字符串rep_utf8_to_ucs4(p,-1,NULL);
155
156自由(p);
157
158if(!src)
159返回IDNA_MALLOC_ERROR;
160}
161
162第3步:
163  /*
164*3.如果设置了UseSTD3ASCIIRules标志,则执行以下检查:
165   *
166*(a)验证无非LDH ASCII码点;也就是说,
167*缺少0..2C、2E。。2F、3A。。40、5B。。60和7B。。第7页。
168   *
169*(b)验证前导和尾随连字符-分钟的缺失;
170*即,在开始和结束时没有U+002D
171*序列。
172   */
173
174if(标志&IDNA_USE_STD3_ASCII_RULES)
175{
176大小_ i;
177
178对于(i=0;src[i];i++)
179如果(src[i]<=0x2C||src[i]==0x2E||src[i]==0x2F||
180(src[i]>=0x3A&&src[i]<=0x40)||
181(src[i]>=0x5B&&src[i]<=0x60)||
182(src[i]>=0x7B&&src[i]<=0x7F)
183          {
184自由(src);
185返回IDNA_CONTAINS_NON_LDH;
186          }
187
188如果(src[0]==0x002D||(i>0&&src[i-1]==x002D)
189        {
190自由(src);
191返回IDNA_CONTAINS_MINUS;
192        }
193    }
194
195  /*
196*4.如果序列中的所有代码点都在ASCII范围内
197*(0..7F),然后跳到步骤8。
198   */
199
200{
201大小_ i;
202int-inasciirange;
203
204inasciirange=1;
205对于(i=0;src[i];i++)
206      {
207如果(src[i]>0x7F)
208inasciirange=0;
209/*如果要跳到步骤8,请将字符串复制到输出缓冲区*/
210如果(i<64)
211输出[i]=src[i];
212      }
213如果(i<64)
214输出[i]=“\0”;
215其他
216      {
217自由(src);
218返回IDNA_INVALID_LENGTH;
219      }
220if(inasciirange)
221转到步骤8;
222  }
223
224  /*
225*5.验证序列不是以ACE前缀开头。
226   *
227   */
228
229  {
230大小_ i;
231int匹配;
232
233匹配=1;
234对于(i=0;匹配&&i<strlen(IDNA_ACE_PREFIX);i++)
235如果(((uint32_t)IDNA_ACE_PREFIX[i]&0xFF)=src[i])
236匹配=0;
237if(匹配)
238{
239自由(src);
240返回IDNA_CONTAINS_ACE_PREFIX;
241      }
242  }
243
244  /*
245*6.使用[PUNYCODE]中的编码算法对序列进行编码
246*,如果出现错误则失败。
247   */
248for(len=0;src[len];len++)
249    ;
250src[len]=“\0”;
251outlen=63-strlen(IDNA_ACE_PREFIX);
252rc=punycode_encode(len,src,NULL,
253&outlen,&out[strlen(IDNA_ACE_PREFIX)]);
254如果(rc!=PUNYCODE_SUCCESS)
255{
256自由(src);
257返回IDNA_PUNYCODE_ERROR;
258    }
259out[strlen(IDNA_ACE_PREFIX)+outlen]=“\0”;
260
261  /*
262*7.在ACE前缀之前。
263   */
264
265memcpy(输出,IDNA_ACE_PREFIX,strlen(IDNA_ACE _PREFIX));
266
267  /*
268*8.验证代码点的数量是否在1到63之间
269*包含(0除外)。
270   */
271
272第8步:
273自由(src);
274if(strlen(out)<1)
275返回IDNA_INVALID_LENGTH;
276
277返回IDNA_SUCCESS;
278}
279
280/*ToUnicode()。可能realloc()utf8in。将无条件释放utf8in。 */
281静态int
282idna_to_unicode内部(字符*utf8in,
283uint32_t*out,size_t*outlen,int标志)
284{
285整数rc;
286char tmpout[64];
287size_t utf8len=字符串(utf8in)+1;
288size_t addlen=0,addinc=utf8len/10+1;
289
290  /*
291*ToUnicode由以下步骤组成:
292*
293*1.如果序列包含ASCII范围之外的任何代码点
294*(0..7F)然后继续执行步骤2,否则跳至步骤3。
295   */
296
297  {
298大小_ i;
299int-inasciirange;
300
301inasciirange=1;
302对于(i=0;utf8in[i];i++)
303if(utf8in[i]和~0x7F)
304inasciirange=0;
305if(inasciirange)
306转到步骤3;
307  }
308
309  /*
310*2.执行[NAMEPREP]中指定的步骤,如果存在
311*错误。(如果此处也执行ToASCII的步骤3,则不会
312*影响ToUnicode的整体行为,但不是
313*必要。)AllowUnassigned标志用于[NAMEPREP]中。
314   */
315
316    {
317char*newp=重新分配(utf8in,utf8len+addlen);
318if(newp==NULL)
319{
320自由(utf8in);
321返回IDNA_MALLOC_ERROR;
322        }
323utf8in=新p;
324if(标志&IDNA_ALLOW_UNASSIGNED)
325rc=字符串rep_nameprep(utf8in,utf8len+addlen);
326其他
327rc=字符串rep_nameprep_no_unassigned(utf8in,utf8len+addlen);
328addlen+=addinc;
329addinc*=2;
330    }
331同时(rc==STRINGPREP_TOO_SMALL_BUFFER);
332
333if(rc!=字符串PREP_OK)
334    {
335自由(utf8in);
336返回IDNA_STRINGPREP_ERROR;
337    }
338
339/*3.验证序列是否以ACE前缀开头,并保存一个
340*序列的副本。
341   * ...ToASCII和ToUnicode操作必须识别ACE
342前缀区分大小写。
343   */
344
345第3步:
346if(c_strncasemp(utf8in,IDNA_ACE_PREFIX,strlen(IDNA_ACE _PREFIX))= 0)
347    {
348自由(utf8in);
349返回IDNA_NO_ACE_PREFIX;
350    }
351
352/*4.删除ACE前缀。
353   */
354
355内存移动(utf8in,&utf8in[strlen(IDNA_ACE_PREFIX)],
356strlen(utf8in)-strlen(IDNA_ACE_PREFIX)+1);
357
358/*5.使用[PUNYCODE]中的解码算法解码序列
359*如果出现错误,则失败。保存结果的副本
360*此步骤。
361   */
362
363(*外)--;/*为零保留一个*/
364
365rc=punycode_decode(字符串(utf8in),utf8in.,outlen,out,NULL);
366如果(rc!=PUNYCODE_SUCCESS)
367    {
368自由(utf8in);
369返回IDNA_PUNYCODE_ERROR;
370    }
371
372out[*outlen]=0;/*加零*/
373
374/*6.应用到ASCII。
375   */
376
377rc=idna_to_ascii_4i(out,*outlen,tmpout,flags);
378如果(rc!=IDNA_SUCCESS)
379    {
380自由(utf8in);
381返回rc;
382    }
383
384/*7.验证步骤6的结果是否与保存的副本匹配
385*步骤3,使用区分大小写的ASCII比较。
386   */
387
388if(c_strcasecmp(utf8in,tmpout+strlen(IDNA_ACE_PREFIX))= 0)
389    {
390自由(utf8in);
391返回IDNA_ROUNDTRIP_VERIFY_ERROR;
392    }
393
394/*8.从步骤5返回保存的副本。
395   */
396
397自由(utf8in);
398返回IDNA_SUCCESS;
399}
400
401/**
402*idna_to_unicode _ 44i:
403*@in:带有unicode代码点的输入数组。
404*@inlen:带有unicode代码点的输入数组的长度。
405*@out:带有unicode代码点的输出数组。
406*@outlen:在输入时,具有unicode代码点的输出数组的最大大小,
407*退出时,带有unicode代码点的输出数组的实际大小。
408*@flags:#Idna_flags值,例如,%Idna_ALLOW_UNASSIGNED或
409*%IDNA_USE_STD3_ASCII_RULES。
410 *
411*ToUnicode操作采用一系列Unicode代码点
412*组成一个域标签并返回Unicode序列
413*代码点。如果输入序列是ACE形式的标签,则
414*结果是不在ACE中的等效国际化标签
415*形式,否则原始序列将原封不动地返回。
416 *
417*ToUnicode从未失败。如果任何步骤失败,则原始输入
418*序列在该步骤中立即返回。
419 *
420*Punycode解码器输出的代码点永远不会超过它
421*输入,但Nameprep可以,因此ToUnicode可以。请注意
422表示代码点序列所需的八位字节数
423*取决于使用的特定字符编码。
424 *
425*ToUnicode的输入是一系列代码点
426*AllowUnassigned标志和UseSTD3ASCIIRules标志。的输出
427*ToUnicode始终是一系列Unicode代码点。
428 *
429*返回值:返回#Idna_rc错误条件,但必须是
430*用于调试目的。输出缓冲区始终
431*保证根据
432*规范(sans-malloc引起的错误)。注意!这意味着
433*通常忽略此函数的返回代码,如下所示
434*检查它意味着打破标准。
435 */
436整数
437idna_to_unicode _44i(常量uint32_t*in,大小_入口,
438uint32_t*out,size_t*outlen,int标志)
439{
440整数rc;
441size_t outlensave=*outlen;
442字符*p;
443
444p=字符串rep_ucs4_to_utf8(in,(ssize_t)入口,NULL,NULL);
445如果(p==空)
446返回IDNA_MALLOC_ERROR;
447
448rc=idna_to_unicode内部(p,out,outlen,flags);
449如果(rc!=IDNA_SUCCESS)
450    {
451memcpy(输出、输入、大小(输入[0])*(输入<输出保存?
452入口:outlensave);
453*outlen=入口;
454    }
455
456/*p在idna_to_unicode_internal中被释放。  */
457
458返回rc;
459}
460
461/*处理多个标签的包装纸*/
462
463/**
464*idna_to_ascii_4z:
465*@input:以零结尾的输入Unicode字符串。
466*@output:指向新分配的输出字符串的指针。
467*@flags:#Idna_flags值,例如,%Idna_ALLOW_UNASSIGNED或
468*%IDNA_USE_STD3_ASCII_RULES。
469 *
470*将UCS-4域名转换为ASCII字符串。域名可以
471*包含多个由点分隔的标签。输出缓冲区必须
472*由调用方释放。
473 *
474*返回值:成功时返回%IDNA_SUCCESS,或返回错误代码。
475 **/
476整数
477idna_to_ascii_4z(常量uint32_t*输入,字符**输出,int标志)
478{
479const uint32_t*开始=输入;
480const uint32_t*结束;
481char buf[64];
482char*out=空;
483整数rc;
484
485/*1)当点用作标签分隔符时
486字符必须识别为点:U+002E(句号),
487U+3002(表意全停),U+FF0E(全停),
488U+FF61(半宽度象形全停)。 */
489
490if(输入[0]==0)
491{
492/*处理隐式零长度根标签。 */
493*输出=malloc(1);
494if(!*输出)
495返回IDNA_MALLOC_ERROR;
496strcpy(*输出,“”);
497返回IDNA_SUCCESS;
498    }
499
500if(DOTP(输入[0])&&输入[1]==0)
501    {
502/*处理显式零长度根标签。 */
503*输出=malloc(2);
504if(!*输出)
505返回IDNA_MALLOC_ERROR;
506strcpy(*输出,“.”);
507返回IDNA_SUCCESS;
508    }
509
510*输出=NULL;
511
512    {
513end=开始;
514
515for(;*end&&!DOTP(*end);结束++)
516        ;
517
518if(*end=='\0'&&start==end)
519        {
520/*处理显式零长度根标签。 */
521buf[0]=“\0”;
522        }
523其他
524        {
525rc=idna_to_ascii4i(开始,(size_t)(结束-开始),buf,标志);
526如果(rc!=IDNA_SUCCESS)
527            {
528自由(退出);
529返回rc;
530            }
531        }
532
533如果(out)
534        {
535size_t l=字符串(输出)+1+字符串(buf)+1;
536char*newp=重新分配(out,l);
537if(!newp)
538            {
539自由(退出);
540返回IDNA_MALLOC_ERROR;
541            }
542out=newp;
543strcat(out,“.”);
544strcat(out,buf);
545        }
546其他
547        {
548输出=strdup(buf);
549if(!out)
550返回IDNA_MALLOC_ERROR;
551        }
552
553开始=结束+1;
554    }
555while(*结束);
556
557*输出=输出;
558
559返回IDNA_SUCCESS;
560}
561
562/**
563*idna_to_ascii_8z:
564*@input:以零结尾的输入UTF-8字符串。
565*@output:指向新分配的输出字符串的指针。
566*@flags:#Idna_flags值,例如,%Idna_ALLOW_UNASSIGNED或
567*%IDNA_USE_STD3_ASCII_RULES。
568 *
569*将UTF-8域名转换为ASCII字符串。域名可以
570*包含多个由点分隔的标签。输出缓冲区必须
571*由调用者解除分配。
572 *
573*返回值:成功时返回%IDNA_SUCCESS,或返回错误代码。
574 **/
575整数
576idna_to_ascii8z(const char*输入,char**输出,int标志)
577{
578uint32_t*ucs4;
579size_t ucs4len;
580整数rc;
581
582ucs4=字符串rep_utf8_to_ucs4(输入,-1,&ucs4len);
583如果(!ucs4)
584返回IDNA_ICONV_ERROR;
585
586rc=idna_to_ascii4z(ucs4,输出,标志);
587
588自由(ucs4);
589
590返回rc;
591
592}
593
594/**
595*idna_to_ascii_lz:
596*@input:在当前语言环境中编码的以零结尾的输入字符串
597*字符集。
598*@output:指向新分配的输出字符串的指针。
599*@flags:#Idna_flags值,例如,%Idna_ALLOW_UNASSIGNED或
600*%IDNA_USE_STD3_ASCII_RULES。
601 *
602*将区域设置编码中的域名转换为ASCII字符串
603*域名可能包含多个标签,由点分隔。  The
604*输出缓冲区必须由调用方释放。
605 *
606*返回值:成功时返回%IDNA_SUCCESS,或返回错误代码。
607 **/
608整数
609idna_to_ascii_lz(const char*输入,char**输出,int标志)
610{
611字符*utf8;
612整数rc;
613
614utf8=字符串rep_locale_to_utf8(输入);
615如果(!utf8)
616返回IDNA_ICONV_ERROR;
617
618rc=idna_to_ascii8z(utf8,输出,标志);
619
620自由(utf8);
621
622返回rc;
623}
624
625/**
626*idna_to_unicode _4z4z:
627*@input:以零结尾的Unicode字符串。
628*@output:指向新分配的输出Unicode字符串的指针。
629*@flags:#Idna_flags值,例如%Idna_ALLOW_UNASSIGNED或
630*%IDNA_USE_STD3_ASCII_RULES。
631 *
632*将UCS-4格式的可能ACE编码域名转换为
633*UCS-4字符串。域名可能包含多个标签,
634*由点分隔。输出缓冲区必须由
635*来电者。
636 *
637*返回值:成功返回%IDNA_SUCCESS,或返回错误代码。
638 **/
639整数
640idna_to_unicode 4z4z(const uint32_t*输入,uint32-t**输出,int标志)
641{
642const uint32_t*开始=输入;
643const uint32_t*结束;
644uint32_t*buf;
645size_t buflen;
646uint32_t*out=空;
647size_t outlen=0;
648
649*输出=NULL;
650
651
652{
653end=开始;
654
655for(;*end&&!DOTP(*end);结束++)
656        ;
657
658buflen=(size_t)(结束-开始);
659buf=malloc(大小(buf[0])*(buflen+1));
660if(!buf)
661        {
662自由(退出);
663返回IDNA_MALLOC_ERROR;
664        }
665
666/*不要按照规范检查返回代码! */
667idna_to_unicode _44i(开始,(size_t)(结束-开始),
668buf,&buflen,flags);
669
670if(输出)
671        {
672uint32_t*newp=重新分配(out,
673大小(出[0])
674*(outlen+1+buflen+1);
675if(!newp)
676            {
677自由(buf);
678自由(退出);
679返回IDNA_MALLOC_ERROR;
680}
681out=newp;
682out[outlen++]=0x002E;       /* '.'(完全停止)*/
683memcpy(out+outlen,buf,sizeof(buf[0])*buflen);
684outlen+=buflen;
685out[outlen]=0x0;
686自由(buf);
687        }
688其他
689{
690输出=buf;
691outlen=buflen;
692out[outlen]=0x0;
693        }
694
695开始=结束+1;
696    }
697while(*结束);
698
699*输出=输出;
700
701返回IDNA_SUCCESS;
702}
703
704/**
705*idna_to_unicode _8z4z:
706*@input:以零结尾的UTF-8字符串。
707*@output:指向新分配的输出Unicode字符串的指针。
708*@flags:#Idna_flags值,例如,%Idna_ALLOW_UNASSIGNED或
709*%IDNA_USE_STD3_ASCII_RULES。
710 *
711*将UTF-8格式的可能ACE编码域名转换为
712*UCS-4字符串。域名可能包含多个标签,
713*由点分隔。输出缓冲区必须由
714*来电者。
715 *
716*返回值:成功时返回%IDNA_SUCCESS,或返回错误代码。
717 **/
718整数
719idna_to_unicode 8z4z(const字符*输入,uint32_t**输出,int标志)
720{
721uint32_t*ucs4;
722size_t ucs4len;
723整数rc;
724
725ucs4=字符串rep_utf8_to_ucs4(输入,-1,&ucs4len);
726如果(!ucs4)
727返回IDNA_ICONV_ERROR;
728
729rc=idna_to_unicode 4z4z(ucs4,输出,标志);
730自由(ucs4);
731
732返回rc;
733}
734
735/**
736*idna_to_unicode _8z8z:
737*@input:以零结尾的UTF-8字符串。
738*@output:指向新分配的输出UTF-8字符串的指针。
739*@flags:#Idna_flags值,例如,%Idna_ALLOW_UNASSIGNED或
740*%IDNA_USE_STD3_ASCII_RULES。
741 *
742*将UTF-8格式的可能ACE编码域名转换为
743*UTF-8字符串。域名可能包含多个标签,
744*由点分隔。输出缓冲区必须由
745*来电者。
746 *
747*返回值:成功时返回%IDNA_SUCCESS,或返回错误代码。
748 **/
749整数
750idna_to_unicode 8z8z(const char*输入,char**输出,int标志)
751{
752uint32_t*ucs4;
753整数rc;
754
755rc=idna_to_unicode 8z4z(输入,&ucs4,标志);
756如果(rc!=IDNA_SUCCESS)
757返回rc;
758
759*输出=字符串rep_ucs4_to_utf8(ucs4,-1,NULL,NULL);
760自由(ucs4);
761
762if(!*输出)
763返回IDNA_ICONV_ERROR;
764
765返回IDNA_SUCCESS;
766}
767
768/**
769*idna_to_unicode_8zlz:
770*@input:以零结尾的UTF-8字符串。
771*@output:指向编码在
772*当前区域设置的字符集。
773*@flags:#Idna_flags值,例如,%Idna_ALLOW_UNASSIGNED或
774*%IDNA_USE_STD3_ASCII_RULES。
775 *
776*将UTF-8格式的可能ACE编码域名转换为
777*在当前区域设置的字符集中编码的字符串。
778*名称可能包含多个标签,由点分隔。输出
779*缓冲区必须由调用方释放。
780 *
781*返回值:成功时返回%IDNA_SUCCESS,或返回错误代码。
782 **/
783整数
784idna_to_unicode 8zlz(const char*输入,char**输出,int标志)
785{
786字符*utf8;
787整数rc;
788
789rc=idna_to_unicode 8z8z(输入,&utf8,标志);
790如果(rc!=IDNA_SUCCESS)
791返回rc;
792
793*输出=字符串rep_utf8_to_locale(utf8);
794自由(utf8);
795
796if(!*输出)
797返回IDNA_ICONV_ERROR;
798
799返回IDNA_SUCCESS;
800}
801
802/**
803*idna_to_unicode _ lzlz:
804*@input:在当前语言环境中编码的以零结尾的字符串
805*字符集。
806*@output:指向编码在
807*当前区域设置的字符集。
808*@flags:#Idna_flags值,例如,%Idna_ALLOW_UNASSIGNED或
809*%IDNA_USE_STD3_ASCII_RULES。
810 *
811*转换可能使用区域设置字符的ACE编码域名
812*设置为在当前语言环境的字符集中编码的字符串。
813*域名可能包含多个标签,由点分隔。  The
814*输出缓冲区必须由调用方释放。
815 *
816*返回值:成功返回%IDNA_SUCCESS,或返回错误代码。
817 **/
818整数
819idna_to_unicode _lzlz(const char*输入,char**输出,int标志)
820{
821字符*utf8;
822整数rc;
823
824utf8=字符串rep_locale_to_utf8(输入);
825如果(!utf8)
826返回IDNA_ICONV_ERROR;
827
828rc=idna_to_unicode 8zlz(utf8,输出,标志);
829自由(utf8);
830
831返回rc;
832}
833
834/**
835*IDNA_ACE_PREFIX
836 *
837*IANA分配的用于IDNA的前缀。“xn--”
838 */
839
840/**
841*标识(_R):
842*@IDNA_SUCCESS:操作成功。此值保证为
843*始终为零,其余的只能保证保持不变
844*非零值,用于逻辑比较。
845*@IDNA_STRINGPREP_ERROR:字符串准备期间出错。
846*@IDNA_PUNYCODE_ERROR:PUNYCODE操作期间出错。
847*@IDNA_CONTAINS_NON_LDH:对于IDNA_USE_STD3_ASCII_RULES,表示
848*字符串包含非LDH ASCII字符。
849*@IDNA_CONTAINS_LDH:与@IDNA_CONTAINS-NON_LDH相同,以实现兼容性
850*早期版本中有打字错误。
851*@IDNA_CONTAINS_MINUS:对于IDNA_USE_STD3_ASCII_RULES,表示
852*字符串包含前导或尾随连字符-分钟(U+002D)。
853*@IDNA_INVALID_LENGTH:最终输出字符串不在
854*(含)1到63个字符。
855*@IDNA_NO_ACE_PREFIX:字符串不包含ACE前缀
856*(用于ToUnicode)。
857*@IDNA_ROUNDTRIP_VERIFY_ERROR:输出上的ToASCII操作
858*string不等于输入。
859*@IDNA_CONTAINS_ACE_PREFIX:输入包含ACE前缀(用于
860*ToASCII)。
861*@IDNA_ICONV_ERROR:字符编码转换错误。
862*@IDNA_MALLOC_ERROR:无法分配缓冲区(这通常是
863*致命错误)。
864*@IDNA_DLOPEN_ERROR:无法DLOPEN libcidn DSO(仅使用
865*libc内部)。
866 *
867*idna_to_ascii_4i()的枚举返回码,
868*idna_to_unicode_44i()函数(以及从这些函数派生的函数
869*功能)。保证值0始终与
870*成功。
871 */
872
873
874/**
875*Idna_flags(标识_标志):
876*@IDNA_ALLOW_UNASSIGNED:不要拒绝包含未分配的字符串
877*Unicode代码点。
878*@IDNA_USE_STD3_ASCII_RULES:根据STD3验证字符串
879*规则(即普通主机名规则)。
880 *
881*传递给idna_to_ascii_4i()、idna_toSunicode_44i()等的标志。
882 */