Changeset 221510 in webkit
- Timestamp:
- Sep 1, 2017 5:19:55 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r221507 r221510 1 2017-09-01 Chris Dumez <cdumez@apple.com> 2 3 Implement FileSystemDirectoryEntry.getFile() 4 https://bugs.webkit.org/show_bug.cgi?id=176167 5 <rdar://problem/34187775> 6 7 Reviewed by Andreas Kling. 8 9 Add layout test coverage. 10 11 * editing/pasteboard/datatransfer-items-drop-getFile-expected.txt: Added. 12 * editing/pasteboard/datatransfer-items-drop-getFile.html: Added. 13 1 14 2017-09-01 Matt Lewis <jlewis3@apple.com> 2 15 -
trunk/LayoutTests/platform/wk2/TestExpectations
r221481 r221510 568 568 editing/pasteboard/datatransfer-items-drop-directoryReader-root.html 569 569 editing/pasteboard/datatransfer-items-drop-getAsEntry.html 570 editing/pasteboard/datatransfer-items-drop-getFile.html 570 571 editing/pasteboard/datatransfer-items-drop-getParent-root.html 571 572 editing/pasteboard/datatransfer-items-drop-getParent.html -
trunk/Source/WebCore/ChangeLog
r221509 r221510 1 2017-09-01 Chris Dumez <cdumez@apple.com> 2 3 Implement FileSystemDirectoryEntry.getFile() 4 https://bugs.webkit.org/show_bug.cgi?id=176167 5 <rdar://problem/34187775> 6 7 Reviewed by Andreas Kling. 8 9 Implement FileSystemDirectoryEntry.getFile(): 10 - https://wicg.github.io/entries-api/#dom-filesystemdirectoryentry-getfile 11 12 Test: editing/pasteboard/datatransfer-items-drop-getFile.html 13 14 * Modules/entriesapi/DOMFileSystem.cpp: 15 (WebCore::isValidPathNameCharacter): 16 (WebCore::isValidPathSegment): 17 (WebCore::isValidRelativeVirtualPath): 18 (WebCore::isValidAbsoluteVirtualPath): 19 (WebCore::isValidVirtualPath): 20 Implement various path validation functions as per: 21 - https://wicg.github.io/entries-api/#names-paths 22 23 (WebCore::resolveRelativeVirtualPath): 24 - Use StringView for second parameter for efficiency. Had to keep 25 a String for the first parameter because I need the split to 26 return a Vector. 27 - If the input path is absolute, call recursively with '/' as 28 base path so that the virtual path gets sanitized (i.e. '..' 29 and '.' in the absolute URL get resolved). 30 31 (WebCore::DOMFileSystem::listDirectory): 32 Use String instead of auto. It is not much longer and is clearer. 33 34 (WebCore::validatePathIsDirectory): 35 (WebCore::DOMFileSystem::getParent): 36 Move logic to validate that the path is a directory from getParent() to a 37 separate function. This only makes sure the ScriptExecutionContext is only 38 ref'd / deref'd on the main thread. 39 40 (WebCore::validatePathIsFile): 41 Logic for validating that a path is a file, used by getFile(). 42 43 (WebCore::DOMFileSystem::getFile): 44 Implement getFile() as per: 45 - https://wicg.github.io/entries-api/#dom-filesystemdirectoryentry-getfile 46 47 * Modules/entriesapi/DOMFileSystem.h: 48 * Modules/entriesapi/FileSystemDirectoryEntry.cpp: 49 (WebCore::FileSystemDirectoryEntry::getFile): 50 Add implementation of FileSystemDirectoryEntry::getFile() which merely calls 51 DOMFileSystem::getFile(). 52 1 53 2017-09-01 Brady Eidson <beidson@apple.com> 2 54 -
trunk/Source/WebCore/Modules/entriesapi/DOMFileSystem.cpp
r221481 r221510 88 88 } 89 89 90 static bool isAbsoluteVirtualPath(const String& virtualPath) 91 { 92 return !virtualPath.isEmpty() && virtualPath[0] == '/'; 90 // https://wicg.github.io/entries-api/#name 91 static bool isValidPathNameCharacter(UChar c) 92 { 93 return c != '\0' && c != '/' && c != '\\'; 94 } 95 96 // https://wicg.github.io/entries-api/#path-segment 97 static bool isValidPathSegment(StringView segment) 98 { 99 ASSERT(!segment.isEmpty()); 100 if (segment == "." || segment == "..") 101 return true; 102 103 for (unsigned i = 0; i < segment.length(); ++i) { 104 if (!isValidPathNameCharacter(segment[i])) 105 return false; 106 } 107 return true; 108 } 109 110 // https://wicg.github.io/entries-api/#relative-path 111 static bool isValidRelativeVirtualPath(StringView virtualPath) 112 { 113 if (virtualPath.isEmpty()) 114 return false; 115 116 if (virtualPath[0] == '/') 117 return false; 118 119 auto segments = virtualPath.split('/'); 120 for (auto segment : segments) { 121 if (!isValidPathSegment(segment)) 122 return false; 123 } 124 return true; 125 } 126 127 // https://wicg.github.io/entries-api/#valid-path 128 static bool isValidVirtualPath(StringView virtualPath) 129 { 130 if (virtualPath.isEmpty()) 131 return false; 132 if (virtualPath[0] == '/') 133 return isValidRelativeVirtualPath(virtualPath.substring(1)); 134 return isValidRelativeVirtualPath(virtualPath); 93 135 } 94 136 … … 119 161 120 162 // https://wicg.github.io/entries-api/#resolve-a-relative-path 121 static String resolveRelative Path(const String& virtualPath, const String& relativePath)122 { 123 ASSERT( virtualPath[0] == '/');124 if ( isAbsoluteVirtualPath(relativePath))125 return re lativePath;126 127 auto virtualPathSegments = virtualPath.split('/');128 auto relativePathSegments = relative Path.split('/');129 for (auto &segment : relativePathSegments) {163 static String resolveRelativeVirtualPath(const String& baseVirtualPath, StringView relativeVirtualPath) 164 { 165 ASSERT(baseVirtualPath[0] == '/'); 166 if (relativeVirtualPath[0] == '/') 167 return resolveRelativeVirtualPath(ASCIILiteral("/"), relativeVirtualPath.substring(1)); 168 169 auto virtualPathSegments = baseVirtualPath.split('/'); 170 auto relativePathSegments = relativeVirtualPath.split('/'); 171 for (auto segment : relativePathSegments) { 130 172 ASSERT(!segment.isEmpty()); 131 173 if (segment == ".") … … 136 178 continue; 137 179 } 138 virtualPathSegments.append(segment );180 virtualPathSegments.append(segment.toString()); 139 181 } 140 182 … … 177 219 178 220 String directoryVirtualPath = directory.virtualPath(); 179 autofullPath = evaluatePath(directoryVirtualPath);221 String fullPath = evaluatePath(directoryVirtualPath); 180 222 if (fullPath == m_rootPath) { 181 223 Vector<Ref<FileSystemEntry>> children; … … 193 235 } 194 236 237 static ExceptionOr<String> validatePathIsDirectory(const String& fullPath, String&& virtualPath) 238 { 239 ASSERT(!isMainThread()); 240 241 if (!fileIsDirectory(fullPath, ShouldFollowSymbolicLinks::No)) 242 return Exception { NotFoundError, "Path no longer exists or is no longer a directory" }; 243 return WTFMove(virtualPath); 244 } 245 195 246 void DOMFileSystem::getParent(ScriptExecutionContext& context, FileSystemEntry& entry, GetParentCallback&& completionCallback) 196 247 { 197 String virtualPath = resolveRelativePath(entry.virtualPath(), ASCIILiteral("..")); 248 ASSERT(&entry.filesystem() == this); 249 250 String virtualPath = resolveRelativeVirtualPath(entry.virtualPath(), ".."); 198 251 ASSERT(virtualPath[0] == '/'); 199 252 String fullPath = evaluatePath(virtualPath); 200 253 m_workQueue->dispatch([this, context = makeRef(context), fullPath = crossThreadCopy(fullPath), virtualPath = crossThreadCopy(virtualPath), completionCallback = WTFMove(completionCallback)]() mutable { 201 if (!fileIsDirectory(fullPath, ShouldFollowSymbolicLinks::No)) { 202 callOnMainThread([completionCallback = WTFMove(completionCallback)] { 203 completionCallback(Exception { NotFoundError, "Path no longer exists or is no longer a directory" }); 204 }); 205 return; 206 } 207 callOnMainThread([this, context = WTFMove(context), virtualPath = crossThreadCopy(virtualPath), completionCallback = WTFMove(completionCallback)] { 208 completionCallback(FileSystemDirectoryEntry::create(context, *this, virtualPath)); 254 auto validatedVirtualPath = validatePathIsDirectory(fullPath, WTFMove(virtualPath)); 255 callOnMainThread([this, context = WTFMove(context), validatedVirtualPath = crossThreadCopy(validatedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable { 256 if (validatedVirtualPath.hasException()) 257 completionCallback(validatedVirtualPath.releaseException()); 258 else 259 completionCallback(FileSystemDirectoryEntry::create(context, *this, validatedVirtualPath.releaseReturnValue())); 209 260 }); 210 261 }); 211 262 } 212 263 264 static ExceptionOr<String> validatePathIsFile(const String& fullPath, String&& virtualPath) 265 { 266 ASSERT(!isMainThread()); 267 268 FileMetadata metadata; 269 if (!getFileMetadata(fullPath, metadata, ShouldFollowSymbolicLinks::No)) 270 return Exception { NotFoundError, ASCIILiteral("File does not exist") }; 271 272 if (metadata.type != FileMetadata::TypeFile) 273 return Exception { TypeMismatchError, ASCIILiteral("Entry at path is not a file") }; 274 275 return WTFMove(virtualPath); 276 } 277 278 // https://wicg.github.io/entries-api/#dom-filesystemdirectoryentry-getfile 279 void DOMFileSystem::getFile(ScriptExecutionContext& context, FileSystemDirectoryEntry& directory, const String& virtualPath, const FileSystemDirectoryEntry::Flags& flags, GetFileCallback&& completionCallback) 280 { 281 ASSERT(&directory.filesystem() == this); 282 283 if (!isValidVirtualPath(virtualPath)) { 284 callOnMainThread([completionCallback = WTFMove(completionCallback)] { 285 completionCallback(Exception { TypeMismatchError, ASCIILiteral("Path is invalid") }); 286 }); 287 return; 288 } 289 290 if (flags.create) { 291 callOnMainThread([completionCallback = WTFMove(completionCallback)] { 292 completionCallback(Exception { SecurityError, ASCIILiteral("create flag cannot be true") }); 293 }); 294 return; 295 } 296 297 String resolvedVirtualPath = resolveRelativeVirtualPath(directory.virtualPath(), virtualPath); 298 ASSERT(resolvedVirtualPath[0] == '/'); 299 String fullPath = evaluatePath(resolvedVirtualPath); 300 m_workQueue->dispatch([this, context = makeRef(context), fullPath = crossThreadCopy(fullPath), resolvedVirtualPath = crossThreadCopy(resolvedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable { 301 auto validatedVirtualPath = validatePathIsFile(fullPath, WTFMove(resolvedVirtualPath)); 302 callOnMainThread([this, context = WTFMove(context), validatedVirtualPath = crossThreadCopy(validatedVirtualPath), completionCallback = WTFMove(completionCallback)]() mutable { 303 if (validatedVirtualPath.hasException()) 304 completionCallback(validatedVirtualPath.releaseException()); 305 else 306 completionCallback(FileSystemFileEntry::create(context, *this, validatedVirtualPath.releaseReturnValue())); 307 }); 308 }); 309 } 310 213 311 } // namespace WebCore -
trunk/Source/WebCore/Modules/entriesapi/DOMFileSystem.h
r221481 r221510 27 27 28 28 #include "ExceptionOr.h" 29 #include "FileSystemDirectoryEntry.h" 29 30 #include "ScriptWrappable.h" 30 31 #include <wtf/RefCounted.h> … … 35 36 36 37 class File; 37 class FileSystem DirectoryEntry;38 class FileSystemFileEntry; 38 39 class FileSystemEntry; 39 40 class ScriptExecutionContext; … … 58 59 void getParent(ScriptExecutionContext&, FileSystemEntry&, GetParentCallback&&); 59 60 61 using GetFileCallback = WTF::Function<void(ExceptionOr<Ref<FileSystemFileEntry>>&&)>; 62 void getFile(ScriptExecutionContext&, FileSystemDirectoryEntry&, const String& virtualPath, const FileSystemDirectoryEntry::Flags&, GetFileCallback&&); 63 60 64 private: 61 65 explicit DOMFileSystem(Ref<File>&&); -
trunk/Source/WebCore/Modules/entriesapi/FileSystemDirectoryEntry.cpp
r221481 r221510 28 28 29 29 #include "DOMException.h" 30 #include "DOMFileSystem.h" 30 31 #include "ErrorCallback.h" 31 32 #include "FileSystemDirectoryReader.h" 33 #include "FileSystemEntryCallback.h" 34 #include "FileSystemFileEntry.h" 35 #include "ScriptExecutionContext.h" 32 36 33 37 namespace WebCore { … … 43 47 } 44 48 45 void FileSystemDirectoryEntry::getFile(ScriptExecutionContext& context, const String& , const Flags&, RefPtr<FileSystemEntryCallback>&&, RefPtr<ErrorCallback>&& errorCallback)49 void FileSystemDirectoryEntry::getFile(ScriptExecutionContext& context, const String& path, const Flags& flags, RefPtr<FileSystemEntryCallback>&& successCallback, RefPtr<ErrorCallback>&& errorCallback) 46 50 { 47 if (errorCallback) 48 errorCallback->scheduleCallback(context, DOMException::create(NotSupportedError)); 51 if (!successCallback && !errorCallback) 52 return; 53 54 filesystem().getFile(context, *this, path, flags, [this, pendingActivity = makePendingActivity(*this), successCallback = WTFMove(successCallback), errorCallback = WTFMove(errorCallback)](auto&& result) { 55 if (result.hasException()) { 56 if (errorCallback) 57 errorCallback->handleEvent(DOMException::create(result.releaseException())); 58 return; 59 } 60 if (successCallback) 61 successCallback->handleEvent(result.releaseReturnValue()); 62 }); 49 63 } 50 64
Note: See TracChangeset
for help on using the changeset viewer.