ReactOS  0.4.13-dev-39-g8b6696f
IdnToUnicode.c
Go to the documentation of this file.
1 
2 #define WIN32_NO_STATUS
3 #include <wine/unicode.h>
4 
5 #define NDEBUG
6 #include <debug.h>
7 
8 /* Taken from Wine kernel32/locale.c */
9 
10 enum {
11  BASE = 36,
12  TMIN = 1,
13  TMAX = 26,
14  SKEW = 38,
15  DAMP = 700,
16  INIT_BIAS = 72,
17  INIT_N = 128
18 };
19 
20 static inline INT adapt(INT delta, INT numpoints, BOOL firsttime)
21 {
22  INT k;
23 
24  delta /= (firsttime ? DAMP : 2);
25  delta += delta/numpoints;
26 
27  for(k=0; delta>((BASE-TMIN)*TMAX)/2; k+=BASE)
28  delta /= BASE-TMIN;
29  return k+((BASE-TMIN+1)*delta)/(delta+SKEW);
30 }
31 
32 static inline unsigned short get_table_entry( const unsigned short *table, WCHAR ch )
33 {
34  return table[table[table[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0xf)];
35 }
36 
37 INT WINAPI IdnToUnicode(DWORD dwFlags, LPCWSTR lpASCIICharStr, INT cchASCIIChar,
38  LPWSTR lpUnicodeCharStr, INT cchUnicodeChar)
39 {
40  extern const unsigned short nameprep_char_type[];
41 
42  INT i, label_start, label_end, out_label, out = 0;
43  WCHAR ch;
44 
45  DPRINT("%x %p %d %p %d\n", dwFlags, lpASCIICharStr, cchASCIIChar,
46  lpUnicodeCharStr, cchUnicodeChar);
47 
48  for(label_start=0; label_start<cchASCIIChar;) {
49  INT n = INIT_N, pos = 0, old_pos, w, k, bias = INIT_BIAS, delim=0, digit, t;
50 
51  out_label = out;
52  for(i=label_start; i<cchASCIIChar; i++) {
53  ch = lpASCIICharStr[i];
54 
55  if(ch>0x7f || (i!=cchASCIIChar-1 && !ch)) {
57  return 0;
58  }
59 
60  if(!ch || ch=='.')
61  break;
62  if(ch == '-')
63  delim = i;
64 
65  if((dwFlags&IDN_USE_STD3_ASCII_RULES) == 0)
66  continue;
67  if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z')
68  || (ch>='0' && ch<='9') || ch=='-')
69  continue;
70 
72  return 0;
73  }
74  label_end = i;
75  /* last label may be empty */
76  if(label_start==label_end && ch) {
78  return 0;
79  }
80 
81  if((dwFlags&IDN_USE_STD3_ASCII_RULES) && (lpASCIICharStr[label_start]=='-' ||
82  lpASCIICharStr[label_end-1]=='-')) {
84  return 0;
85  }
86  if(label_end-label_start > 63) {
88  return 0;
89  }
90 
91  if(label_end-label_start<4 ||
92  tolowerW(lpASCIICharStr[label_start])!='x' ||
93  tolowerW(lpASCIICharStr[label_start+1])!='n' ||
94  lpASCIICharStr[label_start+2]!='-' || lpASCIICharStr[label_start+3]!='-') {
95  if(label_end < cchASCIIChar)
96  label_end++;
97 
98  if(!lpUnicodeCharStr) {
99  out += label_end-label_start;
100  }else if(out+label_end-label_start <= cchUnicodeChar) {
101  memcpy(lpUnicodeCharStr+out, lpASCIICharStr+label_start,
102  (label_end-label_start)*sizeof(WCHAR));
103  out += label_end-label_start;
104  }else {
106  return 0;
107  }
108 
109  label_start = label_end;
110  continue;
111  }
112 
113  if(delim == label_start+3)
114  delim++;
115  if(!lpUnicodeCharStr) {
116  out += delim-label_start-4;
117  }else if(out+delim-label_start-4 <= cchUnicodeChar) {
118  memcpy(lpUnicodeCharStr+out, lpASCIICharStr+label_start+4,
119  (delim-label_start-4)*sizeof(WCHAR));
120  out += delim-label_start-4;
121  }else {
123  return 0;
124  }
125  if(out != out_label)
126  delim++;
127 
128  for(i=delim; i<label_end;) {
129  old_pos = pos;
130  w = 1;
131  for(k=BASE; ; k+=BASE) {
132  ch = i<label_end ? tolowerW(lpASCIICharStr[i++]) : 0;
133  if((ch<'a' || ch>'z') && (ch<'0' || ch>'9')) {
135  return 0;
136  }
137  digit = ch<='9' ? ch-'0'+'z'-'a'+1 : ch-'a';
138  pos += digit*w;
139  t = k<=bias ? TMIN : k>=bias+TMAX ? TMAX : k-bias;
140  if(digit < t)
141  break;
142  w *= BASE-t;
143  }
144  bias = adapt(pos-old_pos, out-out_label+1, old_pos==0);
145  n += pos/(out-out_label+1);
146  pos %= out-out_label+1;
147 
148  if((dwFlags&IDN_ALLOW_UNASSIGNED)==0 &&
149  get_table_entry(nameprep_char_type, n)==1/*UNASSIGNED*/) {
151  return 0;
152  }
153  if(!lpUnicodeCharStr) {
154  out++;
155  }else if(out+1 <= cchASCIIChar) {
156  memmove(lpUnicodeCharStr+out_label+pos+1,
157  lpUnicodeCharStr+out_label+pos,
158  (out-out_label-pos)*sizeof(WCHAR));
159  lpUnicodeCharStr[out_label+pos] = n;
160  out++;
161  }else {
163  return 0;
164  }
165  pos++;
166  }
167 
168  if(out-out_label > 63) {
170  return 0;
171  }
172 
173  if(label_end < cchASCIIChar) {
174  if(!lpUnicodeCharStr) {
175  out++;
176  }else if(out+1 <= cchUnicodeChar) {
177  lpUnicodeCharStr[out++] = lpASCIICharStr[label_end];
178  }else {
180  return 0;
181  }
182  }
183  label_start = label_end+1;
184  }
185 
186  return out;
187 }
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
GLdouble n
Definition: glext.h:7729
GLdouble GLdouble t
Definition: gl.h:2047
static INT adapt(INT delta, INT numpoints, BOOL firsttime)
Definition: IdnToUnicode.c:20
const unsigned short nameprep_char_type[4432]
Definition: nameprep.c:5
int32_t INT
Definition: typedefs.h:56
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
INT WINAPI IdnToUnicode(DWORD dwFlags, LPCWSTR lpASCIICharStr, INT cchASCIIChar, LPWSTR lpUnicodeCharStr, INT cchUnicodeChar)
Definition: IdnToUnicode.c:37
GLfloat bias
Definition: glext.h:7909
void DPRINT(...)
Definition: polytest.cpp:61
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WINAPI
Definition: msvc.h:8
static FILE * out
Definition: regtests2xml.c:44
WINE_UNICODE_INLINE WCHAR tolowerW(WCHAR ch)
Definition: unicode.h:135
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:409
static unsigned short get_table_entry(const unsigned short *table, WCHAR ch)
Definition: IdnToUnicode.c:32
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ERROR_INVALID_NAME
Definition: compat.h:93
WCHAR * LPWSTR
Definition: xmlstorage.h:184
int k
Definition: mpi.c:3369
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10