Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(744)

Side by Side Diff: chrome/browser/download/download_path_reservation_tracker.cc

Issue 2136673002: [Downloads] Path collision check should be case insensitive. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/download/download_path_reservation_tracker.h" 5 #include "chrome/browser/download/download_path_reservation_tracker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <map> 9 #include <map>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/files/file_path.h"
13 #include "base/files/file_util.h" 14 #include "base/files/file_util.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/macros.h" 16 #include "base/macros.h"
16 #include "base/path_service.h" 17 #include "base/path_service.h"
17 #include "base/stl_util.h" 18 #include "base/stl_util.h"
18 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
19 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
20 #include "base/third_party/icu/icu_utf.h" 21 #include "base/third_party/icu/icu_utf.h"
21 #include "build/build_config.h" 22 #include "build/build_config.h"
22 #include "chrome/common/chrome_paths.h" 23 #include "chrome/common/chrome_paths.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 75
75 DISALLOW_COPY_AND_ASSIGN(DownloadItemObserver); 76 DISALLOW_COPY_AND_ASSIGN(DownloadItemObserver);
76 }; 77 };
77 78
78 // Returns true if the given path is in use by a path reservation. 79 // Returns true if the given path is in use by a path reservation.
79 bool IsPathReserved(const base::FilePath& path) { 80 bool IsPathReserved(const base::FilePath& path) {
80 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 81 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
81 // No reservation map => no reservations. 82 // No reservation map => no reservations.
82 if (g_reservation_map == NULL) 83 if (g_reservation_map == NULL)
83 return false; 84 return false;
84 // Unfortunately path normalization doesn't work reliably for non-existant 85
85 // files. So given a FilePath, we can't derive a normalized key that we can 86 // We only expect a small number of concurrent downloads at any given time, so
86 // use for lookups. We only expect a small number of concurrent downloads at 87 // going through all of them shouldn't be too slow.
87 // any given time, so going through all of them shouldn't be too slow.
88 for (ReservationMap::const_iterator iter = g_reservation_map->begin(); 88 for (ReservationMap::const_iterator iter = g_reservation_map->begin();
89 iter != g_reservation_map->end(); ++iter) { 89 iter != g_reservation_map->end(); ++iter) {
90 if (iter->second == path) 90 if (base::FilePath::CompareEqualIgnoreCase(iter->second.value(),
91 path.value()))
91 return true; 92 return true;
92 } 93 }
93 return false; 94 return false;
94 } 95 }
95 96
96 // Returns true if the given path is in use by any path reservation or the 97 // Returns true if the given path is in use by any path reservation or the
97 // file system. Called on the FILE thread. 98 // file system. Called on the FILE thread.
98 bool IsPathInUse(const base::FilePath& path) { 99 bool IsPathInUse(const base::FilePath& path) {
99 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 100 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
100 // If there is a reservation, then the path is in use. 101 // If there is a reservation, then the path is in use.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 bool create_directory, 163 bool create_directory,
163 DownloadPathReservationTracker::FilenameConflictAction conflict_action, 164 DownloadPathReservationTracker::FilenameConflictAction conflict_action,
164 base::FilePath* reserved_path) { 165 base::FilePath* reserved_path) {
165 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 166 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
166 DCHECK(suggested_path.IsAbsolute()); 167 DCHECK(suggested_path.IsAbsolute());
167 168
168 // Create a reservation map if one doesn't exist. It will be automatically 169 // Create a reservation map if one doesn't exist. It will be automatically
169 // deleted when all the reservations are revoked. 170 // deleted when all the reservations are revoked.
170 if (g_reservation_map == NULL) 171 if (g_reservation_map == NULL)
171 g_reservation_map = new ReservationMap; 172 g_reservation_map = new ReservationMap;
172 ReservationMap& reservations = *g_reservation_map;
173 173
174 // Erase the reservation if it already exists. This can happen during 174 // Erase the reservation if it already exists. This can happen during
175 // automatic resumption where a new target determination request may be issued 175 // automatic resumption where a new target determination request may be issued
176 // for a DownloadItem without an intervening transition to INTERRUPTED. 176 // for a DownloadItem without an intervening transition to INTERRUPTED.
177 // 177 //
178 // Revoking and re-acquiring the reservation forces us to re-verify the claims 178 // Revoking and re-acquiring the reservation forces us to re-verify the claims
179 // we are making about the path. 179 // we are making about the path.
180 reservations.erase(key); 180 g_reservation_map->erase(key);
181 181
182 base::FilePath target_path(suggested_path.NormalizePathSeparators()); 182 base::FilePath target_path(suggested_path.NormalizePathSeparators());
183 base::FilePath target_dir = target_path.DirName(); 183 base::FilePath target_dir = target_path.DirName();
184 base::FilePath filename = target_path.BaseName(); 184 base::FilePath filename = target_path.BaseName();
185 bool is_path_writeable = true; 185 bool is_path_writeable = true;
186 bool has_conflicts = false; 186 bool has_conflicts = false;
187 bool name_too_long = false; 187 bool name_too_long = false;
188 188
189 // Create target_dir if necessary and appropriate. target_dir may be the last 189 // Create target_dir if necessary and appropriate. target_dir may be the last
190 // directory that the user selected in a FilePicker; if that directory has 190 // directory that the user selected in a FilePicker; if that directory has
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 if (!IsPathInUse(path_to_check)) { 246 if (!IsPathInUse(path_to_check)) {
247 target_path = path_to_check; 247 target_path = path_to_check;
248 has_conflicts = false; 248 has_conflicts = false;
249 break; 249 break;
250 } 250 }
251 } 251 }
252 } 252 }
253 } 253 }
254 } 254 }
255 255
256 reservations[key] = target_path; 256 (*g_reservation_map)[key] = target_path;
257 bool verified = (is_path_writeable && !has_conflicts && !name_too_long); 257 bool verified = (is_path_writeable && !has_conflicts && !name_too_long);
258 *reserved_path = target_path; 258 *reserved_path = target_path;
259 return verified; 259 return verified;
260 } 260 }
261 261
262 // Called on the FILE thread to update the path of the reservation associated 262 // Called on the FILE thread to update the path of the reservation associated
263 // with |key| to |new_path|. 263 // with |key| to |new_path|.
264 void UpdateReservation(ReservationKey key, const base::FilePath& new_path) { 264 void UpdateReservation(ReservationKey key, const base::FilePath& new_path) {
265 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 265 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
266 DCHECK(g_reservation_map != NULL); 266 DCHECK(g_reservation_map != NULL);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 base::Bind(&RunGetReservedPathCallback, 389 base::Bind(&RunGetReservedPathCallback,
390 callback, 390 callback,
391 base::Owned(reserved_path))); 391 base::Owned(reserved_path)));
392 } 392 }
393 393
394 // static 394 // static
395 bool DownloadPathReservationTracker::IsPathInUseForTesting( 395 bool DownloadPathReservationTracker::IsPathInUseForTesting(
396 const base::FilePath& path) { 396 const base::FilePath& path) {
397 return IsPathInUse(path); 397 return IsPathInUse(path);
398 } 398 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698