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
8f24641f
Commit
8f24641f
authored
Sep 27, 2016
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user32: Enforce null termination of strings added to the clipboard.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
1d27f915
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
164 additions
and
8 deletions
+164
-8
clipboard.c
dlls/user32/clipboard.c
+34
-8
clipboard.c
dlls/user32/tests/clipboard.c
+130
-0
No files found.
dlls/user32/clipboard.c
View file @
8f24641f
...
...
@@ -173,6 +173,29 @@ static HANDLE marshal_data( UINT format, HANDLE handle, data_size_t *ret_size )
GlobalUnlock
(
handle
);
return
mfbits
;
}
case
CF_UNICODETEXT
:
{
WCHAR
*
ptr
;
if
(
!
(
size
=
GlobalSize
(
handle
)))
return
0
;
if
((
data_size_t
)
size
!=
size
)
return
0
;
if
(
!
(
ptr
=
GlobalLock
(
handle
)))
return
0
;
ptr
[(
size
+
1
)
/
sizeof
(
WCHAR
)
-
1
]
=
0
;
/* enforce null-termination */
GlobalUnlock
(
handle
);
*
ret_size
=
size
;
return
handle
;
}
case
CF_TEXT
:
case
CF_OEMTEXT
:
{
char
*
ptr
;
if
(
!
(
size
=
GlobalSize
(
handle
)))
return
0
;
if
((
data_size_t
)
size
!=
size
)
return
0
;
if
(
!
(
ptr
=
GlobalLock
(
handle
)))
return
0
;
ptr
[
size
-
1
]
=
0
;
/* enforce null-termination */
GlobalUnlock
(
handle
);
*
ret_size
=
size
;
return
handle
;
}
default:
if
(
!
(
size
=
GlobalSize
(
handle
)))
return
0
;
if
((
data_size_t
)
size
!=
size
)
return
0
;
...
...
@@ -382,9 +405,11 @@ static HANDLE render_synthesized_textA( HANDLE data, UINT format, UINT from )
size
=
len
*
sizeof
(
WCHAR
);
}
len
=
WideCharToMultiByte
(
codepage
,
0
,
src
,
size
/
sizeof
(
WCHAR
),
NULL
,
0
,
NULL
,
NULL
);
if
((
ret
=
GlobalAlloc
(
GMEM_FIXED
,
len
)))
WideCharToMultiByte
(
codepage
,
0
,
src
,
size
/
sizeof
(
WCHAR
),
ret
,
len
,
NULL
,
NULL
);
if
((
len
=
WideCharToMultiByte
(
codepage
,
0
,
src
,
size
/
sizeof
(
WCHAR
),
NULL
,
0
,
NULL
,
NULL
)))
{
if
((
ret
=
GlobalAlloc
(
GMEM_FIXED
,
len
)))
WideCharToMultiByte
(
codepage
,
0
,
src
,
size
/
sizeof
(
WCHAR
),
ret
,
len
,
NULL
,
NULL
);
}
done:
HeapFree
(
GetProcessHeap
(),
0
,
srcW
);
...
...
@@ -396,16 +421,17 @@ done:
static
HANDLE
render_synthesized_textW
(
HANDLE
data
,
UINT
from
)
{
char
*
src
;
HANDLE
ret
;
HANDLE
ret
=
0
;
UINT
len
,
size
=
GlobalSize
(
data
);
UINT
codepage
=
get_format_codepage
(
get_clipboard_locale
(),
from
);
if
(
!
(
src
=
GlobalLock
(
data
)))
return
0
;
len
=
MultiByteToWideChar
(
codepage
,
0
,
src
,
size
,
NULL
,
0
);
if
((
ret
=
GlobalAlloc
(
GMEM_FIXED
,
len
*
sizeof
(
WCHAR
)
)))
MultiByteToWideChar
(
codepage
,
0
,
src
,
size
,
ret
,
len
);
if
((
len
=
MultiByteToWideChar
(
codepage
,
0
,
src
,
size
,
NULL
,
0
)))
{
if
((
ret
=
GlobalAlloc
(
GMEM_FIXED
,
len
*
sizeof
(
WCHAR
)
)))
MultiByteToWideChar
(
codepage
,
0
,
src
,
size
,
ret
,
len
);
}
GlobalUnlock
(
data
);
return
ret
;
}
...
...
dlls/user32/tests/clipboard.c
View file @
8f24641f
...
...
@@ -2264,6 +2264,130 @@ static void test_GetUpdatedClipboardFormats(void)
ok
(
count
==
4
,
"wrong count %u
\n
"
,
count
);
}
static
const
struct
{
char
strA
[
12
];
WCHAR
strW
[
12
];
UINT
len
;
}
test_data
[]
=
{
{
"foo"
,
{},
3
},
/* 0 */
{
"foo"
,
{},
4
},
{
"foo
\0
bar"
,
{},
7
},
{
"foo
\0
bar"
,
{},
8
},
{
""
,
{
'f'
,
'o'
,
'o'
},
3
*
sizeof
(
WCHAR
)
},
{
""
,
{
'f'
,
'o'
,
'o'
,
0
},
4
*
sizeof
(
WCHAR
)
},
/* 5 */
{
""
,
{
'f'
,
'o'
,
'o'
,
0
,
'b'
,
'a'
,
'r'
},
7
*
sizeof
(
WCHAR
)
},
{
""
,
{
'f'
,
'o'
,
'o'
,
0
,
'b'
,
'a'
,
'r'
,
0
},
8
*
sizeof
(
WCHAR
)
},
{
""
,
{
'f'
,
'o'
,
'o'
},
1
},
{
""
,
{
'f'
,
'o'
,
'o'
},
2
},
{
""
,
{
'f'
,
'o'
,
'o'
},
5
},
/* 10 */
{
""
,
{
'f'
,
'o'
,
'o'
,
0
},
7
},
{
""
,
{
'f'
,
'o'
,
'o'
,
0
},
9
},
};
static
void
test_string_data
(
void
)
{
UINT
i
;
BOOL
r
;
HANDLE
data
;
char
cmd
[
16
];
char
bufferA
[
12
];
WCHAR
bufferW
[
12
];
for
(
i
=
0
;
i
<
sizeof
(
test_data
)
/
sizeof
(
test_data
[
0
]);
i
++
)
{
/* 1-byte Unicode strings crash on Win64 */
#ifdef _WIN64
if
(
!
test_data
[
i
].
strA
[
0
]
&&
test_data
[
i
].
len
<
sizeof
(
WCHAR
))
continue
;
#endif
r
=
OpenClipboard
(
0
);
ok
(
r
,
"gle %d
\n
"
,
GetLastError
()
);
r
=
EmptyClipboard
();
ok
(
r
,
"gle %d
\n
"
,
GetLastError
()
);
data
=
GlobalAlloc
(
GMEM_FIXED
,
test_data
[
i
].
len
);
if
(
test_data
[
i
].
strA
[
0
])
{
memcpy
(
data
,
test_data
[
i
].
strA
,
test_data
[
i
].
len
);
SetClipboardData
(
CF_TEXT
,
data
);
memcpy
(
bufferA
,
test_data
[
i
].
strA
,
test_data
[
i
].
len
);
bufferA
[
test_data
[
i
].
len
-
1
]
=
0
;
ok
(
!
memcmp
(
data
,
bufferA
,
test_data
[
i
].
len
),
"%u: wrong data %.*s
\n
"
,
i
,
test_data
[
i
].
len
,
(
char
*
)
data
);
}
else
{
memcpy
(
data
,
test_data
[
i
].
strW
,
test_data
[
i
].
len
);
SetClipboardData
(
CF_UNICODETEXT
,
data
);
memcpy
(
bufferW
,
test_data
[
i
].
strW
,
test_data
[
i
].
len
);
bufferW
[(
test_data
[
i
].
len
+
1
)
/
sizeof
(
WCHAR
)
-
1
]
=
0
;
ok
(
!
memcmp
(
data
,
bufferW
,
test_data
[
i
].
len
),
"%u: wrong data %s
\n
"
,
i
,
wine_dbgstr_wn
(
data
,
(
test_data
[
i
].
len
+
1
)
/
sizeof
(
WCHAR
)
));
}
r
=
CloseClipboard
();
ok
(
r
,
"gle %d
\n
"
,
GetLastError
()
);
sprintf
(
cmd
,
"string_data %u"
,
i
);
run_process
(
cmd
);
}
}
static
void
test_string_data_process
(
int
i
)
{
BOOL
r
;
HANDLE
data
;
UINT
len
,
len2
;
char
bufferA
[
12
];
WCHAR
bufferW
[
12
];
r
=
OpenClipboard
(
0
);
ok
(
r
,
"gle %d
\n
"
,
GetLastError
()
);
if
(
test_data
[
i
].
strA
[
0
])
{
data
=
GetClipboardData
(
CF_TEXT
);
ok
(
data
!=
0
,
"%u: could not get data
\n
"
,
i
);
len
=
GlobalSize
(
data
);
ok
(
len
==
test_data
[
i
].
len
,
"%u: wrong size %u / %u
\n
"
,
i
,
len
,
test_data
[
i
].
len
);
memcpy
(
bufferA
,
test_data
[
i
].
strA
,
test_data
[
i
].
len
);
bufferA
[
test_data
[
i
].
len
-
1
]
=
0
;
ok
(
!
memcmp
(
data
,
bufferA
,
len
),
"%u: wrong data %.*s
\n
"
,
i
,
len
,
(
char
*
)
data
);
data
=
GetClipboardData
(
CF_UNICODETEXT
);
ok
(
data
!=
0
,
"%u: could not get data
\n
"
,
i
);
len
=
GlobalSize
(
data
);
len2
=
MultiByteToWideChar
(
CP_ACP
,
0
,
bufferA
,
test_data
[
i
].
len
,
bufferW
,
12
);
ok
(
len
==
len2
*
sizeof
(
WCHAR
),
"%u: wrong size %u / %u
\n
"
,
i
,
len
,
len2
);
ok
(
!
memcmp
(
data
,
bufferW
,
len
),
"%u: wrong data %s
\n
"
,
i
,
wine_dbgstr_wn
(
data
,
len2
));
}
else
{
data
=
GetClipboardData
(
CF_UNICODETEXT
);
ok
(
data
!=
0
,
"%u: could not get data
\n
"
,
i
);
len
=
GlobalSize
(
data
);
ok
(
len
==
test_data
[
i
].
len
,
"%u: wrong size %u / %u
\n
"
,
i
,
len
,
test_data
[
i
].
len
);
memcpy
(
bufferW
,
test_data
[
i
].
strW
,
test_data
[
i
].
len
);
bufferW
[(
test_data
[
i
].
len
+
1
)
/
sizeof
(
WCHAR
)
-
1
]
=
0
;
ok
(
!
memcmp
(
data
,
bufferW
,
len
),
"%u: wrong data %s
\n
"
,
i
,
wine_dbgstr_wn
(
data
,
(
len
+
1
)
/
sizeof
(
WCHAR
)
));
data
=
GetClipboardData
(
CF_TEXT
);
if
(
test_data
[
i
].
len
>=
sizeof
(
WCHAR
))
{
ok
(
data
!=
0
,
"%u: could not get data
\n
"
,
i
);
len
=
GlobalSize
(
data
);
len2
=
WideCharToMultiByte
(
CP_ACP
,
0
,
bufferW
,
test_data
[
i
].
len
/
sizeof
(
WCHAR
),
bufferA
,
12
,
NULL
,
NULL
);
bufferA
[
len2
-
1
]
=
0
;
ok
(
len
==
len2
,
"%u: wrong size %u / %u
\n
"
,
i
,
len
,
len2
);
ok
(
!
memcmp
(
data
,
bufferA
,
len
),
"%u: wrong data %.*s
\n
"
,
i
,
len
,
(
char
*
)
data
);
}
else
{
ok
(
!
data
,
"%u: got data for empty string
\n
"
,
i
);
ok
(
IsClipboardFormatAvailable
(
CF_TEXT
),
"%u: text not available
\n
"
,
i
);
}
}
r
=
CloseClipboard
();
ok
(
r
,
"gle %d
\n
"
,
GetLastError
()
);
}
START_TEST
(
clipboard
)
{
char
**
argv
;
...
...
@@ -2301,6 +2425,11 @@ START_TEST(clipboard)
test_handles_process_dib
(
argv
[
3
]
);
return
;
}
if
(
argc
==
4
&&
!
strcmp
(
argv
[
2
],
"string_data"
))
{
test_string_data_process
(
atoi
(
argv
[
3
]
));
return
;
}
test_RegisterClipboardFormatA
();
test_ClipboardOwner
();
...
...
@@ -2308,4 +2437,5 @@ START_TEST(clipboard)
test_messages
();
test_data_handles
();
test_GetUpdatedClipboardFormats
();
test_string_data
();
}
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