Skip to content

Commit 4655295

Browse files
Fix Windows file checks of unicode paths (flutter#16105)
1 parent 74930e4 commit 4655295

File tree

2 files changed

+47
-11
lines changed

2 files changed

+47
-11
lines changed

fml/file_unittest.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "flutter/fml/build_config.h"
1111
#include "flutter/fml/file.h"
1212
#include "flutter/fml/mapping.h"
13+
#include "flutter/fml/paths.h"
1314
#include "flutter/fml/unique_fd.h"
1415

1516
static bool WriteStringToFile(const fml::UniqueFD& fd,
@@ -267,3 +268,31 @@ TEST(FileTest, EmptyMappingTest) {
267268

268269
ASSERT_TRUE(fml::UnlinkFile(dir.fd(), "my_contents"));
269270
}
271+
272+
TEST(FileTest, FileTestsWork) {
273+
fml::ScopedTemporaryDirectory dir;
274+
ASSERT_TRUE(dir.fd().is_valid());
275+
const char* filename = "some.txt";
276+
auto fd =
277+
fml::OpenFile(dir.fd(), filename, true, fml::FilePermission::kWrite);
278+
ASSERT_TRUE(fd.is_valid());
279+
fd.reset();
280+
ASSERT_TRUE(fml::FileExists(dir.fd(), filename));
281+
ASSERT_TRUE(
282+
fml::IsFile(fml::paths::JoinPaths({dir.path(), filename}).c_str()));
283+
ASSERT_TRUE(fml::UnlinkFile(dir.fd(), filename));
284+
}
285+
286+
TEST(FileTest, FileTestsSupportsUnicode) {
287+
fml::ScopedTemporaryDirectory dir;
288+
ASSERT_TRUE(dir.fd().is_valid());
289+
const char* filename = u8"äëïöüテスト☃";
290+
auto fd =
291+
fml::OpenFile(dir.fd(), filename, true, fml::FilePermission::kWrite);
292+
ASSERT_TRUE(fd.is_valid());
293+
fd.reset();
294+
ASSERT_TRUE(fml::FileExists(dir.fd(), filename));
295+
ASSERT_TRUE(
296+
fml::IsFile(fml::paths::JoinPaths({dir.path(), filename}).c_str()));
297+
ASSERT_TRUE(fml::UnlinkFile(dir.fd(), filename));
298+
}

fml/platform/win/file_win.cc

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <Shlwapi.h>
99
#include <fcntl.h>
1010
#include <limits.h>
11-
#include <sys/stat.h>
1211

1312
#include <algorithm>
1413
#include <sstream>
@@ -18,10 +17,6 @@
1817
#include "flutter/fml/platform/win/errors_win.h"
1918
#include "flutter/fml/platform/win/wstring_conversion.h"
2019

21-
#if defined(OS_WIN)
22-
#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
23-
#endif
24-
2520
namespace fml {
2621

2722
static std::string GetFullHandlePath(const fml::UniqueFD& handle) {
@@ -80,6 +75,16 @@ static DWORD GetShareFlags(FilePermission permission) {
8075
return FILE_SHARE_READ;
8176
}
8277

78+
static DWORD GetFileAttributesForUtf8Path(const char* absolute_path) {
79+
return ::GetFileAttributes(ConvertToWString(absolute_path).c_str());
80+
}
81+
82+
static DWORD GetFileAttributesForUtf8Path(const fml::UniqueFD& base_directory,
83+
const char* path) {
84+
std::string full_path = GetFullHandlePath(base_directory) + "\\" + path;
85+
return GetFileAttributesForUtf8Path(full_path.c_str());
86+
}
87+
8388
std::string CreateTemporaryDirectory() {
8489
// Get the system temporary directory.
8590
auto temp_dir_container = GetTemporaryDirectoryPath();
@@ -253,16 +258,17 @@ bool IsDirectory(const fml::UniqueFD& directory) {
253258
}
254259

255260
bool IsDirectory(const fml::UniqueFD& base_directory, const char* path) {
256-
std::string full_path = GetFullHandlePath(base_directory) + "\\" + path;
257-
return ::GetFileAttributes(ConvertToWString(full_path.c_str()).c_str()) &
261+
return GetFileAttributesForUtf8Path(base_directory, path) &
258262
FILE_ATTRIBUTE_DIRECTORY;
259263
}
260264

261265
bool IsFile(const std::string& path) {
262-
struct stat buf;
263-
if (stat(path.c_str(), &buf) != 0)
266+
DWORD attributes = GetFileAttributesForUtf8Path(path.c_str());
267+
if (attributes == INVALID_FILE_ATTRIBUTES) {
264268
return false;
265-
return S_ISREG(buf.st_mode);
269+
}
270+
return !(attributes &
271+
(FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT));
266272
}
267273

268274
bool UnlinkDirectory(const char* path) {
@@ -323,7 +329,8 @@ bool TruncateFile(const fml::UniqueFD& file, size_t size) {
323329
}
324330

325331
bool FileExists(const fml::UniqueFD& base_directory, const char* path) {
326-
return IsFile(GetAbsolutePath(base_directory, path).c_str());
332+
return GetFileAttributesForUtf8Path(base_directory, path) !=
333+
INVALID_FILE_ATTRIBUTES;
327334
}
328335

329336
bool WriteAtomically(const fml::UniqueFD& base_directory,

0 commit comments

Comments
 (0)