mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
Fix socketpair failure when temporary directory has non-latin character
This commit is contained in:
parent
211c6653ae
commit
f8bb9d8484
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -288,6 +288,7 @@ jobs:
|
||||
- DISABLE_DEBUG_MODE
|
||||
- DISABLE_MM_REPLACEMENT
|
||||
- DUNICODE
|
||||
- UNOCODE_TEMPORARY_DIRECTORY
|
||||
- TEST_EXPORT_SHARED
|
||||
- TEST_EXPORT_STATIC
|
||||
|
||||
@ -332,6 +333,11 @@ jobs:
|
||||
elseif ( "${{ matrix.EVENT_MATRIX }}" -eq "UNICODE" ) {
|
||||
$EVENT_CMAKE_OPTIONS="-DCMAKE_C_FLAGS='-DUNICODE -D_UNICODE'"
|
||||
}
|
||||
elseif ( "${{ matrix.EVENT_MATRIX }}" -eq "UNOCODE_TEMPORARY_DIRECTORY" ) {
|
||||
$EVENT_CMAKE_OPTIONS=""
|
||||
mkdir "${{ runner.workspace }}\𝑼𝑵𝑰𝑪𝑶𝑫𝑬"
|
||||
echo "TMP=${{ runner.workspace }}\𝑼𝑵𝑰𝑪𝑶𝑫𝑬" >> $env:GITHUB_ENV
|
||||
}
|
||||
elseif ( "${{ matrix.EVENT_MATRIX }}" -eq "TEST_EXPORT_SHARED" ) {
|
||||
$EVENT_CMAKE_OPTIONS="-DEVENT__DISABLE_TESTS=ON -DEVENT__DISABLE_SAMPLES=ON"
|
||||
}
|
||||
|
33
evutil.c
33
evutil.c
@ -31,6 +31,7 @@
|
||||
#include <winsock2.h>
|
||||
#include <winerror.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stringapiset.h>
|
||||
#ifdef EVENT__HAVE_AFUNIX_H
|
||||
#include <afunix.h>
|
||||
#endif
|
||||
@ -212,14 +213,14 @@ evutil_read_file_(const char *filename, char **content_out, size_t *len_out,
|
||||
#ifdef _WIN32
|
||||
|
||||
static int
|
||||
create_tmpfile(char tmpfile[MAX_PATH])
|
||||
create_tmpfile(WCHAR tmpfile[MAX_PATH])
|
||||
{
|
||||
char short_path[MAX_PATH] = {0};
|
||||
char long_path[MAX_PATH] = {0};
|
||||
char prefix[4] = {0};
|
||||
// GetTempFileNameA() uses up to the first three characters of the prefix
|
||||
WCHAR short_path[MAX_PATH] = {0};
|
||||
WCHAR long_path[MAX_PATH] = {0};
|
||||
WCHAR prefix[4] = {0};
|
||||
// GetTempFileNameW() uses up to the first three characters of the prefix
|
||||
// and windows filesystems are case-insensitive
|
||||
const char *base32set = "abcdefghijklmnopqrstuvwxyz012345";
|
||||
const WCHAR *base32set = L"abcdefghijklmnopqrstuvwxyz012345";
|
||||
ev_uint16_t rnd;
|
||||
|
||||
evutil_secure_rng_get_bytes(&rnd, sizeof(rnd));
|
||||
@ -228,9 +229,9 @@ create_tmpfile(char tmpfile[MAX_PATH])
|
||||
prefix[2] = base32set[(rnd >> 10) & 31];
|
||||
prefix[3] = '\0';
|
||||
|
||||
GetTempPathA(MAX_PATH, short_path);
|
||||
GetLongPathNameA(short_path, long_path, MAX_PATH);
|
||||
if (!GetTempFileNameA(long_path, prefix, 0, tmpfile)) {
|
||||
GetTempPathW(MAX_PATH, short_path);
|
||||
GetLongPathNameW(short_path, long_path, MAX_PATH);
|
||||
if (!GetTempFileNameW(long_path, prefix, 0, tmpfile)) {
|
||||
event_warnx("GetTempFileName failed: %d", EVUTIL_SOCKET_ERROR());
|
||||
return -1;
|
||||
}
|
||||
@ -271,7 +272,8 @@ evutil_win_socketpair_afunix(int family, int type, int protocol,
|
||||
|
||||
struct sockaddr_un listen_addr;
|
||||
struct sockaddr_un connect_addr;
|
||||
char tmp_file[MAX_PATH] = {0};
|
||||
WCHAR tmp_file[MAX_PATH] = {0};
|
||||
char tmp_file_utf8[MAX_PATH] = {0};
|
||||
|
||||
ev_socklen_t size;
|
||||
int saved_errno = -1;
|
||||
@ -289,9 +291,14 @@ evutil_win_socketpair_afunix(int family, int type, int protocol,
|
||||
if (create_tmpfile(tmp_file)) {
|
||||
goto tidy_up_and_fail;
|
||||
}
|
||||
DeleteFileA(tmp_file);
|
||||
DeleteFileW(tmp_file);
|
||||
|
||||
/* Windows requires `sun_path` to be encoded by UTF-8 */
|
||||
WideCharToMultiByte(
|
||||
CP_UTF8, 0, tmp_file, MAX_PATH, tmp_file_utf8, MAX_PATH, NULL, NULL);
|
||||
|
||||
listen_addr.sun_family = AF_UNIX;
|
||||
if (strlcpy(listen_addr.sun_path, tmp_file, UNIX_PATH_MAX) >=
|
||||
if (strlcpy(listen_addr.sun_path, tmp_file_utf8, UNIX_PATH_MAX) >=
|
||||
UNIX_PATH_MAX) {
|
||||
event_warnx("Temp file name is too long");
|
||||
goto tidy_up_and_fail;
|
||||
@ -352,7 +359,7 @@ evutil_win_socketpair_afunix(int family, int type, int protocol,
|
||||
if (acceptor != -1)
|
||||
evutil_closesocket(acceptor);
|
||||
if (tmp_file[0])
|
||||
DeleteFileA(tmp_file);
|
||||
DeleteFileW(tmp_file);
|
||||
|
||||
EVUTIL_SET_SOCKET_ERROR(saved_errno);
|
||||
return -1;
|
||||
|
@ -1199,6 +1199,10 @@ test_evbuffer_add_file(void *ptr)
|
||||
}
|
||||
|
||||
fd = regress_make_tmpfile(data, datalen, &tmpfilename);
|
||||
/* On Windows, if TMP environment variable is corrupted, we may not be
|
||||
* able create temporary file, just skip it */
|
||||
if (fd < 0)
|
||||
tt_skip();
|
||||
|
||||
if (map_from_offset) {
|
||||
starting_offset = datalen/4 + 1;
|
||||
@ -1332,7 +1336,10 @@ test_evbuffer_file_segment_add_cleanup_cb(void* ptr)
|
||||
char const* arg = "token";
|
||||
|
||||
fd = regress_make_tmpfile("file_segment_test_file", 22, &tmpfilename);
|
||||
tt_int_op(fd, >=, 0);
|
||||
/* On Windows, if TMP environment variable is corrupted, we may not be
|
||||
* able create temporary file, just skip it */
|
||||
if (fd < 0)
|
||||
tt_skip();
|
||||
|
||||
evb = evbuffer_new();
|
||||
tt_assert(evb);
|
||||
@ -2587,6 +2594,11 @@ test_evbuffer_freeze(void *ptr)
|
||||
FREEZE_EQ(r, 0, -1);
|
||||
len = strlen(tmpfilecontent);
|
||||
fd = regress_make_tmpfile(tmpfilecontent, len, &tmpfilename);
|
||||
/* On Windows, if TMP environment variable is corrupted, we may not be
|
||||
* able create temporary file, just skip it */
|
||||
if (fd < 0)
|
||||
tt_skip();
|
||||
|
||||
r = evbuffer_add_file(buf, fd, 0, len);
|
||||
FREEZE_EQ(r, 0, -1);
|
||||
|
||||
|
@ -152,19 +152,26 @@ regress_make_tmpfile(const void *data, size_t datalen, char **filename_out)
|
||||
return (fd);
|
||||
#else
|
||||
/* XXXX actually delete the file later */
|
||||
char tmpfilepath[MAX_PATH];
|
||||
WCHAR tmpfilepath[MAX_PATH];
|
||||
WCHAR tmpfilelongpath[MAX_PATH];
|
||||
WCHAR tmpfilewideame[MAX_PATH];
|
||||
char tmpfilename[MAX_PATH];
|
||||
DWORD r, written;
|
||||
int tries = 16;
|
||||
HANDLE h;
|
||||
r = GetTempPathA(MAX_PATH, tmpfilepath);
|
||||
r = GetTempPathW(MAX_PATH, tmpfilepath);
|
||||
if (r > MAX_PATH || r == 0)
|
||||
return (-1);
|
||||
r = GetLongPathNameW(tmpfilepath, tmpfilelongpath, MAX_PATH);
|
||||
if (r > MAX_PATH || r == 0)
|
||||
return (-1);
|
||||
for (; tries > 0; --tries) {
|
||||
r = GetTempFileNameA(tmpfilepath, "LIBEVENT", 0, tmpfilename);
|
||||
if (r == 0)
|
||||
r = GetTempFileNameW(tmpfilelongpath, L"LIBEVENT", 0, tmpfilewideame);
|
||||
if (r == 0) {
|
||||
int err = GetLastError();
|
||||
return (-1);
|
||||
h = CreateFileA(tmpfilename, GENERIC_READ|GENERIC_WRITE,
|
||||
}
|
||||
h = CreateFileW(tmpfilewideame, GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (h != INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
@ -172,6 +179,9 @@ regress_make_tmpfile(const void *data, size_t datalen, char **filename_out)
|
||||
if (tries == 0)
|
||||
return (-1);
|
||||
written = 0;
|
||||
WideCharToMultiByte(
|
||||
CP_ACP, 0, tmpfilewideame, MAX_PATH, tmpfilename,
|
||||
MAX_PATH, NULL, NULL);
|
||||
*filename_out = strdup(tmpfilename);
|
||||
WriteFile(h, data, (DWORD)datalen, &written, NULL);
|
||||
/* Closing the fd returned by this function will indeed close h. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user