Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(421)

Unified Diff: runtime/bin/directory_win.cc

Issue 1781883002: Fixes some memory leaks in //runtime/bin (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix tests on Windows Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/directory_macos.cc ('k') | runtime/bin/fdutils_android.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/directory_win.cc
diff --git a/runtime/bin/directory_win.cc b/runtime/bin/directory_win.cc
index 40bfb9bf158ddf36b53217204bf56c9589a373c1..efaaaf90a6e7ee6f08e5e94b2f5e6a0157d08900 100644
--- a/runtime/bin/directory_win.cc
+++ b/runtime/bin/directory_win.cc
@@ -13,6 +13,7 @@
#include <errno.h> // NOLINT
#include <sys/stat.h> // NOLINT
+#include "bin/dartutils.h"
#include "bin/log.h"
#undef DeleteFile
@@ -23,24 +24,37 @@ namespace dart {
namespace bin {
PathBuffer::PathBuffer() : length_(0) {
- data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT
+ data_ = calloc(MAX_LONG_PATH + 1, sizeof(wchar_t)); // NOLINT
}
+
+PathBuffer::~PathBuffer() {
+ free(data_);
+}
+
+
char* PathBuffer::AsString() const {
- return StringUtilsWin::WideToUtf8(AsStringW());
+ UNREACHABLE();
+ return NULL;
}
+
wchar_t* PathBuffer::AsStringW() const {
return reinterpret_cast<wchar_t*>(data_);
}
+
+const char* PathBuffer::AsScopedString() const {
+ return StringUtilsWin::WideToUtf8(AsStringW());
+}
+
+
bool PathBuffer::Add(const char* name) {
const wchar_t* wide_name = StringUtilsWin::Utf8ToWide(name);
- bool success = AddW(wide_name);
- free(const_cast<wchar_t*>(wide_name));
- return success;
+ return AddW(wide_name);
}
+
bool PathBuffer::AddW(const wchar_t* name) {
wchar_t* data = AsStringW();
int written = _snwprintf(data + length_,
@@ -48,9 +62,9 @@ bool PathBuffer::AddW(const wchar_t* name) {
L"%s",
name);
data[MAX_LONG_PATH] = L'\0';
- if (written <= MAX_LONG_PATH - length_ &&
- written >= 0 &&
- static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1)) {
+ if ((written <= MAX_LONG_PATH - length_) &&
+ (written >= 0) &&
+ (static_cast<size_t>(written) == wcsnlen(name, MAX_LONG_PATH + 1))) {
length_ += written;
return true;
} else {
@@ -59,11 +73,13 @@ bool PathBuffer::AddW(const wchar_t* name) {
}
}
-void PathBuffer::Reset(int new_length) {
+
+void PathBuffer::Reset(intptr_t new_length) {
length_ = new_length;
AsStringW()[length_] = L'\0';
}
+
// If link_name points to a link, IsBrokenLink will return true if link_name
// points to an invalid target.
static bool IsBrokenLink(const wchar_t* link_name) {
@@ -83,6 +99,7 @@ static bool IsBrokenLink(const wchar_t* link_name) {
}
}
+
// A linked list structure holding a link target's unique file system ID.
// Used to detect loops in the file system when listing recursively.
struct LinkList {
@@ -98,7 +115,7 @@ static bool DeleteRecursively(PathBuffer* path);
static ListType HandleFindFile(DirectoryListing* listing,
DirectoryListingEntry* entry,
- WIN32_FIND_DATAW& find_file_data) {
+ const WIN32_FIND_DATAW& find_file_data) {
if (!listing->path_buffer().AddW(find_file_data.cFileName)) {
return kListError;
}
@@ -137,17 +154,17 @@ static ListType HandleFindFile(DirectoryListing* listing,
current_link.next = entry->link();
LinkList* previous = entry->link();
while (previous != NULL) {
- if (previous->volume == current_link.volume &&
- previous->id_low == current_link.id_low &&
- previous->id_high == current_link.id_high) {
+ if ((previous->volume == current_link.volume) &&
+ (previous->id_low == current_link.id_low) &&
+ (previous->id_high == current_link.id_high)) {
// Report the looping link as a link, rather than following it.
return kListLink;
}
previous = previous->next;
}
// Recurse into the directory, adding current link to the seen links list.
- if (wcscmp(find_file_data.cFileName, L".") == 0 ||
- wcscmp(find_file_data.cFileName, L"..") == 0) {
+ if ((wcscmp(find_file_data.cFileName, L".") == 0) ||
+ (wcscmp(find_file_data.cFileName, L"..") == 0)) {
return entry->Next(listing);
}
entry->set_link(new LinkList(current_link));
@@ -155,8 +172,8 @@ static ListType HandleFindFile(DirectoryListing* listing,
}
}
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
- if (wcscmp(find_file_data.cFileName, L".") == 0 ||
- wcscmp(find_file_data.cFileName, L"..") == 0) {
+ if ((wcscmp(find_file_data.cFileName, L".") == 0) ||
+ (wcscmp(find_file_data.cFileName, L"..") == 0)) {
return entry->Next(listing);
}
return kListDirectory;
@@ -165,6 +182,7 @@ static ListType HandleFindFile(DirectoryListing* listing,
}
}
+
ListType DirectoryListingEntry::Next(DirectoryListing* listing) {
if (done_) {
return kListDone;
@@ -223,7 +241,7 @@ DirectoryListingEntry::~DirectoryListingEntry() {
void DirectoryListingEntry::ResetLink() {
- if (link_ != NULL && (parent_ == NULL || parent_->link_ != link_)) {
+ if ((link_ != NULL) && ((parent_ == NULL) || (parent_->link_ != link_))) {
delete link_;
link_ = NULL;
}
@@ -234,7 +252,9 @@ void DirectoryListingEntry::ResetLink() {
static bool DeleteFile(wchar_t* file_name, PathBuffer* path) {
- if (!path->AddW(file_name)) return false;
+ if (!path->AddW(file_name)) {
+ return false;
+ }
if (DeleteFileW(path->AsStringW()) != 0) {
return true;
@@ -265,8 +285,10 @@ static bool DeleteFile(wchar_t* file_name, PathBuffer* path) {
static bool DeleteDir(wchar_t* dir_name, PathBuffer* path) {
- if (wcscmp(dir_name, L".") == 0) return true;
- if (wcscmp(dir_name, L"..") == 0) return true;
+ if ((wcscmp(dir_name, L".") == 0) ||
+ (wcscmp(dir_name, L"..") == 0)) {
+ return true;
+ }
return path->AddW(dir_name) && DeleteRecursively(path);
}
@@ -284,7 +306,7 @@ static bool DeleteEntry(LPWIN32_FIND_DATAW find_file_data, PathBuffer* path) {
static bool DeleteRecursively(PathBuffer* path) {
DWORD attributes = GetFileAttributesW(path->AsStringW());
- if ((attributes == INVALID_FILE_ATTRIBUTES)) {
+ if (attributes == INVALID_FILE_ATTRIBUTES) {
return false;
}
// If the directory is a junction, it's pointing to some other place in the
@@ -298,7 +320,9 @@ static bool DeleteRecursively(PathBuffer* path) {
return DeleteFile(L"", path);
}
- if (!path->AddW(L"\\*")) return false;
+ if (!path->AddW(L"\\*")) {
+ return false;
+ }
WIN32_FIND_DATAW find_file_data;
HANDLE find_handle = FindFirstFileW(path->AsStringW(), &find_file_data);
@@ -336,8 +360,8 @@ static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) {
DWORD attributes = GetFileAttributesW(dir_name);
if (attributes == INVALID_FILE_ATTRIBUTES) {
DWORD last_error = GetLastError();
- if (last_error == ERROR_FILE_NOT_FOUND ||
- last_error == ERROR_PATH_NOT_FOUND) {
+ if ((last_error == ERROR_FILE_NOT_FOUND) ||
+ (last_error == ERROR_PATH_NOT_FOUND)) {
return Directory::DOES_NOT_EXIST;
} else {
// We might not be able to get the file attributes for other
@@ -354,27 +378,42 @@ static Directory::ExistsResult ExistsHelper(const wchar_t* dir_name) {
Directory::ExistsResult Directory::Exists(const char* dir_name) {
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(dir_name);
- Directory::ExistsResult result = ExistsHelper(system_name);
- free(const_cast<wchar_t*>(system_name));
- return result;
+ return ExistsHelper(system_name);
}
-char* Directory::Current() {
+char* Directory::CurrentNoScope() {
int length = GetCurrentDirectoryW(0, NULL);
- if (length == 0) return NULL;
+ if (length == 0) {
+ return NULL;
+ }
wchar_t* current = new wchar_t[length + 1];
GetCurrentDirectoryW(length + 1, current);
- char* result = StringUtilsWin::WideToUtf8(current);
+ int utf8_len = WideCharToMultiByte(
+ CP_UTF8, 0, current, -1, NULL, 0, NULL, NULL);
+ char* result = reinterpret_cast<char*>(malloc(utf8_len));
+ WideCharToMultiByte(CP_UTF8, 0, current, -1, result, utf8_len, NULL, NULL);
delete[] current;
return result;
}
+const char* Directory::Current() {
+ int length = GetCurrentDirectoryW(0, NULL);
+ if (length == 0) {
+ return NULL;
+ }
+ wchar_t* current;
+ current = reinterpret_cast<wchar_t*>(
+ Dart_ScopeAllocate((length + 1) * sizeof(*current)));
+ GetCurrentDirectoryW(length + 1, current);
+ return StringUtilsWin::WideToUtf8(current);
+}
+
+
bool Directory::SetCurrent(const char* path) {
const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path);
bool result = SetCurrentDirectoryW(system_path) != 0;
- free(const_cast<wchar_t*>(system_path));
return result;
}
@@ -383,35 +422,34 @@ bool Directory::Create(const char* dir_name) {
const wchar_t* system_name = StringUtilsWin::Utf8ToWide(dir_name);
int create_status = CreateDirectoryW(system_name, NULL);
// If the directory already existed, treat it as a success.
- if (create_status == 0 &&
- GetLastError() == ERROR_ALREADY_EXISTS &&
- ExistsHelper(system_name) == EXISTS) {
- free(const_cast<wchar_t*>(system_name));
+ if ((create_status == 0) &&
+ (GetLastError() == ERROR_ALREADY_EXISTS) &&
+ (ExistsHelper(system_name) == EXISTS)) {
return true;
}
- free(const_cast<wchar_t*>(system_name));
return (create_status != 0);
}
-char* Directory::SystemTemp() {
+const char* Directory::SystemTemp() {
PathBuffer path;
// Remove \ at end.
path.Reset(GetTempPathW(MAX_LONG_PATH, path.AsStringW()) - 1);
- return path.AsString();
+ return path.AsScopedString();
}
-char* Directory::CreateTemp(const char* prefix) {
+const char* Directory::CreateTemp(const char* prefix) {
// Returns a new, unused directory name, adding characters to the
// end of prefix.
// Creates this directory, with a default security
// descriptor inherited from its parent directory.
- // The return value must be freed by the caller.
+ // The return value is Dart_ScopeAllocated.
PathBuffer path;
const wchar_t* system_prefix = StringUtilsWin::Utf8ToWide(prefix);
- path.AddW(system_prefix);
- free(const_cast<wchar_t*>(system_prefix));
+ if (!path.AddW(system_prefix)) {
+ return NULL;
+ }
// Length of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 36.
if (path.length() > MAX_LONG_PATH - 36) {
@@ -420,7 +458,7 @@ char* Directory::CreateTemp(const char* prefix) {
UUID uuid;
RPC_STATUS status = UuidCreateSequential(&uuid);
- if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) {
+ if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) {
return NULL;
}
RPC_WSTR uuid_string;
@@ -430,13 +468,14 @@ char* Directory::CreateTemp(const char* prefix) {
}
// RPC_WSTR is an unsigned short*, so we cast to wchar_t*.
- path.AddW(reinterpret_cast<wchar_t*>(uuid_string));
+ if (!path.AddW(reinterpret_cast<wchar_t*>(uuid_string))) {
+ return NULL;
+ }
RpcStringFreeW(&uuid_string);
if (!CreateDirectoryW(path.AsStringW(), NULL)) {
return NULL;
}
- char* result = path.AsString();
- return result;
+ return path.AsScopedString();
}
@@ -455,7 +494,6 @@ bool Directory::Delete(const char* dir_name, bool recursive) {
result = DeleteRecursively(&path);
}
}
- free(const_cast<wchar_t*>(system_dir_name));
return result;
}
@@ -464,20 +502,22 @@ bool Directory::Rename(const char* path, const char* new_path) {
const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path);
const wchar_t* system_new_path = StringUtilsWin::Utf8ToWide(new_path);
ExistsResult exists = ExistsHelper(system_path);
- if (exists != EXISTS) return false;
+ if (exists != EXISTS) {
+ return false;
+ }
ExistsResult new_exists = ExistsHelper(system_new_path);
// MoveFile does not allow replacing exising directories. Therefore,
// if the new_path is currently a directory we need to delete it
// first.
if (new_exists == EXISTS) {
bool success = Delete(new_path, true);
- if (!success) return false;
+ if (!success) {
+ return false;
+ }
}
DWORD flags = MOVEFILE_WRITE_THROUGH;
int move_status =
MoveFileExW(system_path, system_new_path, flags);
- free(const_cast<wchar_t*>(system_path));
- free(const_cast<wchar_t*>(system_new_path));
return (move_status != 0);
}
« no previous file with comments | « runtime/bin/directory_macos.cc ('k') | runtime/bin/fdutils_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698