зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1736331) for causing failures at test_ioutils_mac_xattr.html. CLOSED TREE
Backed out changeset 3d627a038faa (bug 1736331) Backed out changeset b0df890ed09e (bug 1736331)
This commit is contained in:
Родитель
2696bcc736
Коммит
1ce2eea394
|
@ -235,49 +235,8 @@ namespace IOUtils {
|
|||
* @return A promise that resolves is the attributes were set successfully.
|
||||
*/
|
||||
Promise<void> setWindowsAttributes(DOMString path, optional WindowsFileAttributes attrs = {});
|
||||
#elif defined(XP_MACOSX)
|
||||
/**
|
||||
* Return whether or not the file has a specific extended attribute.
|
||||
*
|
||||
* @param path An absolute path.
|
||||
* @param attr The attribute to check for.
|
||||
*
|
||||
* @return A promise that resolves to whether or not the file has an extended
|
||||
* attribute, or rejects with an error.
|
||||
*/
|
||||
Promise<boolean> hasMacXAttr(DOMString path, UTF8String attr);
|
||||
/**
|
||||
* Return the value of an extended attribute for a file.
|
||||
*
|
||||
* @param path An absolute path.
|
||||
* @param attr The attribute to get the value of.
|
||||
*
|
||||
* @return A promise that resolves to the value of the extended attribute, or
|
||||
* rejects with an error.
|
||||
*/
|
||||
Promise<Uint8Array> getMacXAttr(DOMString path, UTF8String attr);
|
||||
/**
|
||||
* Set the extended attribute on a file.
|
||||
*
|
||||
* @param path An absolute path.
|
||||
* @param attr The attribute to set.
|
||||
* @param value The value of the attribute to set.
|
||||
*
|
||||
* @return A promise that resolves to whether or not the file has an extended
|
||||
* attribute, or rejects with an error.
|
||||
*/
|
||||
Promise<void> setMacXAttr(DOMString path, UTF8String attr, Uint8Array value);
|
||||
/**
|
||||
* Delete the extended attribute on a file.
|
||||
*
|
||||
* @param path An absolute path.
|
||||
* @param attr The attribute to delete.
|
||||
*
|
||||
* @return A promise that resolves if the attribute was deleted, or rejects
|
||||
* with an error.
|
||||
*/
|
||||
Promise<void> delMacXAttr(DOMString path, UTF8String attr);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
[Exposed=Window]
|
||||
|
|
|
@ -59,8 +59,6 @@
|
|||
|
||||
#if defined(XP_WIN)
|
||||
# include "nsILocalFileWin.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
# include "nsILocalFileMac.h"
|
||||
#endif
|
||||
|
||||
#define REJECT_IF_INIT_PATH_FAILED(_file, _path, _promise) \
|
||||
|
@ -158,9 +156,6 @@ template <typename T>
|
|||
static void ResolveJSPromise(Promise* aPromise, T&& aValue) {
|
||||
if constexpr (std::is_same_v<T, Ok>) {
|
||||
aPromise->MaybeResolveWithUndefined();
|
||||
} else if constexpr (std::is_same_v<T, nsTArray<uint8_t>>) {
|
||||
TypedArrayCreator<Uint8Array> array(aValue);
|
||||
aPromise->MaybeResolve(array);
|
||||
} else {
|
||||
aPromise->MaybeResolve(std::forward<T>(aValue));
|
||||
}
|
||||
|
@ -247,9 +242,6 @@ static void RejectJSPromise(Promise* aPromise, const IOUtils::IOError& aError) {
|
|||
aPromise->MaybeRejectWithDataError(
|
||||
errMsg.refOr("Argument is not allowed"_ns));
|
||||
break;
|
||||
case NS_ERROR_NOT_AVAILABLE:
|
||||
aPromise->MaybeRejectWithNotFoundError(errMsg.refOr("Unavailable"_ns));
|
||||
break;
|
||||
case NS_ERROR_ABORT:
|
||||
aPromise->MaybeRejectWithAbortError(errMsg.refOr("Operation aborted"_ns));
|
||||
break;
|
||||
|
@ -785,74 +777,6 @@ already_AddRefed<Promise> IOUtils::SetWindowsAttributes(
|
|||
});
|
||||
}
|
||||
|
||||
#elif defined(XP_MACOSX)
|
||||
|
||||
/* static */
|
||||
already_AddRefed<Promise> IOUtils::HasMacXAttr(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const nsACString& aAttr) {
|
||||
return WithPromiseAndState(aGlobal, [&](Promise* promise, auto& state) {
|
||||
nsCOMPtr<nsIFile> file = new nsLocalFile();
|
||||
REJECT_IF_INIT_PATH_FAILED(file, aPath, promise);
|
||||
|
||||
DispatchAndResolve<bool>(
|
||||
state->mEventQueue, promise,
|
||||
[file = std::move(file), attr = nsCString(aAttr)]() {
|
||||
return HasMacXAttrSync(file, attr);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<Promise> IOUtils::GetMacXAttr(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const nsACString& aAttr) {
|
||||
return WithPromiseAndState(aGlobal, [&](Promise* promise, auto& state) {
|
||||
nsCOMPtr<nsIFile> file = new nsLocalFile();
|
||||
REJECT_IF_INIT_PATH_FAILED(file, aPath, promise);
|
||||
|
||||
DispatchAndResolve<nsTArray<uint8_t>>(
|
||||
state->mEventQueue, promise,
|
||||
[file = std::move(file), attr = nsCString(aAttr)]() {
|
||||
return GetMacXAttrSync(file, attr);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<Promise> IOUtils::SetMacXAttr(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const nsACString& aAttr,
|
||||
const Uint8Array& aValue) {
|
||||
return WithPromiseAndState(aGlobal, [&](Promise* promise, auto& state) {
|
||||
nsCOMPtr<nsIFile> file = new nsLocalFile();
|
||||
REJECT_IF_INIT_PATH_FAILED(file, aPath, promise);
|
||||
|
||||
nsTArray<uint8_t> value(aValue.Data(), aValue.Length());
|
||||
|
||||
DispatchAndResolve<Ok>(state->mEventQueue, promise,
|
||||
[file = std::move(file), attr = nsCString(aAttr),
|
||||
value = std::move(value)] {
|
||||
return SetMacXAttrSync(file, attr, value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<Promise> IOUtils::DelMacXAttr(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const nsACString& aAttr) {
|
||||
return WithPromiseAndState(aGlobal, [&](Promise* promise, auto& state) {
|
||||
nsCOMPtr<nsIFile> file = new nsLocalFile();
|
||||
REJECT_IF_INIT_PATH_FAILED(file, aPath, promise);
|
||||
|
||||
DispatchAndResolve<Ok>(state->mEventQueue, promise,
|
||||
[file = std::move(file), attr = nsCString(aAttr)] {
|
||||
return DelMacXAttrSync(file, attr);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* static */
|
||||
|
@ -1614,95 +1538,7 @@ Result<Ok, IOUtils::IOError> IOUtils::SetWindowsAttributesSync(
|
|||
return Ok{};
|
||||
}
|
||||
|
||||
#elif defined(XP_MACOSX)
|
||||
|
||||
/* static */
|
||||
Result<bool, IOUtils::IOError> IOUtils::HasMacXAttrSync(
|
||||
nsIFile* aFile, const nsCString& aAttr) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> file = do_QueryInterface(aFile);
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
bool hasAttr;
|
||||
if (nsresult rv = file->HasXAttr(aAttr, &hasAttr); NS_FAILED(rv)) {
|
||||
return Err(IOError(rv).WithMessage(
|
||||
"Could not read the extended attribute `%s' from the file `%s'",
|
||||
aAttr.get(), aFile->HumanReadablePath().get()));
|
||||
}
|
||||
|
||||
return hasAttr;
|
||||
}
|
||||
|
||||
/* static */
|
||||
Result<nsTArray<uint8_t>, IOUtils::IOError> IOUtils::GetMacXAttrSync(
|
||||
nsIFile* aFile, const nsCString& aAttr) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> file = do_QueryInterface(aFile);
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
nsTArray<uint8_t> value;
|
||||
if (nsresult rv = file->GetXAttr(aAttr, value); NS_FAILED(rv)) {
|
||||
auto err = IOError(rv);
|
||||
|
||||
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
||||
return Err(err.WithMessage(
|
||||
"The file `%s' does not have an extended attribute `%s'",
|
||||
aFile->HumanReadablePath().get(), aAttr.get()));
|
||||
}
|
||||
|
||||
return Err(err.WithMessage(
|
||||
"Could not read the extended attribute `%s' from the file `%s'",
|
||||
aAttr.get(), aFile->HumanReadablePath().get()));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* static */
|
||||
Result<Ok, IOUtils::IOError> IOUtils::SetMacXAttrSync(
|
||||
nsIFile* aFile, const nsCString& aAttr, const nsTArray<uint8_t>& aValue) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> file = do_QueryInterface(aFile);
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
if (nsresult rv = file->SetXAttr(aAttr, aValue); NS_FAILED(rv)) {
|
||||
return Err(IOError(rv).WithMessage(
|
||||
"Could not set extended attribute `%s' on file `%s'", aAttr.get(),
|
||||
aFile->HumanReadablePath().get()));
|
||||
}
|
||||
|
||||
return Ok{};
|
||||
}
|
||||
|
||||
/* static */
|
||||
Result<Ok, IOUtils::IOError> IOUtils::DelMacXAttrSync(nsIFile* aFile,
|
||||
const nsCString& aAttr) {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> file = do_QueryInterface(aFile);
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
if (nsresult rv = file->DelXAttr(aAttr); NS_FAILED(rv)) {
|
||||
auto err = IOError(rv);
|
||||
|
||||
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
||||
return Err(err.WithMessage(
|
||||
"The file `%s' does not have an extended attribute `%s'",
|
||||
aFile->HumanReadablePath().get(), aAttr.get()));
|
||||
}
|
||||
|
||||
return Err(IOError(rv).WithMessage(
|
||||
"Could not delete extended attribute `%s' on file `%s'", aAttr.get(),
|
||||
aFile->HumanReadablePath().get()));
|
||||
}
|
||||
|
||||
return Ok{};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // XP_WIN
|
||||
|
||||
/* static */
|
||||
void IOUtils::GetProfileBeforeChange(GlobalObject& aGlobal,
|
||||
|
|
|
@ -131,20 +131,6 @@ class IOUtils final {
|
|||
static already_AddRefed<Promise> SetWindowsAttributes(
|
||||
GlobalObject& aGlobal, const nsAString& aPath,
|
||||
const mozilla::dom::WindowsFileAttributes& aAttrs);
|
||||
#elif defined(XP_MACOSX)
|
||||
static already_AddRefed<Promise> HasMacXAttr(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const nsACString& aAttr);
|
||||
static already_AddRefed<Promise> GetMacXAttr(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const nsACString& aAttr);
|
||||
static already_AddRefed<Promise> SetMacXAttr(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const nsACString& aAttr,
|
||||
const Uint8Array& aValue);
|
||||
static already_AddRefed<Promise> DelMacXAttr(GlobalObject& aGlobal,
|
||||
const nsAString& aPath,
|
||||
const nsACString& aAttr);
|
||||
#endif
|
||||
|
||||
static void GetProfileBeforeChange(GlobalObject& aGlobal,
|
||||
|
@ -415,16 +401,6 @@ class IOUtils final {
|
|||
*/
|
||||
static Result<Ok, IOError> SetWindowsAttributesSync(
|
||||
nsIFile* aFile, const uint32_t aSetAttrs, const uint32_t aClearAttrs);
|
||||
#elif defined(XP_MACOSX)
|
||||
static Result<bool, IOError> HasMacXAttrSync(nsIFile* aFile,
|
||||
const nsCString& aAttr);
|
||||
static Result<nsTArray<uint8_t>, IOError> GetMacXAttrSync(
|
||||
nsIFile* aFile, const nsCString& aAttr);
|
||||
static Result<Ok, IOError> SetMacXAttrSync(nsIFile* aFile,
|
||||
const nsCString& aAttr,
|
||||
const nsTArray<uint8_t>& aValue);
|
||||
static Result<Ok, IOError> DelMacXAttrSync(nsIFile* aFile,
|
||||
const nsCString& aAttr);
|
||||
#endif
|
||||
|
||||
enum class EventQueueStatus {
|
||||
|
|
|
@ -6,8 +6,6 @@ support-files =
|
|||
[test_ioutils.html]
|
||||
[test_ioutils_copy_move.html]
|
||||
[test_ioutils_dir_iteration.html]
|
||||
[test_ioutils_mac_xattr.html]
|
||||
skip-if = (os != "mac")
|
||||
[test_ioutils_mkdir.html]
|
||||
[test_ioutils_read_write.html]
|
||||
[test_ioutils_read_write_json.html]
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
- http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test the IOUtils file I/O API</title>
|
||||
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
<script src="file_ioutils_test_fixtures.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
const { Assert } = ChromeUtils.import("resource://testing-common/Assert.jsm");
|
||||
const { FileUtils } = ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
const ATTR = "bogus.attr";
|
||||
|
||||
add_task(async function getSetWindowsAttributes() {
|
||||
const bogus = new TextEncoder().encode("bogus");
|
||||
|
||||
const tmpDir = PathUtils.join(await PathUtils.getTempDir(), "ioutils-macos-xattr.tmp.d");
|
||||
await createDir(tmpDir)
|
||||
|
||||
const path = PathUtils.join(tmpDir, "file.tmp");
|
||||
await IOUtils.writeUTF8(path, "");
|
||||
|
||||
ok(
|
||||
!await IOUtils.hasMacXAttr(path, ATTR),
|
||||
"File does not have an extended attribute at creation"
|
||||
);
|
||||
|
||||
info("Testing getting an attribute that does not exist");
|
||||
await Assert.rejects(
|
||||
IOUtils.getMacXAttr(path, ATTR),
|
||||
/NotFoundError: The file `.+' does not have an extended attribute/,
|
||||
"IOUtils::getMacXAttr rejects when the attribute does not exist"
|
||||
);
|
||||
|
||||
info("Testing setting an attribute");
|
||||
await IOUtils.setMacXAttr(ATTR, new TextEncoder().encode("bogus"));
|
||||
ok(
|
||||
await IOUtils.hasMacXAttr(path, ATTR),
|
||||
"File has extended attribute after setting"
|
||||
);
|
||||
|
||||
{
|
||||
info("Testing getting an attribute")
|
||||
const value = await IOUtils.getMacXAttr(ATTR);
|
||||
Assert.equal(value, bogus, "Attribute value should match");
|
||||
}
|
||||
|
||||
info("Testing removing an attribute");
|
||||
await IOUtils.delMacXAttr(ATTR);
|
||||
await Assert.rejects(
|
||||
IOUtils.getMacXAttr(path, ATTR),
|
||||
/NotFoundError: The file `.+' does not have an extended attribute/,
|
||||
"IOUtils::delMacXAttr removes the attribute"
|
||||
);
|
||||
|
||||
ok(
|
||||
await IOUtils.hasMacXAttr(path, ATTR),
|
||||
"File does not have extended attribute after removing"
|
||||
);
|
||||
|
||||
info("Testing removing an attribute that does not exist");
|
||||
await Assert.rejects(
|
||||
await IOUtils.delMacXAttr(ATTR),
|
||||
/NotFoundError: The file `.+' does not have an extended attribute/,
|
||||
"IOUtils::delMacXAttr rejects when the attribute does not exist"
|
||||
);
|
||||
|
||||
await cleanup(tmpDir);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -168,39 +168,6 @@ interface nsILocalFileMac : nsIFile
|
|||
* this is the same as lastModifiedTime.
|
||||
*/
|
||||
readonly attribute int64_t bundleContentsLastModifiedTime;
|
||||
|
||||
/**
|
||||
* Return whether or not the file has an extended attribute.
|
||||
*
|
||||
* @param aAttrName The attribute name to check for.
|
||||
*
|
||||
* @return Whether or not the extended attribute is present.
|
||||
*/
|
||||
bool hasXAttr(in ACString aAttrName);
|
||||
|
||||
/**
|
||||
* Get the value of the extended attribute.
|
||||
*
|
||||
* @param aAttrName The attribute name to read.
|
||||
*
|
||||
* @return The extended attribute value.
|
||||
*/
|
||||
Array<uint8_t> getXAttr(in ACString aAttrName);
|
||||
|
||||
/**
|
||||
* Set an extended attribute.
|
||||
*
|
||||
* @param aAttrName The attribute name to set a value for.
|
||||
* @param aAttrValue The value to set for the attribute.
|
||||
*/
|
||||
void setXAttr(in ACString aAttrName, in Array<uint8_t> aAttrValue);
|
||||
|
||||
/**
|
||||
* Delete an extended attribute.
|
||||
*
|
||||
* @param aAttrName The extended attribute to delete.
|
||||
*/
|
||||
void delXAttr(in ACString aAttrName);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
|
|
@ -109,11 +109,6 @@ inline nsresult nsresultForErrno(int aErr) {
|
|||
case EFBIG: /* File too large. */
|
||||
return NS_ERROR_FILE_TOO_BIG;
|
||||
|
||||
#ifdef ENOATTR
|
||||
case ENOATTR:
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
#endif // ENOATTR
|
||||
|
||||
default:
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -917,7 +917,11 @@ nsLocalFile::CopyToNative(nsIFile* aNewParent, const nsACString& aNewName) {
|
|||
|
||||
#if defined(XP_MACOSX)
|
||||
bool quarantined = true;
|
||||
(void)HasXAttr("com.apple.quarantine"_ns, &quarantined);
|
||||
if (getxattr(mPath.get(), "com.apple.quarantine", nullptr, 0, 0, 0) == -1) {
|
||||
if (errno == ENOATTR) {
|
||||
quarantined = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PRFileDesc* oldFD;
|
||||
|
@ -1003,7 +1007,7 @@ nsLocalFile::CopyToNative(nsIFile* aNewParent, const nsACString& aNewName) {
|
|||
else if (!quarantined) {
|
||||
// If the original file was not in quarantine, lift the quarantine that
|
||||
// file creation added because of LSFileQuarantineEnabled.
|
||||
(void)newFile->DelXAttr("com.apple.quarantine"_ns);
|
||||
removexattr(newPathName.get(), "com.apple.quarantine", 0);
|
||||
}
|
||||
#endif // defined(XP_MACOSX)
|
||||
|
||||
|
@ -2277,86 +2281,6 @@ nsresult NS_NewLocalFile(const nsAString& aPath, bool aFollowLinks,
|
|||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::HasXAttr(const nsACString& aAttrName, bool* aHasAttr) {
|
||||
NS_ENSURE_ARG_POINTER(aHasAttr);
|
||||
|
||||
nsAutoCString attrName{aAttrName};
|
||||
|
||||
ssize_t size = getxattr(mPath.get(), attrName.get(), nullptr, 0, 0, 0);
|
||||
if (size == -1) {
|
||||
if (errno == ENOATTR) {
|
||||
*aHasAttr = false;
|
||||
} else {
|
||||
return NSRESULT_FOR_ERRNO();
|
||||
}
|
||||
}
|
||||
|
||||
*aHasAttr = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::GetXAttr(const nsACString& aAttrName,
|
||||
nsTArray<uint8_t>& aAttrValue) {
|
||||
aAttrValue.Clear();
|
||||
|
||||
nsAutoCString attrName{aAttrName};
|
||||
|
||||
ssize_t size = getxattr(mPath.get(), attrName.get(), nullptr, 0, 0, 0);
|
||||
|
||||
if (size == -1) {
|
||||
return NSRESULT_FOR_ERRNO();
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
aAttrValue.SetCapacity(size);
|
||||
|
||||
// The attribute can change between our first call and this call, so we need
|
||||
// to re-check the size and possibly call with a larger buffer.
|
||||
ssize_t newSize = getxattr(mPath.get(), attrName.get(),
|
||||
aAttrValue.Elements(), size, 0, 0);
|
||||
if (newSize == -1) {
|
||||
return NSRESULT_FOR_ERRNO();
|
||||
}
|
||||
|
||||
if (newSize <= size) {
|
||||
aAttrValue.SetLength(newSize);
|
||||
break;
|
||||
} else {
|
||||
size = newSize;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::SetXAttr(const nsACString& aAttrName,
|
||||
const nsTArray<uint8_t>& aAttrValue) {
|
||||
nsAutoCString attrName{aAttrName};
|
||||
|
||||
if (setxattr(mPath.get(), attrName.get(), aAttrValue.Elements(),
|
||||
aAttrValue.Length(), 0, 0) == -1) {
|
||||
return NSRESULT_FOR_ERRNO();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::DelXAttr(const nsACString& aAttrName) {
|
||||
nsAutoCString attrName{aAttrName};
|
||||
|
||||
// Ignore removing an attribute that does not exist.
|
||||
if (removexattr(mPath.get(), attrName.get(), 0) == -1) {
|
||||
return NSRESULT_FOR_ERRNO();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult MacErrorMapper(OSErr inErr) {
|
||||
nsresult outErr;
|
||||
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const { Assert } = ChromeUtils.import("resource://testing-common/Assert.jsm");
|
||||
const { FileUtils } = ChromeUtils.import(
|
||||
"resource://gre/modules/FileUtils.jsm"
|
||||
);
|
||||
|
||||
async function run_test() {
|
||||
const path = PathUtils.join(await IOUtils.getTempDir(), "macos-xattrs.tmp.d");
|
||||
await IOUtils.makeDirectory(path);
|
||||
|
||||
try {
|
||||
test_macos_xattr(path);
|
||||
} finally {
|
||||
await IOUtils.remove(path, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
async function test_macos_xattr(tmpDir) {
|
||||
const encoder = new TextEncoder();
|
||||
const path = PathUtils.join(tmpDir, "file.tmp");
|
||||
|
||||
await IOUtils.writeUTF8(path, "");
|
||||
|
||||
const file = new FileUtils.File(path);
|
||||
file.queryInterface(Cc.nsILocalFileMac);
|
||||
|
||||
info("Testing reading an attribute that does not exist");
|
||||
Assert.ok(
|
||||
!file.hasXAttr("bogus.attr"),
|
||||
"File should not have attribute before being set."
|
||||
);
|
||||
Assert.throws(
|
||||
() => file.getXAttr("bogus.attr"),
|
||||
/NS_ERROR_NOT_AVAILABLE/,
|
||||
"Attempting to get an attribute that does not exist throws"
|
||||
);
|
||||
|
||||
{
|
||||
info("Testing setting and reading an attribute");
|
||||
file.setXAttr("bogus.attr", encoder.encode("bogus"));
|
||||
Assert.ok(
|
||||
file.hasXAttr("bogus.attr"),
|
||||
"File should have attribute after being set"
|
||||
);
|
||||
const result = file.getXAttr("bogus.attr");
|
||||
|
||||
Assert.equal(
|
||||
result,
|
||||
encoder.encode("bogus"),
|
||||
"File should have attribute value matching what was set"
|
||||
);
|
||||
}
|
||||
|
||||
info("Testing removing an attribute");
|
||||
file.delXAttr("bogus.attr");
|
||||
Assert.ok(
|
||||
!file.hasXAttr("bogus.attr"),
|
||||
"File should no longer have the attribute after removal"
|
||||
);
|
||||
Assert.throws(
|
||||
() => file.getXAttr("bogus.attr"),
|
||||
/NS_ERROR_NOT_AVAILABLE/,
|
||||
"Attempting to get an attribute after removal results in an error"
|
||||
);
|
||||
|
||||
info("Testing removing an attribute that does not exist");
|
||||
Assert.throws(
|
||||
() => file.delXAttr("bogus.attr"),
|
||||
/NS_ERROR_NOT_AVAILABLE/,
|
||||
"Attempting to remove an attribute that does not exist throws"
|
||||
);
|
||||
}
|
|
@ -31,8 +31,6 @@ fail-if = os == "android"
|
|||
[test_ioutil.js]
|
||||
[test_localfile.js]
|
||||
[test_mac_bundle.js]
|
||||
[test_mac_xattrs.js]
|
||||
skip-if = os != "mac"
|
||||
[test_nsIMutableArray.js]
|
||||
[test_nsIProcess.js]
|
||||
skip-if = os == "win" || os == "linux" || os == "android" # bug 582821, bug 1325609, Bug 676998, Bug 1631671
|
||||
|
|
Загрузка…
Ссылка в новой задаче