| Index: webkit/fileapi/file_system_util.cc
 | 
| diff --git a/webkit/fileapi/file_system_util.cc b/webkit/fileapi/file_system_util.cc
 | 
| index ed365c65d8f0e66e7d28ffa19eb2da1222ef2ed0..85e3512e1fe24f4695f102fc71cf6db3e27159f3 100644
 | 
| --- a/webkit/fileapi/file_system_util.cc
 | 
| +++ b/webkit/fileapi/file_system_util.cc
 | 
| @@ -20,10 +20,10 @@
 | 
|  
 | 
|  namespace fileapi {
 | 
|  
 | 
| -const char kPersistentDir[] = "/persistent/";
 | 
| -const char kTemporaryDir[] = "/temporary/";
 | 
| -const char kIsolatedDir[] = "/isolated/";
 | 
| -const char kExternalDir[] = "/external/";
 | 
| +const char kPersistentDir[] = "/persistent";
 | 
| +const char kTemporaryDir[] = "/temporary";
 | 
| +const char kIsolatedDir[] = "/isolated";
 | 
| +const char kExternalDir[] = "/external";
 | 
|  
 | 
|  const char kPersistentName[] = "Persistent";
 | 
|  const char kTemporaryName[] = "Temporary";
 | 
| @@ -35,38 +35,11 @@ bool CrackFileSystemURL(const GURL& url, GURL* origin_url, FileSystemType* type,
 | 
|    GURL origin;
 | 
|    FileSystemType file_system_type = kFileSystemTypeUnknown;
 | 
|  
 | 
| -  if (url.scheme() != "filesystem")
 | 
| +  if (!url.is_valid() || !url.SchemeIsFileSystem())
 | 
|      return false;
 | 
| +  DCHECK(url.inner_url());
 | 
|  
 | 
| -  std::string temp = url.path();
 | 
| -  // TODO(ericu): This should probably be done elsewhere after the stackable
 | 
| -  // layers are properly in.  We're supposed to reject any paths that contain
 | 
| -  // '..' segments, but the GURL constructor is helpfully resolving them for us.
 | 
| -  // Make sure there aren't any before we call it.
 | 
| -  size_t pos = temp.find("..");
 | 
| -  for (; pos != std::string::npos; pos = temp.find("..", pos + 1)) {
 | 
| -    if ((pos == 0 || temp[pos - 1] == '/') &&
 | 
| -        (pos == temp.length() - 2 || temp[pos + 2] == '/'))
 | 
| -      return false;
 | 
| -  }
 | 
| -
 | 
| -  // bare_url will look something like:
 | 
| -  //    http://example.com/temporary/dir/file.txt.
 | 
| -  GURL bare_url(temp);
 | 
| -
 | 
| -  // The input URL was malformed, bail out early.
 | 
| -  if (bare_url.path().empty())
 | 
| -    return false;
 | 
| -
 | 
| -  origin = bare_url.GetOrigin();
 | 
| -
 | 
| -  // The input URL was malformed, bail out early.
 | 
| -  if (origin.is_empty())
 | 
| -    return false;
 | 
| -
 | 
| -  std::string path = net::UnescapeURLComponent(bare_url.path(),
 | 
| -      net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS |
 | 
| -      net::UnescapeRule::CONTROL_CHARS);
 | 
| +  std::string inner_path = url.inner_url()->path();
 | 
|  
 | 
|    const struct {
 | 
|      FileSystemType type;
 | 
| @@ -78,9 +51,8 @@ bool CrackFileSystemURL(const GURL& url, GURL* origin_url, FileSystemType* type,
 | 
|      { kFileSystemTypeExternal, kExternalDir },
 | 
|    };
 | 
|    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidTypes); ++i) {
 | 
| -    if (StartsWithASCII(path, kValidTypes[i].dir, true)) {
 | 
| +    if (StartsWithASCII(inner_path, kValidTypes[i].dir, true)) {
 | 
|        file_system_type = kValidTypes[i].type;
 | 
| -      path = path.substr(strlen(kValidTypes[i].dir));
 | 
|        break;
 | 
|      }
 | 
|    }
 | 
| @@ -88,17 +60,27 @@ bool CrackFileSystemURL(const GURL& url, GURL* origin_url, FileSystemType* type,
 | 
|    if (file_system_type == kFileSystemTypeUnknown)
 | 
|      return false;
 | 
|  
 | 
| +  std::string path = net::UnescapeURLComponent(url.path(),
 | 
| +      net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS |
 | 
| +      net::UnescapeRule::CONTROL_CHARS);
 | 
| +
 | 
|    // Ensure the path is relative.
 | 
|    while (!path.empty() && path[0] == '/')
 | 
|      path.erase(0, 1);
 | 
|  
 | 
| +  FilePath converted_path = FilePath::FromUTF8Unsafe(path);
 | 
| +
 | 
| +  // All parent references should have been resolved in the renderer.
 | 
| +  if (converted_path.ReferencesParent())
 | 
| +    return false;
 | 
| +
 | 
|    if (origin_url)
 | 
| -    *origin_url = origin;
 | 
| +    *origin_url = url.GetOrigin();
 | 
|    if (type)
 | 
|      *type = file_system_type;
 | 
|    if (file_path)
 | 
| -    *file_path = FilePath::FromUTF8Unsafe(path).
 | 
| -        NormalizePathSeparators().StripTrailingSeparators();
 | 
| +    *file_path = converted_path.NormalizePathSeparators().
 | 
| +        StripTrailingSeparators();
 | 
|  
 | 
|    return true;
 | 
|  }
 | 
| @@ -149,18 +131,21 @@ void VirtualPath::GetComponents(
 | 
|  }
 | 
|  
 | 
|  GURL GetFileSystemRootURI(const GURL& origin_url, FileSystemType type) {
 | 
| -  std::string path("filesystem:");
 | 
| -  path += origin_url.spec();
 | 
| +  // origin_url is based on a security origin, so http://foo.com or file:///
 | 
| +  // instead of the corresponding filesystem URL.
 | 
| +  DCHECK(!origin_url.SchemeIsFileSystem());
 | 
| +
 | 
| +  std::string url = "filesystem:" + origin_url.GetWithEmptyPath().spec();
 | 
|    switch (type) {
 | 
|    case kFileSystemTypeTemporary:
 | 
| -    path += (kTemporaryDir + 1);  // We don't want the leading slash.
 | 
| -    return GURL(path);
 | 
| +    url += (kTemporaryDir + 1);  // We don't want the leading slash.
 | 
| +    return GURL(url + "/");
 | 
|    case kFileSystemTypePersistent:
 | 
| -    path += (kPersistentDir + 1);  // We don't want the leading slash.
 | 
| -    return GURL(path);
 | 
| +    url += (kPersistentDir + 1);  // We don't want the leading slash.
 | 
| +    return GURL(url + "/");
 | 
|    case kFileSystemTypeExternal:
 | 
| -    path += (kExternalDir + 1);  // We don't want the leading slash.
 | 
| -    return GURL(path);
 | 
| +    url += (kExternalDir + 1);  // We don't want the leading slash.
 | 
| +    return GURL(url + "/");
 | 
|    case kFileSystemTypeIsolated:
 | 
|      // Falling through; we won't call this for isolated filesystems.
 | 
|    case kFileSystemTypeUnknown:
 | 
| 
 |