10de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 20de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 30de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)// found in the LICENSE file. 40de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 50de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "net/base/filename_util.h" 60de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 70de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "base/bind.h" 80de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "base/files/file_path.h" 90de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "base/i18n/file_util_icu.h" 100de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "base/strings/string16.h" 110de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "net/base/filename_util_internal.h" 120de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 130de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)class GURL; 140de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 150de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)namespace net { 160de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 170de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)bool IsSafePortablePathComponent(const base::FilePath& component) { 180de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) base::string16 component16; 190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) base::FilePath::StringType sanitized = component.value(); 200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) SanitizeGeneratedFileName(&sanitized, true); 210de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) base::FilePath::StringType extension = component.Extension(); 220de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (!extension.empty()) 230de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) extension.erase(extension.begin()); // Erase preceding '.'. 240de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return !component.empty() && (component == component.BaseName()) && 250de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) (component == component.StripTrailingSeparators()) && 260de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) FilePathToString16(component, &component16) && 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::i18n::IsFilenameLegal(component16) && 280de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) !IsShellIntegratedExtension(extension) && 290de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) (sanitized == component.value()) && !IsReservedName(component.value()); 300de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 310de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 320de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)bool IsSafePortableRelativePath(const base::FilePath& path) { 330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (path.empty() || path.IsAbsolute() || path.EndsWithSeparator()) 340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return false; 350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) std::vector<base::FilePath::StringType> components; 360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) path.GetComponents(&components); 370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (components.empty()) 380de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return false; 390de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) for (size_t i = 0; i < components.size() - 1; ++i) { 400de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (!IsSafePortablePathComponent(base::FilePath(components[i]))) 410de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return false; 420de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) } 430de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return IsSafePortablePathComponent(path.BaseName()); 440de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 450de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 460de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)base::string16 GetSuggestedFilename(const GURL& url, 470de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& content_disposition, 480de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& referrer_charset, 490de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& suggested_name, 500de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& mime_type, 510de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& default_name) { 520de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return GetSuggestedFilenameImpl( 530de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) url, 540de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) content_disposition, 550de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) referrer_charset, 560de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) suggested_name, 570de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) mime_type, 580de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) default_name, 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&base::i18n::ReplaceIllegalCharactersInPath)); 600de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 610de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 620de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)base::FilePath GenerateFileName(const GURL& url, 630de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& content_disposition, 640de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& referrer_charset, 650de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& suggested_name, 660de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& mime_type, 670de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) const std::string& default_file_name) { 680de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) base::FilePath generated_name(GenerateFileNameImpl( 690de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) url, 700de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) content_disposition, 710de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) referrer_charset, 720de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) suggested_name, 730de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) mime_type, 740de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) default_file_name, 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&base::i18n::ReplaceIllegalCharactersInPath))); 760de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 770de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#if defined(OS_CHROMEOS) 780de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // When doing file manager operations on ChromeOS, the file paths get 790de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // normalized in WebKit layer, so let's ensure downloaded files have 800de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // normalized names. Otherwise, we won't be able to handle files with NFD 810de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // utf8 encoded characters in name. 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::i18n::NormalizeFileNameEncoding(&generated_name); 830de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#endif 840de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 850de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DCHECK(!generated_name.empty()); 860de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 870de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) return generated_name; 880de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} 890de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) 900de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)} // namespace net 91