summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorahendrickson@chromium.org <ahendrickson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-14 03:19:03 +0000
committerahendrickson@chromium.org <ahendrickson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-14 03:19:03 +0000
commitf798d7a4a79a04ea303558e1b24d4161fb0b84d7 (patch)
treea7d638b9f4ade253029b9aaa418afa0f5a8510f5 /base
parent1c69f8b7c992962fc6387d31eeeb5a3b16c93660 (diff)
downloadchromium_src-f798d7a4a79a04ea303558e1b24d4161fb0b84d7.zip
chromium_src-f798d7a4a79a04ea303558e1b24d4161fb0b84d7.tar.gz
chromium_src-f798d7a4a79a04ea303558e1b24d4161fb0b84d7.tar.bz2
Added read-only file error test.
Depends on CLs 9568003 and 9570005. BUG=None TEST=None Review URL: http://codereview.chromium.org/9355050 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126541 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/test/test_file_util.h17
-rw-r--r--base/test/test_file_util_posix.cc51
-rw-r--r--base/test/test_file_util_win.cc63
3 files changed, 129 insertions, 2 deletions
diff --git a/base/test/test_file_util.h b/base/test/test_file_util.h
index ce0b302..99ec478f 100644
--- a/base/test/test_file_util.h
+++ b/base/test/test_file_util.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include <string>
#include "base/compiler_specific.h"
+#include "base/file_path.h"
class FilePath;
@@ -56,6 +57,20 @@ FilePath WStringAsFilePath(const std::wstring& path);
bool MakeFileUnreadable(const FilePath& path) WARN_UNUSED_RESULT;
bool MakeFileUnwritable(const FilePath& path) WARN_UNUSED_RESULT;
+// Saves the current permissions for a path, and restores it on destruction.
+class PermissionRestorer {
+ public:
+ explicit PermissionRestorer(const FilePath& path);
+ ~PermissionRestorer();
+
+ private:
+ const FilePath path_;
+ void* info_; // The opaque stored permission information.
+ size_t length_; // The length of the stored permission information.
+
+ DISALLOW_COPY_AND_ASSIGN(PermissionRestorer);
+};
+
} // namespace file_util
#endif // BASE_TEST_TEST_FILE_UTIL_H_
diff --git a/base/test/test_file_util_posix.cc b/base/test/test_file_util_posix.cc
index 0096c9e..67c450f 100644
--- a/base/test/test_file_util_posix.cc
+++ b/base/test/test_file_util_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -32,6 +32,43 @@ bool DenyFilePermission(const FilePath& path, mode_t permission) {
return rv == 0;
}
+// Gets a blob indicating the permission information for |path|.
+// |length| is the length of the blob. Zero on failure.
+// Returns the blob pointer, or NULL on failure.
+void* GetPermissionInfo(const FilePath& path, size_t* length) {
+ DCHECK(length);
+ *length = 0;
+
+ struct stat stat_buf;
+ if (stat(path.value().c_str(), &stat_buf) != 0)
+ return NULL;
+
+ *length = sizeof(mode_t);
+ mode_t* mode = new mode_t;
+ *mode = stat_buf.st_mode & ~S_IFMT; // Filter out file/path kind.
+
+ return mode;
+}
+
+// Restores the permission information for |path|, given the blob retrieved
+// using |GetPermissionInfo()|.
+// |info| is the pointer to the blob.
+// |length| is the length of the blob.
+// Either |info| or |length| may be NULL/0, in which case nothing happens.
+bool RestorePermissionInfo(const FilePath& path, void* info, size_t length) {
+ if (!info || (length == 0))
+ return false;
+
+ DCHECK_EQ(sizeof(mode_t), length);
+ mode_t* mode = reinterpret_cast<mode_t*>(info);
+
+ int rv = HANDLE_EINTR(chmod(path.value().c_str(), *mode));
+
+ delete mode;
+
+ return rv == 0;
+}
+
} // namespace
bool DieFileDie(const FilePath& file, bool recurse) {
@@ -140,4 +177,16 @@ bool MakeFileUnwritable(const FilePath& path) {
return DenyFilePermission(path, S_IWUSR | S_IWGRP | S_IWOTH);
}
+PermissionRestorer::PermissionRestorer(const FilePath& path)
+ : path_(path), info_(NULL), length_(0) {
+ info_ = GetPermissionInfo(path_, &length_);
+ DCHECK(info_ != NULL);
+ DCHECK_NE(0u, length_);
+}
+
+PermissionRestorer::~PermissionRestorer() {
+ if (!RestorePermissionInfo(path_, info_, length_))
+ NOTREACHED();
+}
+
} // namespace file_util
diff --git a/base/test/test_file_util_win.cc b/base/test/test_file_util_win.cc
index f028080..41d69ea 100644
--- a/base/test/test_file_util_win.cc
+++ b/base/test/test_file_util_win.cc
@@ -23,6 +23,11 @@ static const ptrdiff_t kOneMB = 1024 * 1024;
namespace {
+struct PermissionInfo {
+ PSECURITY_DESCRIPTOR security_descriptor;
+ ACL dacl;
+};
+
// Deny |permission| on the file |path|, for the current user.
bool DenyFilePermission(const FilePath& path, DWORD permission) {
PACL old_dacl;
@@ -59,6 +64,52 @@ bool DenyFilePermission(const FilePath& path, DWORD permission) {
return rc == ERROR_SUCCESS;
}
+// Gets a blob indicating the permission information for |path|.
+// |length| is the length of the blob. Zero on failure.
+// Returns the blob pointer, or NULL on failure.
+void* GetPermissionInfo(const FilePath& path, size_t* length) {
+ DCHECK(length != NULL);
+ *length = 0;
+ PACL dacl = NULL;
+ PSECURITY_DESCRIPTOR security_descriptor;
+ if (GetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
+ SE_FILE_OBJECT,
+ DACL_SECURITY_INFORMATION, NULL, NULL, &dacl,
+ NULL, &security_descriptor) != ERROR_SUCCESS) {
+ return NULL;
+ }
+ DCHECK(dacl != NULL);
+
+ *length = sizeof(PSECURITY_DESCRIPTOR) + dacl->AclSize;
+ PermissionInfo* info = reinterpret_cast<PermissionInfo*>(new char[*length]);
+ info->security_descriptor = security_descriptor;
+ memcpy(&info->dacl, dacl, dacl->AclSize);
+
+ return info;
+}
+
+// Restores the permission information for |path|, given the blob retrieved
+// using |GetPermissionInfo()|.
+// |info| is the pointer to the blob.
+// |length| is the length of the blob.
+// Either |info| or |length| may be NULL/0, in which case nothing happens.
+bool RestorePermissionInfo(const FilePath& path, void* info, size_t length) {
+ if (!info || !length)
+ return false;
+
+ PermissionInfo* perm = reinterpret_cast<PermissionInfo*>(info);
+
+ DWORD rc = SetNamedSecurityInfo(const_cast<wchar_t*>(path.value().c_str()),
+ SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
+ NULL, NULL, &perm->dacl, NULL);
+ LocalFree(perm->security_descriptor);
+
+ char* char_array = reinterpret_cast<char*>(info);
+ delete [] char_array;
+
+ return rc == ERROR_SUCCESS;
+}
+
} // namespace
bool DieFileDie(const FilePath& file, bool recurse) {
@@ -277,4 +328,16 @@ bool MakeFileUnwritable(const FilePath& path) {
return DenyFilePermission(path, GENERIC_WRITE);
}
+PermissionRestorer::PermissionRestorer(const FilePath& path)
+ : path_(path), info_(NULL), length_(0) {
+ info_ = GetPermissionInfo(path_, &length_);
+ DCHECK(info_ != NULL);
+ DCHECK_NE(0u, length_);
+}
+
+PermissionRestorer::~PermissionRestorer() {
+ if (!RestorePermissionInfo(path_, info_, length_))
+ NOTREACHED();
+}
+
} // namespace file_util