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
12717397
Commit
12717397
authored
Jan 07, 2008
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Accept utf-8 data as input in registry files.
parent
98c13331
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
137 additions
and
77 deletions
+137
-77
registry.c
server/registry.c
+12
-75
unicode.c
server/unicode.c
+123
-1
unicode.h
server/unicode.h
+2
-1
No files found.
server/registry.c
View file @
12717397
...
...
@@ -168,12 +168,6 @@ static const struct object_ops key_ops =
* - REG_EXPAND_SZ and REG_MULTI_SZ are saved as strings instead of hex
*/
static
inline
char
to_hex
(
char
ch
)
{
if
(
isdigit
(
ch
))
return
ch
-
'0'
;
return
tolower
(
ch
)
-
'a'
+
10
;
}
/* dump the full path of a key */
static
void
dump_path
(
const
struct
key
*
key
,
const
struct
key
*
base
,
FILE
*
f
)
{
...
...
@@ -1076,65 +1070,6 @@ static void file_read_error( const char *err, struct file_load_info *info )
fprintf
(
stderr
,
"<fd>:%d: %s '%s'
\n
"
,
info
->
line
,
err
,
info
->
buffer
);
}
/* parse an escaped string back into Unicode */
/* return the number of chars read from the input, or -1 on output overflow */
static
int
parse_strW
(
WCHAR
*
dest
,
data_size_t
*
len
,
const
char
*
src
,
char
endchar
)
{
data_size_t
count
=
sizeof
(
WCHAR
);
/* for terminating null */
const
char
*
p
=
src
;
while
(
*
p
&&
*
p
!=
endchar
)
{
if
(
*
p
!=
'\\'
)
*
dest
=
(
WCHAR
)
*
p
++
;
else
{
p
++
;
switch
(
*
p
)
{
case
'a'
:
*
dest
=
'\a'
;
p
++
;
break
;
case
'b'
:
*
dest
=
'\b'
;
p
++
;
break
;
case
'e'
:
*
dest
=
'\e'
;
p
++
;
break
;
case
'f'
:
*
dest
=
'\f'
;
p
++
;
break
;
case
'n'
:
*
dest
=
'\n'
;
p
++
;
break
;
case
'r'
:
*
dest
=
'\r'
;
p
++
;
break
;
case
't'
:
*
dest
=
'\t'
;
p
++
;
break
;
case
'v'
:
*
dest
=
'\v'
;
p
++
;
break
;
case
'x'
:
/* hex escape */
p
++
;
if
(
!
isxdigit
(
*
p
))
*
dest
=
'x'
;
else
{
*
dest
=
to_hex
(
*
p
++
);
if
(
isxdigit
(
*
p
))
*
dest
=
(
*
dest
*
16
)
+
to_hex
(
*
p
++
);
if
(
isxdigit
(
*
p
))
*
dest
=
(
*
dest
*
16
)
+
to_hex
(
*
p
++
);
if
(
isxdigit
(
*
p
))
*
dest
=
(
*
dest
*
16
)
+
to_hex
(
*
p
++
);
}
break
;
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
/* octal escape */
*
dest
=
*
p
++
-
'0'
;
if
(
*
p
>=
'0'
&&
*
p
<=
'7'
)
*
dest
=
(
*
dest
*
8
)
+
(
*
p
++
-
'0'
);
if
(
*
p
>=
'0'
&&
*
p
<=
'7'
)
*
dest
=
(
*
dest
*
8
)
+
(
*
p
++
-
'0'
);
break
;
default:
*
dest
=
(
WCHAR
)
*
p
++
;
break
;
}
}
if
((
count
+=
sizeof
(
WCHAR
))
>
*
len
)
return
-
1
;
/* dest buffer overflow */
dest
++
;
}
*
dest
=
0
;
if
(
!*
p
)
return
-
1
;
/* delimiter not found */
*
len
=
count
;
return
p
+
1
-
src
;
}
/* convert a data type tag to a value type */
static
int
get_data_type
(
const
char
*
buffer
,
int
*
type
,
int
*
parse_type
)
{
...
...
@@ -1176,10 +1111,11 @@ static struct key *load_key( struct key *base, const char *buffer, int flags,
WCHAR
*
p
;
struct
unicode_str
name
;
int
res
,
modif
;
data_size_t
len
=
strlen
(
buffer
)
*
sizeof
(
WCHAR
)
;
data_size_t
len
;
if
(
!
get_file_tmp_space
(
info
,
len
))
return
NULL
;
if
(
!
get_file_tmp_space
(
info
,
strlen
(
buffer
)
*
sizeof
(
WCHAR
)
))
return
NULL
;
len
=
info
->
tmplen
;
if
((
res
=
parse_strW
(
info
->
tmp
,
&
len
,
buffer
,
']'
))
==
-
1
)
{
file_read_error
(
"Malformed key"
,
info
);
...
...
@@ -1233,10 +1169,10 @@ static struct key_value *parse_value_name( struct key *key, const char *buffer,
struct
key_value
*
value
;
struct
unicode_str
name
;
int
index
;
data_size_t
maxlen
=
strlen
(
buffer
)
*
sizeof
(
WCHAR
);
if
(
!
get_file_tmp_space
(
info
,
maxlen
))
return
NULL
;
if
(
!
get_file_tmp_space
(
info
,
strlen
(
buffer
)
*
sizeof
(
WCHAR
)
))
return
NULL
;
name
.
str
=
info
->
tmp
;
name
.
len
=
info
->
tmplen
;
if
(
buffer
[
0
]
==
'@'
)
{
name
.
len
=
0
;
...
...
@@ -1244,10 +1180,10 @@ static struct key_value *parse_value_name( struct key *key, const char *buffer,
}
else
{
int
r
=
parse_strW
(
info
->
tmp
,
&
max
len
,
buffer
+
1
,
'\"'
);
int
r
=
parse_strW
(
info
->
tmp
,
&
name
.
len
,
buffer
+
1
,
'\"'
);
if
(
r
==
-
1
)
goto
error
;
*
len
=
r
+
1
;
/* for initial quote */
name
.
len
=
maxlen
-
sizeof
(
WCHAR
);
name
.
len
-=
sizeof
(
WCHAR
);
/* terminating null */
}
while
(
isspace
(
buffer
[
*
len
]))
(
*
len
)
++
;
if
(
buffer
[
*
len
]
!=
'='
)
goto
error
;
...
...
@@ -1277,8 +1213,8 @@ static int load_value( struct key *key, const char *buffer, struct file_load_inf
switch
(
parse_type
)
{
case
REG_SZ
:
len
=
strlen
(
buffer
)
*
sizeof
(
WCHAR
)
;
if
(
!
get_file_tmp_space
(
info
,
len
))
return
0
;
if
(
!
get_file_tmp_space
(
info
,
strlen
(
buffer
)
*
sizeof
(
WCHAR
)
))
return
0
;
len
=
info
->
tmplen
;
if
((
res
=
parse_strW
(
info
->
tmp
,
&
len
,
buffer
,
'\"'
))
==
-
1
)
goto
error
;
ptr
=
info
->
tmp
;
break
;
...
...
@@ -1332,10 +1268,11 @@ static int get_prefix_len( struct key *key, const char *name, struct file_load_i
{
WCHAR
*
p
;
int
res
;
data_size_t
len
=
strlen
(
name
)
*
sizeof
(
WCHAR
)
;
data_size_t
len
;
if
(
!
get_file_tmp_space
(
info
,
len
))
return
0
;
if
(
!
get_file_tmp_space
(
info
,
strlen
(
name
)
*
sizeof
(
WCHAR
)
))
return
0
;
len
=
info
->
tmplen
;
if
((
res
=
parse_strW
(
info
->
tmp
,
&
len
,
name
,
']'
))
==
-
1
)
{
file_read_error
(
"Malformed key"
,
info
);
...
...
server/unicode.c
View file @
12717397
...
...
@@ -26,8 +26,130 @@
#include "unicode.h"
/* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */
static
const
char
utf8_length
[
128
]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x80-0x8f */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0x90-0x9f */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0xa0-0xaf */
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/* 0xb0-0xbf */
0
,
0
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
/* 0xc0-0xcf */
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
/* 0xd0-0xdf */
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
/* 0xe0-0xef */
3
,
3
,
3
,
3
,
3
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
/* 0xf0-0xff */
};
/* first byte mask depending on UTF-8 sequence length */
static
const
unsigned
char
utf8_mask
[
4
]
=
{
0x7f
,
0x1f
,
0x0f
,
0x07
};
/* minimum Unicode value depending on UTF-8 sequence length */
static
const
unsigned
int
utf8_minval
[
4
]
=
{
0x0
,
0x80
,
0x800
,
0x10000
};
static
inline
char
to_hex
(
char
ch
)
{
if
(
isdigit
(
ch
))
return
ch
-
'0'
;
return
tolower
(
ch
)
-
'a'
+
10
;
}
/* parse an escaped string back into Unicode */
/* return the number of chars read from the input, or -1 on output overflow */
int
parse_strW
(
WCHAR
*
buffer
,
data_size_t
*
len
,
const
char
*
src
,
char
endchar
)
{
WCHAR
*
dest
=
buffer
;
WCHAR
*
end
=
buffer
+
*
len
/
sizeof
(
WCHAR
);
const
char
*
p
=
src
;
unsigned
char
ch
;
while
(
*
p
&&
*
p
!=
endchar
&&
dest
<
end
)
{
if
(
*
p
==
'\\'
)
{
p
++
;
if
(
!*
p
)
break
;
switch
(
*
p
)
{
case
'a'
:
*
dest
++
=
'\a'
;
p
++
;
continue
;
case
'b'
:
*
dest
++
=
'\b'
;
p
++
;
continue
;
case
'e'
:
*
dest
++
=
'\e'
;
p
++
;
continue
;
case
'f'
:
*
dest
++
=
'\f'
;
p
++
;
continue
;
case
'n'
:
*
dest
++
=
'\n'
;
p
++
;
continue
;
case
'r'
:
*
dest
++
=
'\r'
;
p
++
;
continue
;
case
't'
:
*
dest
++
=
'\t'
;
p
++
;
continue
;
case
'v'
:
*
dest
++
=
'\v'
;
p
++
;
continue
;
case
'x'
:
/* hex escape */
p
++
;
if
(
!
isxdigit
(
*
p
))
*
dest
=
'x'
;
else
{
*
dest
=
to_hex
(
*
p
++
);
if
(
isxdigit
(
*
p
))
*
dest
=
(
*
dest
*
16
)
+
to_hex
(
*
p
++
);
if
(
isxdigit
(
*
p
))
*
dest
=
(
*
dest
*
16
)
+
to_hex
(
*
p
++
);
if
(
isxdigit
(
*
p
))
*
dest
=
(
*
dest
*
16
)
+
to_hex
(
*
p
++
);
}
dest
++
;
continue
;
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
/* octal escape */
*
dest
=
*
p
++
-
'0'
;
if
(
*
p
>=
'0'
&&
*
p
<=
'7'
)
*
dest
=
(
*
dest
*
8
)
+
(
*
p
++
-
'0'
);
if
(
*
p
>=
'0'
&&
*
p
<=
'7'
)
*
dest
=
(
*
dest
*
8
)
+
(
*
p
++
-
'0'
);
dest
++
;
continue
;
}
/* unrecognized escape: fall through to normal char handling */
}
ch
=
*
p
++
;
if
(
ch
<
0x80
)
*
dest
++
=
ch
;
else
/* parse utf8 char */
{
int
charlen
=
utf8_length
[
ch
-
0x80
];
unsigned
int
res
=
ch
&
utf8_mask
[
charlen
];
switch
(
charlen
)
{
case
3
:
if
((
ch
=
*
p
^
0x80
)
>=
0x40
)
break
;
res
=
(
res
<<
6
)
|
ch
;
p
++
;
case
2
:
if
((
ch
=
*
p
^
0x80
)
>=
0x40
)
break
;
res
=
(
res
<<
6
)
|
ch
;
p
++
;
case
1
:
if
((
ch
=
*
p
^
0x80
)
>=
0x40
)
break
;
res
=
(
res
<<
6
)
|
ch
;
p
++
;
if
(
res
<
utf8_minval
[
charlen
])
break
;
if
(
res
>
0x10ffff
)
break
;
if
(
res
<=
0xffff
)
*
dest
++
=
res
;
else
/* we need surrogates */
{
res
-=
0x10000
;
*
dest
++
=
0xd800
|
(
res
>>
10
);
if
(
dest
<
end
)
*
dest
++
=
0xdc00
|
(
res
&
0x3ff
);
}
continue
;
}
/* ignore invalid char */
}
}
if
(
dest
>=
end
)
return
-
1
;
/* overflow */
*
dest
++
=
0
;
if
(
!*
p
)
return
-
1
;
/* delimiter not found */
*
len
=
(
dest
-
buffer
)
*
sizeof
(
WCHAR
);
return
p
+
1
-
src
;
}
/* dump a Unicode string with proper escaping */
int
dump_strW
(
const
WCHAR
*
str
,
size_t
len
,
FILE
*
f
,
const
char
escape
[
2
]
)
int
dump_strW
(
const
WCHAR
*
str
,
data_
size_t
len
,
FILE
*
f
,
const
char
escape
[
2
]
)
{
static
const
char
escapes
[
32
]
=
".......abtnvfr.............e...."
;
char
buffer
[
256
];
...
...
server/unicode.h
View file @
12717397
...
...
@@ -33,6 +33,7 @@ static inline WCHAR *strdupW( const WCHAR *str )
return
memdup
(
str
,
len
);
}
extern
int
dump_strW
(
const
WCHAR
*
str
,
size_t
len
,
FILE
*
f
,
const
char
escape
[
2
]
);
extern
int
parse_strW
(
WCHAR
*
buffer
,
data_size_t
*
len
,
const
char
*
src
,
char
endchar
);
extern
int
dump_strW
(
const
WCHAR
*
str
,
data_size_t
len
,
FILE
*
f
,
const
char
escape
[
2
]
);
#endif
/* __WINE_SERVER_UNICODE_H */
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