https://bugs.webkit.org/show_bug.cgi?id=176292
<rdar://problem/
34257666>
Reviewed by Andreas Kling.
Source/WebCore:
FileSystemEntry API should ignore hidden files as the user likely does not mean
to expose those when drag'n dropping a folder.
Test: editing/pasteboard/enties-api/datatransfer-items-drop-hidden-file.html
* Modules/entriesapi/DOMFileSystem.cpp:
(WebCore::listDirectoryWithMetadata):
(WebCore::validatePathIsExpectedType):
(WebCore::fileType):
(WebCore::DOMFileSystem::getEntry):
LayoutTests:
Add layout test coverage.
* editing/pasteboard/enties-api/datatransfer-items-drop-getAsEntry-expected.txt:
* editing/pasteboard/enties-api/datatransfer-items-drop-getAsEntry.html:
* editing/pasteboard/enties-api/datatransfer-items-drop-hidden-file-expected.txt: Added.
* editing/pasteboard/enties-api/datatransfer-items-drop-hidden-file.html: Added.
* fast/forms/file/entries-api/resources/testFiles/.hidden.txt: Added.
* fast/forms/file/entries-api/resources/testFiles/.hidden/hidden.txt: Added.
* platform/win/TestExpectations:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221639
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2017-09-05 Chris Dumez <cdumez@apple.com>
+
+ FileSystemEntry API should ignore hidden files
+ https://bugs.webkit.org/show_bug.cgi?id=176292
+ <rdar://problem/34257666>
+
+ Reviewed by Andreas Kling.
+
+ Add layout test coverage.
+
+ * editing/pasteboard/enties-api/datatransfer-items-drop-getAsEntry-expected.txt:
+ * editing/pasteboard/enties-api/datatransfer-items-drop-getAsEntry.html:
+ * editing/pasteboard/enties-api/datatransfer-items-drop-hidden-file-expected.txt: Added.
+ * editing/pasteboard/enties-api/datatransfer-items-drop-hidden-file.html: Added.
+ * fast/forms/file/entries-api/resources/testFiles/.hidden.txt: Added.
+ * fast/forms/file/entries-api/resources/testFiles/.hidden/hidden.txt: Added.
+ * platform/win/TestExpectations:
+
2017-09-05 Matt Lewis <jlewis3@apple.com>
Marked svg/as-image/svg-image-with-data-uri-background.html as flaky.
PASS secondDataTransferItem.kind is "file"
PASS secondDataTransferItem.type is ""
PASS secondFile.name is "testFiles"
-PASS secondFile.size is 204
+PASS secondFile.size is 272
PASS secondFile.type is ""
PASS secondEntry.isDirectory is true
PASS secondEntry.isFile is false
shouldBeEqualToString("secondDataTransferItem.type", "");
secondFile = secondDataTransferItem.getAsFile();
shouldBeEqualToString("secondFile.name", "testFiles");
- shouldBe("secondFile.size", "204"); // Chrome returns folder size, Firefox returns 0.
+ shouldBe("secondFile.size", "272"); // Chrome returns folder size, Firefox returns 0.
shouldBeEqualToString("secondFile.type", "");
secondEntry = secondDataTransferItem.webkitGetAsEntry();
--- /dev/null
+Test that hidden files are not exposed via Entries API
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS dataTransfer.items.length is 1
+PASS directoryEntry.name is "testFiles"
+PASS directoryEntry.fullPath is "/testFiles"
+PASS directoryEntry.isDirectory is true
+PASS foundEntries.length is 4
+PASS ex.name is "NotFoundError"
+PASS ex.name is "NotFoundError"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../editing.js"></script>
+</head>
+<body>
+<div id="dropzone" style="width: 200px; height: 200px; background-color: grey;"></div>
+<script>
+description("Test that hidden files are not exposed via Entries API");
+jsTestIsAsync = true;
+
+function getFileAsPromise(dirEntry, path)
+{
+ return new Promise((resolve, reject) => {
+ dirEntry.getFile(path, {}, resolve, reject);
+ });
+}
+
+function getDirectoryAsPromise(dirEntry, path)
+{
+ return new Promise((resolve, reject) => {
+ dirEntry.getDirectory(path, {}, resolve, reject);
+ });
+}
+
+function getEntriesAsPromise(dirEntry) {
+ return new Promise((resolve, reject) => {
+ let result = [];
+ let reader = dirEntry.createReader();
+ let doBatch = () => {
+ reader.readEntries(entries => {
+ if (entries.length > 0) {
+ entries.forEach(e => result.push(e));
+ doBatch();
+ } else {
+ resolve(result);
+ }
+ }, reject);
+ };
+ doBatch();
+ });
+}
+
+function readEntriesTest()
+{
+ shouldBeEqualToString("directoryEntry.name", "testFiles");
+ shouldBeEqualToString("directoryEntry.fullPath", "/testFiles");
+ shouldBeTrue("directoryEntry.isDirectory");
+
+ return getEntriesAsPromise(directoryEntry).then(entries => {
+ foundEntries = entries;
+ shouldBe("foundEntries.length", "4");
+ for (let entry of entries) {
+ if (entry.name.startsWith(".hidden")) {
+ testFailed("Hidden file was returned by directoryEntry");
+ break;
+ }
+ }
+ }, e => {
+ testFailed("Call to readEntries() failed unexpectedly: " + e);
+ finishJSTest();
+ });
+}
+
+function getFileTest()
+{
+ return getFileAsPromise(directoryEntry, ".hidden.txt").then(fileEntry => {
+ testFailed("Hidden file was returned by getFile()");
+ finishJSTest();
+ }, e => {
+ ex = e;
+ shouldBeEqualToString("ex.name", "NotFoundError");
+ });
+}
+
+function getDirectoryTest()
+{
+ return getDirectoryAsPromise(directoryEntry, ".hidden").then(fileEntry => {
+ testFailed("Hidden directory was returned by getDirectory()");
+ finishJSTest();
+ }, e => {
+ ex = e;
+ shouldBeEqualToString("ex.name", "NotFoundError");
+ });
+}
+
+var dropzone = document.getElementById('dropzone');
+dropzone.ondrop = function(e) {
+ e.preventDefault();
+ dataTransfer = e.dataTransfer;
+
+ shouldBe("dataTransfer.items.length", "1");
+
+ directoryEntry = dataTransfer.items[0].webkitGetAsEntry();
+
+ readEntriesTest().then(getFileTest).then(getDirectoryTest).then(finishJSTest);
+};
+
+dropzone.ondragover = function(ev) {
+ ev.preventDefault();
+}
+
+onload = function() {
+ dragFilesOntoElement(dropzone, ['../../../fast/forms/file/entries-api/resources/testFiles']);
+}
+</script>
+</body>
+</html>
# TODO Missing WebSpeech implementation
webkit.org/b/136224 fast/speechsynthesis [ Skip ]
+# Test is Posix-specific.
+editing/pasteboard/enties-api/datatransfer-items-drop-hidden-file.html [ Skip ]
+
# TODO Impossible to test text-only-zoom from DRT on Windows
webkit.org/b/35013 svg/zoom/text/ [ Skip ]
+2017-09-05 Chris Dumez <cdumez@apple.com>
+
+ FileSystemEntry API should ignore hidden files
+ https://bugs.webkit.org/show_bug.cgi?id=176292
+ <rdar://problem/34257666>
+
+ Reviewed by Andreas Kling.
+
+ FileSystemEntry API should ignore hidden files as the user likely does not mean
+ to expose those when drag'n dropping a folder.
+
+ Test: editing/pasteboard/enties-api/datatransfer-items-drop-hidden-file.html
+
+ * Modules/entriesapi/DOMFileSystem.cpp:
+ (WebCore::listDirectoryWithMetadata):
+ (WebCore::validatePathIsExpectedType):
+ (WebCore::fileType):
+ (WebCore::DOMFileSystem::getEntry):
+
2017-09-05 Myles C. Maxfield <mmaxfield@apple.com>
Update font selection algorithm to match latest CSS spec
listedChildren.reserveInitialCapacity(childPaths.size());
for (auto& childPath : childPaths) {
auto metadata = fileMetadata(childPath);
- if (!metadata)
+ if (!metadata || metadata.value().isHidden)
continue;
listedChildren.uncheckedAppend(ListedChild { pathGetFileName(childPath), metadata.value().type });
}
ASSERT(!isMainThread());
auto metadata = fileMetadata(fullPath);
- if (!metadata)
+ if (!metadata || metadata.value().isHidden)
return Exception { NotFoundError, ASCIILiteral("Path does not exist") };
if (metadata.value().type != expectedType)
return WTFMove(virtualPath);
}
+static std::optional<FileMetadata::Type> fileType(const String& fullPath)
+{
+ auto metadata = fileMetadata(fullPath);
+ if (!metadata || metadata.value().isHidden)
+ return std::nullopt;
+ return metadata.value().type;
+}
+
// https://wicg.github.io/entries-api/#resolve-a-relative-path
static String resolveRelativeVirtualPath(StringView baseVirtualPath, StringView relativeVirtualPath)
{
}
m_workQueue->dispatch([this, context = makeRef(context), fullPath = crossThreadCopy(fullPath), resolvedVirtualPath = crossThreadCopy(resolvedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable {
- std::optional<FileMetadata::Type> entryType;
- if (auto metadata = fileMetadata(fullPath))
- entryType = metadata.value().type;
+ auto entryType = fileType(fullPath);
callOnMainThread([this, context = WTFMove(context), resolvedVirtualPath = crossThreadCopy(resolvedVirtualPath), entryType, completionCallback = WTFMove(completionCallback)]() mutable {
if (!entryType) {
completionCallback(Exception { NotFoundError, ASCIILiteral("Cannot find entry at given path") });