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
5933c2a6
Commit
5933c2a6
authored
Mar 10, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernelbase: Don't allow the full Unicode character range in path functions.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
0eec0eb7
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
53 additions
and
65 deletions
+53
-65
file.c
dlls/kernelbase/file.c
+1
-1
path.c
dlls/kernelbase/path.c
+52
-64
No files found.
dlls/kernelbase/file.c
View file @
5933c2a6
...
...
@@ -507,7 +507,7 @@ HANDLE WINAPI DECLSPEC_HOTPATCH CreateFileW( LPCWSTR filename, DWORD access, DWO
if
(
!
wcsncmp
(
filename
,
L"
\\\\
.
\\
"
,
4
))
{
if
((
iswalpha
(
filename
[
4
])
&&
filename
[
5
]
==
':'
&&
filename
[
6
]
==
'\0'
)
||
if
((
filename
[
4
]
&&
filename
[
5
]
==
':'
&&
!
filename
[
6
]
)
||
!
wcsnicmp
(
filename
+
4
,
L"PIPE
\\
"
,
5
)
||
!
wcsnicmp
(
filename
+
4
,
L"MAILSLOT
\\
"
,
9
))
{
...
...
dlls/kernelbase/path.c
View file @
5933c2a6
...
...
@@ -36,7 +36,9 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
path
);
#define iswalnum(ch) (iswctype((ch), C1_ALPHA|C1_DIGIT|C1_LOWER|C1_UPPER))
#define isalnum(ch) (((ch) >= '0' && (ch) <= '9') || \
((ch) >= 'A' && (ch) <= 'Z') || \
((ch) >= 'a' && (ch) <= 'z'))
#define isxdigit(ch) (((ch) >= '0' && (ch) <= '9') || \
((ch) >= 'A' && (ch) <= 'F') || \
((ch) >= 'a' && (ch) <= 'f'))
...
...
@@ -112,6 +114,17 @@ static SIZE_T strnlenW(const WCHAR *string, SIZE_T maxlen)
return
i
;
}
static
BOOL
is_drive_spec
(
const
WCHAR
*
str
)
{
return
((
str
[
0
]
>=
'A'
&&
str
[
0
]
<=
'Z'
)
||
(
str
[
0
]
>=
'a'
&&
str
[
0
]
<=
'z'
))
&&
str
[
1
]
==
':'
;
}
static
BOOL
is_escaped_drive_spec
(
const
WCHAR
*
str
)
{
return
((
str
[
0
]
>=
'A'
&&
str
[
0
]
<=
'Z'
)
||
(
str
[
0
]
>=
'a'
&&
str
[
0
]
<=
'z'
))
&&
(
str
[
1
]
==
':'
||
str
[
1
]
==
'|'
);
}
static
BOOL
is_prefixed_unc
(
const
WCHAR
*
string
)
{
return
!
wcsnicmp
(
string
,
L"
\\\\
?
\\
UNC
\\
"
,
8
);
...
...
@@ -119,7 +132,7 @@ static BOOL is_prefixed_unc(const WCHAR *string)
static
BOOL
is_prefixed_disk
(
const
WCHAR
*
string
)
{
return
!
wcsncmp
(
string
,
L"
\\\\
?
\\
"
,
4
)
&&
is
walpha
(
string
[
4
])
&&
string
[
5
]
==
':'
;
return
!
wcsncmp
(
string
,
L"
\\\\
?
\\
"
,
4
)
&&
is
_drive_spec
(
string
+
4
)
;
}
static
BOOL
is_prefixed_volume
(
const
WCHAR
*
string
)
...
...
@@ -148,7 +161,7 @@ static BOOL is_prefixed_volume(const WCHAR *string)
if
(
guid
[
i
]
!=
'}'
)
return
FALSE
;
break
;
default:
if
(
!
is
w
xdigit
(
guid
[
i
]))
return
FALSE
;
if
(
!
isxdigit
(
guid
[
i
]))
return
FALSE
;
break
;
}
i
++
;
...
...
@@ -191,7 +204,7 @@ static const WCHAR *get_root_end(const WCHAR *path)
else
if
(
path
[
0
]
==
'\\'
)
return
path
;
/* X:\ */
else
if
(
is
walpha
(
path
[
0
])
&&
path
[
1
]
==
':'
)
else
if
(
is
_drive_spec
(
path
)
)
return
path
[
2
]
==
'\\'
?
path
+
2
:
path
+
1
;
else
return
NULL
;
...
...
@@ -250,7 +263,7 @@ HRESULT WINAPI PathAllocCanonicalize(const WCHAR *path_in, DWORD flags, WCHAR **
if
(
PathCchStripPrefix
(
dst
,
length
+
6
)
==
S_OK
)
{
/* Fill in \ in X:\ if the \ is missing */
if
(
iswalpha
(
dst
[
0
])
&&
dst
[
1
]
==
':'
&&
dst
[
2
]
!=
'\\'
)
if
(
is_drive_spec
(
dst
)
&&
dst
[
2
]
!=
'\\'
)
{
dst
[
2
]
=
'\\'
;
dst
[
3
]
=
0
;
...
...
@@ -324,7 +337,7 @@ HRESULT WINAPI PathAllocCanonicalize(const WCHAR *path_in, DWORD flags, WCHAR **
}
/* If X:\ is not complete, then complete it */
if
(
is
walpha
(
buffer
[
0
])
&&
buffer
[
1
]
==
':'
&&
buffer
[
2
]
!=
'\\'
)
if
(
is
_drive_spec
(
buffer
)
&&
buffer
[
2
]
!=
'\\'
)
{
root_end
=
buffer
+
2
;
dst
=
buffer
+
3
;
...
...
@@ -365,8 +378,8 @@ HRESULT WINAPI PathAllocCanonicalize(const WCHAR *path_in, DWORD flags, WCHAR **
/* Extend the path if needed */
length
=
lstrlenW
(
buffer
);
if
(((
length
+
1
>
MAX_PATH
&&
is
walpha
(
buffer
[
0
])
&&
buffer
[
1
]
==
':'
)
||
(
is
walpha
(
buffer
[
0
])
&&
buffer
[
1
]
==
':'
&&
flags
&
PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH
))
if
(((
length
+
1
>
MAX_PATH
&&
is
_drive_spec
(
buffer
)
)
||
(
is
_drive_spec
(
buffer
)
&&
flags
&
PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH
))
&&
!
(
flags
&
PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS
))
{
memmove
(
buffer
+
4
,
buffer
,
(
length
+
1
)
*
sizeof
(
WCHAR
));
...
...
@@ -402,7 +415,7 @@ HRESULT WINAPI PathAllocCombine(const WCHAR *path1, const WCHAR *path2, DWORD fl
if
(
!
path1
||
!
path2
)
return
PathAllocCanonicalize
(
path1
?
path1
:
path2
,
flags
,
out
);
/* If path2 is fully qualified, use path2 only */
if
(
(
iswalpha
(
path2
[
0
])
&&
path2
[
1
]
==
':'
)
||
(
path2
[
0
]
==
'\\'
&&
path2
[
1
]
==
'\\'
))
if
(
is_drive_spec
(
path2
)
||
(
path2
[
0
]
==
'\\'
&&
path2
[
1
]
==
'\\'
))
{
path1
=
path2
;
path2
=
NULL
;
...
...
@@ -559,7 +572,7 @@ HRESULT WINAPI PathCchCanonicalize(WCHAR *out, SIZE_T size, const WCHAR *in)
TRACE
(
"%p %lu %s
\n
"
,
out
,
size
,
wine_dbgstr_w
(
in
));
/* Not X:\ and path > MAX_PATH - 4, return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE) */
if
(
lstrlenW
(
in
)
>
MAX_PATH
-
4
&&
!
(
is
walpha
(
in
[
0
])
&&
in
[
1
]
==
':'
&&
in
[
2
]
==
'\\'
))
if
(
lstrlenW
(
in
)
>
MAX_PATH
-
4
&&
!
(
is
_drive_spec
(
in
)
&&
in
[
2
]
==
'\\'
))
return
HRESULT_FROM_WIN32
(
ERROR_FILENAME_EXCED_RANGE
);
return
PathCchCanonicalizeEx
(
out
,
size
,
in
,
PATHCCH_NONE
);
...
...
@@ -582,7 +595,7 @@ HRESULT WINAPI PathCchCanonicalizeEx(WCHAR *out, SIZE_T size, const WCHAR *in, D
if
(
size
<
length
+
1
)
{
/* No root and path > MAX_PATH - 4, return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE) */
if
(
length
>
MAX_PATH
-
4
&&
!
(
in
[
0
]
==
'\\'
||
(
is
walpha
(
in
[
0
])
&&
in
[
1
]
==
':'
&&
in
[
2
]
==
'\\'
)))
if
(
length
>
MAX_PATH
-
4
&&
!
(
in
[
0
]
==
'\\'
||
(
is
_drive_spec
(
in
)
&&
in
[
2
]
==
'\\'
)))
hr
=
HRESULT_FROM_WIN32
(
ERROR_FILENAME_EXCED_RANGE
);
else
hr
=
STRSAFE_E_INSUFFICIENT_BUFFER
;
...
...
@@ -593,7 +606,7 @@ HRESULT WINAPI PathCchCanonicalizeEx(WCHAR *out, SIZE_T size, const WCHAR *in, D
memcpy
(
out
,
buffer
,
(
length
+
1
)
*
sizeof
(
WCHAR
));
/* Fill a backslash at the end of X: */
if
(
is
walpha
(
out
[
0
])
&&
out
[
1
]
==
':'
&&
!
out
[
2
]
&&
size
>
3
)
if
(
is
_drive_spec
(
out
)
&&
!
out
[
2
]
&&
size
>
3
)
{
out
[
2
]
=
'\\'
;
out
[
3
]
=
0
;
...
...
@@ -1779,8 +1792,8 @@ UINT WINAPI PathGetCharTypeW(WCHAR ch)
{
if
(
ch
<
126
)
{
if
(((
ch
&
0x1
)
&&
ch
!=
';'
)
||
!
ch
||
is
w
alnum
(
ch
)
||
ch
==
'$'
||
ch
==
'&'
||
ch
==
'('
||
ch
==
'.'
||
ch
==
'@'
||
ch
==
'^'
||
ch
==
'\''
||
ch
==
130
||
ch
==
'`'
)
if
(((
ch
&
0x1
)
&&
ch
!=
';'
)
||
!
ch
||
isalnum
(
ch
)
||
ch
==
'$'
||
ch
==
'&'
||
ch
==
'('
||
ch
==
'.'
||
ch
==
'@'
||
ch
==
'^'
||
ch
==
'\''
||
ch
==
'`'
)
{
flags
|=
GCT_SHORTCHAR
;
/* All these are valid for DOS */
}
...
...
@@ -1803,7 +1816,7 @@ int WINAPI PathGetDriveNumberA(const char *path)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
path
&&
!
IsDBCSLeadByte
(
*
path
)
&&
path
[
1
]
==
':'
)
if
(
path
&&
*
path
&&
path
[
1
]
==
':'
)
{
if
(
*
path
>=
'a'
&&
*
path
<=
'z'
)
return
*
path
-
'a'
;
if
(
*
path
>=
'A'
&&
*
path
<=
'Z'
)
return
*
path
-
'A'
;
...
...
@@ -2817,7 +2830,7 @@ HRESULT WINAPI ParseURLW(const WCHAR *url, PARSEDURLW *result)
if
(
result
->
cbSize
!=
sizeof
(
*
result
))
return
E_INVALIDARG
;
while
(
*
ptr
&&
(
is
w
alnum
(
*
ptr
)
||
*
ptr
==
'-'
||
*
ptr
==
'+'
||
*
ptr
==
'.'
))
while
(
*
ptr
&&
(
isalnum
(
*
ptr
)
||
*
ptr
==
'-'
||
*
ptr
==
'+'
||
*
ptr
==
'.'
))
ptr
++
;
if
(
*
ptr
!=
':'
||
ptr
<=
url
+
1
)
...
...
@@ -2928,7 +2941,7 @@ HRESULT WINAPI UrlUnescapeW(WCHAR *url, WCHAR *unescaped, DWORD *unescaped_len,
stop_unescaping
=
TRUE
;
next
=
*
src
;
}
else
if
(
*
src
==
'%'
&&
is
wxdigit
(
*
(
src
+
1
))
&&
isw
xdigit
(
*
(
src
+
2
))
&&
!
stop_unescaping
)
else
if
(
*
src
==
'%'
&&
is
xdigit
(
*
(
src
+
1
))
&&
is
xdigit
(
*
(
src
+
2
))
&&
!
stop_unescaping
)
{
INT
ih
;
WCHAR
buf
[
5
]
=
{
'0'
,
'x'
,
0
};
...
...
@@ -3047,7 +3060,7 @@ HRESULT WINAPI PathCreateFromUrlW(const WCHAR *url, WCHAR *path, DWORD *pcchPath
/* fall through */
case
3
:
/* 'file:///' (implied localhost) + escaped DOS path */
if
(
!
is
walpha
(
*
src
)
||
(
src
[
1
]
!=
':'
&&
src
[
1
]
!=
'|'
))
if
(
!
is
_escaped_drive_spec
(
src
))
src
-=
1
;
break
;
case
2
:
...
...
@@ -3056,7 +3069,7 @@ HRESULT WINAPI PathCreateFromUrlW(const WCHAR *url, WCHAR *path, DWORD *pcchPath
/* 'file://localhost/' + escaped DOS path */
src
+=
10
;
}
else
if
(
is
walpha
(
*
src
)
&&
(
src
[
1
]
==
':'
||
src
[
1
]
==
'|'
))
else
if
(
is
_escaped_drive_spec
(
src
))
{
/* 'file://' + unescaped DOS path */
unescape
=
0
;
...
...
@@ -3073,7 +3086,7 @@ HRESULT WINAPI PathCreateFromUrlW(const WCHAR *url, WCHAR *path, DWORD *pcchPath
len
=
src
-
url
;
StrCpyNW
(
dst
,
url
,
len
+
1
);
dst
+=
len
;
if
(
*
src
&&
is
walpha
(
src
[
1
])
&&
(
src
[
2
]
==
':'
||
src
[
2
]
==
'|'
))
if
(
*
src
&&
is
_escaped_drive_spec
(
src
+
1
))
{
/* 'Forget' to add a trailing '/', just like Windows */
src
++
;
...
...
@@ -3083,7 +3096,7 @@ HRESULT WINAPI PathCreateFromUrlW(const WCHAR *url, WCHAR *path, DWORD *pcchPath
case
4
:
/* 'file://' + unescaped UNC path (\\server\share\path) */
unescape
=
0
;
if
(
is
walpha
(
*
src
)
&&
(
src
[
1
]
==
':'
||
src
[
1
]
==
'|'
))
if
(
is
_escaped_drive_spec
(
src
))
break
;
/* fall through */
default:
...
...
@@ -3098,7 +3111,7 @@ HRESULT WINAPI PathCreateFromUrlW(const WCHAR *url, WCHAR *path, DWORD *pcchPath
/* First do the Windows-specific path conversions */
for
(
dst
=
tpath
;
*
dst
;
dst
++
)
if
(
*
dst
==
'/'
)
*
dst
=
'\\'
;
if
(
is
walpha
(
*
tpath
)
&&
tpath
[
1
]
==
'|'
)
if
(
is
_escaped_drive_spec
(
tpath
)
)
tpath
[
1
]
=
':'
;
/* c| -> c: */
/* And only then unescape the path (i.e. escaped slashes are left as is) */
...
...
@@ -3201,7 +3214,7 @@ static BOOL url_needs_escape(WCHAR ch, DWORD flags, DWORD int_flags)
if
(
ch
<=
31
||
(
ch
>=
127
&&
ch
<=
255
)
)
return
TRUE
;
if
(
is
w
alnum
(
ch
))
if
(
isalnum
(
ch
))
return
FALSE
;
switch
(
ch
)
{
...
...
@@ -3596,9 +3609,9 @@ HRESULT WINAPI UrlCanonicalizeW(const WCHAR *src_url, WCHAR *canonicalized, DWOR
switch
(
state
)
{
case
0
:
if
(
!
is
w
alnum
(
*
wk1
))
{
state
=
3
;
break
;}
if
(
!
isalnum
(
*
wk1
))
{
state
=
3
;
break
;}
*
wk2
++
=
*
wk1
++
;
if
(
!
is
w
alnum
(
*
wk1
))
{
state
=
3
;
break
;}
if
(
!
isalnum
(
*
wk1
))
{
state
=
3
;
break
;}
*
wk2
++
=
*
wk1
++
;
state
=
1
;
break
;
...
...
@@ -3627,7 +3640,7 @@ HRESULT WINAPI UrlCanonicalizeW(const WCHAR *src_url, WCHAR *canonicalized, DWOR
while
(
*
body
==
'/'
)
++
body
;
if
(
is
walnum
(
*
body
)
&&
*
(
body
+
1
)
==
':'
)
if
(
is
_drive_spec
(
body
)
)
{
if
(
!
(
flags
&
(
URL_WININET_COMPATIBILITY
|
URL_FILE_USE_PATHURL
)))
{
...
...
@@ -3684,12 +3697,12 @@ HRESULT WINAPI UrlCanonicalizeW(const WCHAR *src_url, WCHAR *canonicalized, DWOR
}
break
;
case
4
:
if
(
!
is
w
alnum
(
*
wk1
)
&&
(
*
wk1
!=
'-'
)
&&
(
*
wk1
!=
'.'
)
&&
(
*
wk1
!=
':'
))
if
(
!
isalnum
(
*
wk1
)
&&
(
*
wk1
!=
'-'
)
&&
(
*
wk1
!=
'.'
)
&&
(
*
wk1
!=
':'
))
{
state
=
3
;
break
;
}
while
(
is
w
alnum
(
*
wk1
)
||
(
*
wk1
==
'-'
)
||
(
*
wk1
==
'.'
)
||
(
*
wk1
==
':'
))
while
(
isalnum
(
*
wk1
)
||
(
*
wk1
==
'-'
)
||
(
*
wk1
==
'.'
)
||
(
*
wk1
==
':'
))
*
wk2
++
=
*
wk1
++
;
state
=
5
;
if
(
!*
wk1
)
...
...
@@ -3960,8 +3973,7 @@ static HRESULT url_create_from_path(const WCHAR *path, WCHAR *url, DWORD *url_le
new_url
=
heap_alloc
((
lstrlenW
(
path
)
+
9
)
*
sizeof
(
WCHAR
));
/* "file:///" + path length + 1 */
lstrcpyW
(
new_url
,
L"file:"
);
if
(
iswalpha
(
path
[
0
])
&&
path
[
1
]
==
':'
)
lstrcatW
(
new_url
,
L"///"
);
if
(
is_drive_spec
(
path
))
lstrcatW
(
new_url
,
L"///"
);
lstrcatW
(
new_url
,
path
);
hr
=
UrlEscapeW
(
new_url
,
url
,
url_len
,
URL_ESCAPE_PERCENT
);
heap_free
(
new_url
);
...
...
@@ -4166,34 +4178,25 @@ HRESULT WINAPI UrlGetPartA(const char *url, char *out, DWORD *out_len, DWORD par
static
const
WCHAR
*
scan_url
(
const
WCHAR
*
start
,
DWORD
*
size
,
enum
url_scan_type
type
)
{
static
DWORD
alwayszero
=
0
;
BOOL
cont
=
TRUE
;
*
size
=
0
;
switch
(
type
)
{
case
SCHEME
:
while
(
cont
)
{
if
((
iswlower
(
*
start
)
&&
iswalpha
(
*
start
))
||
iswdigit
(
*
start
)
||
*
start
==
'+'
||
*
start
==
'-'
||
*
start
==
'.'
)
while
((
*
start
>=
'a'
&&
*
start
<=
'z'
)
||
(
*
start
>=
'0'
&&
*
start
<=
'9'
)
||
*
start
==
'+'
||
*
start
==
'-'
||
*
start
==
'.'
)
{
start
++
;
(
*
size
)
++
;
}
else
cont
=
FALSE
;
}
if
(
*
start
!=
':'
)
*
size
=
0
;
break
;
case
USERPASS
:
while
(
cont
)
for
(;;
)
{
if
(
iswalpha
(
*
start
)
||
iswdigit
(
*
start
)
||
if
(
isalnum
(
*
start
)
||
/* user/password only characters */
(
*
start
==
';'
)
||
(
*
start
==
'?'
)
||
...
...
@@ -4217,49 +4220,34 @@ static const WCHAR * scan_url(const WCHAR *start, DWORD *size, enum url_scan_typ
start
++
;
(
*
size
)
++
;
}
else
if
(
*
start
==
'%'
)
{
if
(
iswxdigit
(
*
(
start
+
1
))
&&
iswxdigit
(
*
(
start
+
2
)))
else
if
(
*
start
==
'%'
&&
isxdigit
(
start
[
1
])
&&
isxdigit
(
start
[
2
]))
{
start
+=
3
;
*
size
+=
3
;
}
else
cont
=
FALSE
;
}
else
cont
=
FALSE
;
else
break
;
}
break
;
case
PORT
:
while
(
cont
)
{
if
(
iswdigit
(
*
start
))
while
(
*
start
>=
'0'
&&
*
start
<=
'9'
)
{
start
++
;
(
*
size
)
++
;
}
else
cont
=
FALSE
;
}
break
;
case
HOST
:
while
(
cont
)
{
if
(
iswalnum
(
*
start
)
||
*
start
==
'-'
||
*
start
==
'.'
||
*
start
==
' '
||
*
start
==
'*'
)
while
(
isalnum
(
*
start
)
||
*
start
==
'-'
||
*
start
==
'.'
||
*
start
==
' '
||
*
start
==
'*'
)
{
start
++
;
(
*
size
)
++
;
}
else
cont
=
FALSE
;
}
break
;
default:
FIXME
(
"unknown type %d
\n
"
,
type
);
return
(
LPWSTR
)
&
alwayszero
;
return
L""
;
}
return
start
;
...
...
@@ -4833,7 +4821,7 @@ HRESULT WINAPI UrlCombineW(const WCHAR *baseW, const WCHAR *relativeW, WCHAR *co
process_case
=
1
;
break
;
}
if
(
is
walnum
(
*
mrelative
)
&&
*
(
mrelative
+
1
)
==
':'
)
if
(
is
_drive_spec
(
mrelative
)
)
{
/* case that becomes "file:///" */
lstrcpyW
(
preliminary
,
L"file:///"
);
...
...
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