Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
ab9fe967
Commit
ab9fe967
authored
Mar 02, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Reimplement IdnToUnicode() using the normalization table and the ntdll helpers.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
01237d08
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
148 additions
and
175 deletions
+148
-175
locale.c
dlls/kernel32/locale.c
+4
-169
locale.c
dlls/kernel32/tests/locale.c
+13
-6
locale.c
dlls/ntdll/locale.c
+129
-0
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-0
winternl.h
include/winternl.h
+1
-0
No files found.
dlls/kernel32/locale.c
View file @
ab9fe967
...
...
@@ -544,28 +544,6 @@ INT WINAPI GetGeoInfoA(GEOID geoid, GEOTYPE geotype, LPSTR data, int data_len, L
}
enum
{
BASE
=
36
,
TMIN
=
1
,
TMAX
=
26
,
SKEW
=
38
,
DAMP
=
700
,
INIT_BIAS
=
72
,
INIT_N
=
128
};
static
inline
INT
adapt
(
INT
delta
,
INT
numpoints
,
BOOL
firsttime
)
{
INT
k
;
delta
/=
(
firsttime
?
DAMP
:
2
);
delta
+=
delta
/
numpoints
;
for
(
k
=
0
;
delta
>
((
BASE
-
TMIN
)
*
TMAX
)
/
2
;
k
+=
BASE
)
delta
/=
BASE
-
TMIN
;
return
k
+
((
BASE
-
TMIN
+
1
)
*
delta
)
/
(
delta
+
SKEW
);
}
/******************************************************************************
* IdnToAscii (KERNEL32.@)
*/
...
...
@@ -589,154 +567,11 @@ INT WINAPI IdnToNameprepUnicode( DWORD flags, const WCHAR *src, INT srclen, WCHA
/******************************************************************************
* IdnToUnicode (KERNEL32.@)
*/
INT
WINAPI
IdnToUnicode
(
DWORD
dwFlags
,
LPCWSTR
lpASCIICharStr
,
INT
cchASCIIChar
,
LPWSTR
lpUnicodeCharStr
,
INT
cchUnicodeChar
)
INT
WINAPI
IdnToUnicode
(
DWORD
flags
,
const
WCHAR
*
src
,
INT
srclen
,
WCHAR
*
dst
,
INT
dstlen
)
{
INT
i
,
label_start
,
label_end
,
out_label
,
out
=
0
;
WCHAR
ch
;
TRACE
(
"%x %p %d %p %d
\n
"
,
dwFlags
,
lpASCIICharStr
,
cchASCIIChar
,
lpUnicodeCharStr
,
cchUnicodeChar
);
for
(
label_start
=
0
;
label_start
<
cchASCIIChar
;)
{
INT
n
=
INIT_N
,
pos
=
0
,
old_pos
,
w
,
k
,
bias
=
INIT_BIAS
,
delim
=
0
,
digit
,
t
;
out_label
=
out
;
for
(
i
=
label_start
;
i
<
cchASCIIChar
;
i
++
)
{
ch
=
lpASCIICharStr
[
i
];
if
(
ch
>
0x7f
||
(
i
!=
cchASCIIChar
-
1
&&
!
ch
))
{
SetLastError
(
ERROR_INVALID_NAME
);
return
0
;
}
if
(
!
ch
||
ch
==
'.'
)
break
;
if
(
ch
==
'-'
)
delim
=
i
;
if
((
dwFlags
&
IDN_USE_STD3_ASCII_RULES
)
==
0
)
continue
;
if
((
ch
>=
'a'
&&
ch
<=
'z'
)
||
(
ch
>=
'A'
&&
ch
<=
'Z'
)
||
(
ch
>=
'0'
&&
ch
<=
'9'
)
||
ch
==
'-'
)
continue
;
SetLastError
(
ERROR_INVALID_NAME
);
return
0
;
}
label_end
=
i
;
/* last label may be empty */
if
(
label_start
==
label_end
&&
ch
)
{
SetLastError
(
ERROR_INVALID_NAME
);
return
0
;
}
if
((
dwFlags
&
IDN_USE_STD3_ASCII_RULES
)
&&
(
lpASCIICharStr
[
label_start
]
==
'-'
||
lpASCIICharStr
[
label_end
-
1
]
==
'-'
))
{
SetLastError
(
ERROR_INVALID_NAME
);
return
0
;
}
if
(
label_end
-
label_start
>
63
)
{
SetLastError
(
ERROR_INVALID_NAME
);
return
0
;
}
if
(
label_end
-
label_start
<
4
||
tolowerW
(
lpASCIICharStr
[
label_start
])
!=
'x'
||
tolowerW
(
lpASCIICharStr
[
label_start
+
1
])
!=
'n'
||
lpASCIICharStr
[
label_start
+
2
]
!=
'-'
||
lpASCIICharStr
[
label_start
+
3
]
!=
'-'
)
{
if
(
label_end
<
cchASCIIChar
)
label_end
++
;
if
(
!
lpUnicodeCharStr
)
{
out
+=
label_end
-
label_start
;
}
else
if
(
out
+
label_end
-
label_start
<=
cchUnicodeChar
)
{
memcpy
(
lpUnicodeCharStr
+
out
,
lpASCIICharStr
+
label_start
,
(
label_end
-
label_start
)
*
sizeof
(
WCHAR
));
out
+=
label_end
-
label_start
;
}
else
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
return
0
;
}
label_start
=
label_end
;
continue
;
}
if
(
delim
==
label_start
+
3
)
delim
++
;
if
(
!
lpUnicodeCharStr
)
{
out
+=
delim
-
label_start
-
4
;
}
else
if
(
out
+
delim
-
label_start
-
4
<=
cchUnicodeChar
)
{
memcpy
(
lpUnicodeCharStr
+
out
,
lpASCIICharStr
+
label_start
+
4
,
(
delim
-
label_start
-
4
)
*
sizeof
(
WCHAR
));
out
+=
delim
-
label_start
-
4
;
}
else
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
return
0
;
}
if
(
out
!=
out_label
)
delim
++
;
for
(
i
=
delim
;
i
<
label_end
;)
{
old_pos
=
pos
;
w
=
1
;
for
(
k
=
BASE
;
;
k
+=
BASE
)
{
ch
=
i
<
label_end
?
tolowerW
(
lpASCIICharStr
[
i
++
])
:
0
;
if
((
ch
<
'a'
||
ch
>
'z'
)
&&
(
ch
<
'0'
||
ch
>
'9'
))
{
SetLastError
(
ERROR_INVALID_NAME
);
return
0
;
}
digit
=
ch
<=
'9'
?
ch
-
'0'
+
'z'
-
'a'
+
1
:
ch
-
'a'
;
pos
+=
digit
*
w
;
t
=
k
<=
bias
?
TMIN
:
k
>=
bias
+
TMAX
?
TMAX
:
k
-
bias
;
if
(
digit
<
t
)
break
;
w
*=
BASE
-
t
;
}
bias
=
adapt
(
pos
-
old_pos
,
out
-
out_label
+
1
,
old_pos
==
0
);
n
+=
pos
/
(
out
-
out_label
+
1
);
pos
%=
out
-
out_label
+
1
;
if
((
dwFlags
&
IDN_ALLOW_UNASSIGNED
)
==
0
&&
get_table_entry
(
nameprep_char_type
,
n
)
==
1
/*UNASSIGNED*/
)
{
SetLastError
(
ERROR_INVALID_NAME
);
return
0
;
}
if
(
!
lpUnicodeCharStr
)
{
out
++
;
}
else
if
(
out
+
1
<=
cchASCIIChar
)
{
memmove
(
lpUnicodeCharStr
+
out_label
+
pos
+
1
,
lpUnicodeCharStr
+
out_label
+
pos
,
(
out
-
out_label
-
pos
)
*
sizeof
(
WCHAR
));
lpUnicodeCharStr
[
out_label
+
pos
]
=
n
;
out
++
;
}
else
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
return
0
;
}
pos
++
;
}
if
(
out
-
out_label
>
63
)
{
SetLastError
(
ERROR_INVALID_NAME
);
return
0
;
}
if
(
label_end
<
cchASCIIChar
)
{
if
(
!
lpUnicodeCharStr
)
{
out
++
;
}
else
if
(
out
+
1
<=
cchUnicodeChar
)
{
lpUnicodeCharStr
[
out
++
]
=
lpASCIICharStr
[
label_end
];
}
else
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
return
0
;
}
}
label_start
=
label_end
+
1
;
}
return
out
;
NTSTATUS
status
=
RtlIdnToUnicode
(
flags
,
src
,
srclen
,
dst
,
&
dstlen
);
if
(
!
set_ntstatus
(
status
))
return
0
;
return
dstlen
;
}
...
...
dlls/kernel32/tests/locale.c
View file @
ab9fe967
...
...
@@ -4600,10 +4600,13 @@ static void test_IdnToUnicode(void)
/* 5 */
{
64
,
L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
,
0
,
0
},
{
8
,
L"xn--7va"
,
IDN_ALLOW_UNASSIGNED
,
2
,
2
,
L"
\x380
"
},
{
8
,
L"xn--7va"
,
0
,
0
,
0
,
L"
\x380
"
},
{
-
1
,
L"xn----bm3an932a1l5d.xn--xvj"
,
0
,
8
,
0
,
L"
\xd803\xde78\x46b5
-
\xa861
.
\x2e87
"
},
{
-
1
,
L"xn--z123456789012345678901234567890123456789012345678901234-9te"
,
0
,
57
,
57
,
L"
\xe4
z123456789012345678901234567890123456789012345678901234"
},
/* 10 */
{
-
1
,
L"foo.bar"
,
0
,
8
,
8
,
L"foo.bar"
},
{
-
1
,
L"d.xn----dha"
,
0
,
5
,
5
,
L"d.
\x00fc
-"
},
};
WCHAR
buf
[
1024
];
...
...
@@ -4612,13 +4615,11 @@ static void test_IdnToUnicode(void)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
test_data
);
i
++
)
{
ret
=
pIdnToUnicode
(
test_data
[
i
].
flags
,
test_data
[
i
].
in
,
test_data
[
i
].
in_len
,
NULL
,
0
);
todo_wine_if
(
i
>
6
)
ok
(
ret
==
test_data
[
i
].
ret
||
broken
(
ret
==
test_data
[
i
].
broken_ret
),
"%d: ret = %d
\n
"
,
i
,
ret
);
SetLastError
(
0xdeadbeef
);
ret
=
pIdnToUnicode
(
test_data
[
i
].
flags
,
test_data
[
i
].
in
,
test_data
[
i
].
in_len
,
buf
,
ARRAY_SIZE
(
buf
));
err
=
GetLastError
();
todo_wine_if
(
i
>
6
)
ok
(
ret
==
test_data
[
i
].
ret
||
broken
(
ret
==
test_data
[
i
].
broken_ret
),
"%d: ret = %d
\n
"
,
i
,
ret
);
ok
(
err
==
ret
?
0xdeadbeef
:
ERROR_INVALID_NAME
,
"%d: err = %d
\n
"
,
i
,
err
);
ok
(
!
wcsncmp
(
test_data
[
i
].
out
,
buf
,
ret
),
"%d: buf = %s
\n
"
,
i
,
wine_dbgstr_wn
(
buf
,
ret
));
...
...
@@ -4632,8 +4633,8 @@ static BOOL is_idn_error( const WCHAR *str )
for
(
p
=
wcstok
(
err
,
L" []"
);
p
;
p
=
wcstok
(
NULL
,
L" []"
)
)
{
if
(
*
p
==
'B'
||
!
wcscmp
(
p
,
L"V8"
))
continue
;
/* BiDi */
if
(
!
wcscmp
(
p
,
L"V2"
)
||
!
wcscmp
(
p
,
L"V3"
)
)
continue
;
/* CheckHyphens */
if
(
!
wcscmp
(
p
,
L"V
7"
))
continue
;
/* CheckJoiner
s */
if
(
!
wcscmp
(
p
,
L"V2"
))
continue
;
/* CheckHyphens */
if
(
!
wcscmp
(
p
,
L"V
5"
))
continue
;
/* Combining mark
s */
return
TRUE
;
}
return
FALSE
;
...
...
@@ -4705,7 +4706,7 @@ static void test_Idn(void)
error
=
columns
[
2
];
SetLastError
(
0xdeadbeef
);
memset
(
dst
,
0xcc
,
sizeof
(
dst
)
);
ret
=
pIdnToUnicode
(
0
,
columns
[
0
],
-
1
,
dst
,
ARRAY_SIZE
(
dst
)
);
ret
=
pIdnToUnicode
(
IDN_USE_STD3_ASCII_RULES
,
columns
[
0
],
-
1
,
dst
,
ARRAY_SIZE
(
dst
)
);
for
(
i
=
0
;
columns
[
0
][
i
];
i
++
)
if
(
columns
[
0
][
i
]
>
0x7f
)
break
;
if
(
columns
[
0
][
i
])
{
...
...
@@ -4713,10 +4714,16 @@ static void test_Idn(void)
}
else
if
(
!
is_idn_error
(
error
))
{
ok
(
ret
,
"line %u: toUnicode failed for %s
\n
"
,
line
,
debugstr_w
(
columns
[
0
])
);
ok
(
ret
,
"line %u: toUnicode failed for %s expected %s
\n
"
,
line
,
debugstr_w
(
columns
[
0
]),
debugstr_w
(
expect
)
);
if
(
ret
)
ok
(
!
wcscmp
(
dst
,
expect
),
"line %u: got %s expected %s
\n
"
,
line
,
debugstr_w
(
dst
),
debugstr_w
(
expect
)
);
}
else
{
ok
(
!
ret
,
"line %u: toUnicode didn't fail for %s got %s expected error %s
\n
"
,
line
,
debugstr_w
(
columns
[
0
]),
debugstr_w
(
dst
),
debugstr_w
(
error
)
);
}
}
fclose
(
f
);
}
...
...
dlls/ntdll/locale.c
View file @
ab9fe967
...
...
@@ -2238,3 +2238,132 @@ NTSTATUS WINAPI RtlIdnToNameprepUnicode( DWORD flags, const WCHAR *src, INT srcl
*
dstlen
=
buflen
;
return
status
;
}
/******************************************************************************
* RtlIdnToUnicode (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlIdnToUnicode
(
DWORD
flags
,
const
WCHAR
*
src
,
INT
srclen
,
WCHAR
*
dst
,
INT
*
dstlen
)
{
const
struct
norm_table
*
info
;
int
i
,
buflen
,
start
,
end
,
out_label
,
out
=
0
;
NTSTATUS
status
;
UINT
buffer
[
64
];
WCHAR
ch
;
if
(
!
src
||
srclen
<
-
1
)
return
STATUS_INVALID_PARAMETER
;
if
(
srclen
==
-
1
)
srclen
=
strlenW
(
src
)
+
1
;
TRACE
(
"%x %s %p %d
\n
"
,
flags
,
debugstr_wn
(
src
,
srclen
),
dst
,
*
dstlen
);
if
((
status
=
load_norm_table
(
13
,
&
info
)))
return
status
;
for
(
start
=
0
;
start
<
srclen
;
)
{
int
n
=
0x80
,
bias
=
72
,
pos
=
0
,
old_pos
,
w
,
k
,
t
,
delim
=
0
,
digit
,
delta
;
out_label
=
out
;
for
(
i
=
start
;
i
<
srclen
;
i
++
)
{
ch
=
src
[
i
];
if
(
ch
>
0x7f
||
(
i
!=
srclen
-
1
&&
!
ch
))
return
STATUS_INVALID_IDN_NORMALIZATION
;
if
(
!
ch
||
ch
==
'.'
)
break
;
if
(
ch
==
'-'
)
delim
=
i
;
if
(
!
(
flags
&
IDN_USE_STD3_ASCII_RULES
))
continue
;
if
((
ch
>=
'a'
&&
ch
<=
'z'
)
||
(
ch
>=
'A'
&&
ch
<=
'Z'
)
||
(
ch
>=
'0'
&&
ch
<=
'9'
)
||
ch
==
'-'
)
continue
;
return
STATUS_INVALID_IDN_NORMALIZATION
;
}
end
=
i
;
/* last label may be empty */
if
(
start
==
end
&&
ch
)
return
STATUS_INVALID_IDN_NORMALIZATION
;
if
(
end
-
start
<
4
||
(
src
[
start
]
!=
'x'
&&
src
[
start
]
!=
'X'
)
||
(
src
[
start
+
1
]
!=
'n'
&&
src
[
start
+
1
]
!=
'N'
)
||
src
[
start
+
2
]
!=
'-'
||
src
[
start
+
3
]
!=
'-'
)
{
if
(
end
-
start
>
63
)
return
STATUS_INVALID_IDN_NORMALIZATION
;
if
((
flags
&
IDN_USE_STD3_ASCII_RULES
)
&&
(
src
[
start
]
==
'-'
||
src
[
end
-
1
]
==
'-'
))
return
STATUS_INVALID_IDN_NORMALIZATION
;
if
(
end
<
srclen
)
end
++
;
if
(
*
dstlen
)
{
if
(
out
+
end
-
start
<=
*
dstlen
)
memcpy
(
dst
+
out
,
src
+
start
,
(
end
-
start
)
*
sizeof
(
WCHAR
));
else
return
STATUS_BUFFER_TOO_SMALL
;
}
out
+=
end
-
start
;
start
=
end
;
continue
;
}
if
(
delim
==
start
+
3
)
delim
++
;
buflen
=
0
;
for
(
i
=
start
+
4
;
i
<
delim
&&
buflen
<
ARRAY_SIZE
(
buffer
);
i
++
)
buffer
[
buflen
++
]
=
src
[
i
];
if
(
buflen
)
i
++
;
while
(
i
<
end
)
{
old_pos
=
pos
;
w
=
1
;
for
(
k
=
BASE
;
;
k
+=
BASE
)
{
if
(
i
>=
end
)
return
STATUS_INVALID_IDN_NORMALIZATION
;
ch
=
src
[
i
++
];
if
(
ch
>=
'a'
&&
ch
<=
'z'
)
digit
=
ch
-
'a'
;
else
if
(
ch
>=
'A'
&&
ch
<=
'Z'
)
digit
=
ch
-
'A'
;
else
if
(
ch
>=
'0'
&&
ch
<=
'9'
)
digit
=
ch
-
'0'
+
26
;
else
return
STATUS_INVALID_IDN_NORMALIZATION
;
pos
+=
digit
*
w
;
t
=
k
<=
bias
?
TMIN
:
k
>=
bias
+
TMAX
?
TMAX
:
k
-
bias
;
if
(
digit
<
t
)
break
;
w
*=
BASE
-
t
;
}
delta
=
(
pos
-
old_pos
)
/
(
!
old_pos
?
DAMP
:
2
);
delta
+=
delta
/
(
buflen
+
1
);
for
(
k
=
0
;
delta
>
((
BASE
-
TMIN
)
*
TMAX
)
/
2
;
k
+=
BASE
)
delta
/=
BASE
-
TMIN
;
bias
=
k
+
((
BASE
-
TMIN
+
1
)
*
delta
)
/
(
delta
+
SKEW
);
n
+=
pos
/
(
buflen
+
1
);
pos
%=
buflen
+
1
;
if
(
buflen
>=
ARRAY_SIZE
(
buffer
)
-
1
)
return
STATUS_INVALID_IDN_NORMALIZATION
;
memmove
(
buffer
+
pos
+
1
,
buffer
+
pos
,
(
buflen
-
pos
)
*
sizeof
(
*
buffer
)
);
buffer
[
pos
++
]
=
n
;
buflen
++
;
}
if
(
check_invalid_chars
(
info
,
flags
,
buffer
,
buflen
))
return
STATUS_INVALID_IDN_NORMALIZATION
;
for
(
i
=
0
;
i
<
buflen
;
i
++
)
{
int
len
=
1
+
(
buffer
[
i
]
>=
0x10000
);
if
(
*
dstlen
)
{
if
(
out
+
len
<=
*
dstlen
)
put_utf16
(
dst
+
out
,
buffer
[
i
]
);
else
return
STATUS_BUFFER_TOO_SMALL
;
}
out
+=
len
;
}
if
(
out
-
out_label
>
63
)
return
STATUS_INVALID_IDN_NORMALIZATION
;
if
(
end
<
srclen
)
{
if
(
*
dstlen
)
{
if
(
out
+
1
<=
*
dstlen
)
dst
[
out
]
=
src
[
end
];
else
return
STATUS_BUFFER_TOO_SMALL
;
}
out
++
;
}
start
=
end
+
1
;
}
*
dstlen
=
out
;
return
STATUS_SUCCESS
;
}
dlls/ntdll/ntdll.spec
View file @
ab9fe967
...
...
@@ -724,6 +724,7 @@
@ stdcall RtlIdentifierAuthoritySid(ptr)
@ stdcall RtlIdnToAscii(long wstr long ptr ptr)
@ stdcall RtlIdnToNameprepUnicode(long wstr long ptr ptr)
@ stdcall RtlIdnToUnicode(long wstr long ptr ptr)
@ stdcall RtlImageDirectoryEntryToData(long long long ptr)
@ stdcall RtlImageNtHeader(long)
@ stdcall RtlImageRvaToSection(ptr long long)
...
...
include/winternl.h
View file @
ab9fe967
...
...
@@ -2799,6 +2799,7 @@ NTSYSAPI NTSTATUS WINAPI RtlGUIDFromString(PUNICODE_STRING,GUID*);
NTSYSAPI
PSID_IDENTIFIER_AUTHORITY
WINAPI
RtlIdentifierAuthoritySid
(
PSID
);
NTSYSAPI
NTSTATUS
WINAPI
RtlIdnToAscii
(
DWORD
,
const
WCHAR
*
,
INT
,
WCHAR
*
,
INT
*
);
NTSYSAPI
NTSTATUS
WINAPI
RtlIdnToNameprepUnicode
(
DWORD
,
const
WCHAR
*
,
INT
,
WCHAR
*
,
INT
*
);
NTSYSAPI
NTSTATUS
WINAPI
RtlIdnToUnicode
(
DWORD
,
const
WCHAR
*
,
INT
,
WCHAR
*
,
INT
*
);
NTSYSAPI
PVOID
WINAPI
RtlImageDirectoryEntryToData
(
HMODULE
,
BOOL
,
WORD
,
ULONG
*
);
NTSYSAPI
PIMAGE_NT_HEADERS
WINAPI
RtlImageNtHeader
(
HMODULE
);
NTSYSAPI
PIMAGE_SECTION_HEADER
WINAPI
RtlImageRvaToSection
(
const
IMAGE_NT_HEADERS
*
,
HMODULE
,
DWORD
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment