| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/sync/util/path_helpers.h" | |
| 6 | |
| 7 #include <Shlwapi.h> | |
| 8 #include <stdlib.h> | |
| 9 | |
| 10 #include "base/logging.h" | |
| 11 #include "base/port.h" | |
| 12 #include "build/build_config.h" | |
| 13 #include "chrome/browser/sync/syncable/syncable.h" | |
| 14 | |
| 15 #ifndef OS_WIN | |
| 16 #error Compile this file on Windows only. | |
| 17 #endif | |
| 18 | |
| 19 using std::string; | |
| 20 | |
| 21 namespace { | |
| 22 const string kWindowsIllegalBaseFilenames[] = { | |
| 23 "CON", "PRN", "AUX", "NUL", "COM1", "COM2", | |
| 24 "COM3", "COM4", "COM5", "COM6", "COM7", | |
| 25 "COM8", "COM9", "LPT1", "LPT2", "LPT3", | |
| 26 "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", | |
| 27 "LPT9" }; | |
| 28 } | |
| 29 | |
| 30 // See: http://msdn.microsoft.com/library/default.asp?url=/library/ | |
| 31 // en-us/fileio/fs/naming_a_file.asp | |
| 32 // note that * and ? are not listed on the page as illegal characters, | |
| 33 // but they are. | |
| 34 string MakePathComponentOSLegal(const string& component) { | |
| 35 CHECK(!component.empty()); | |
| 36 string mutable_component = component; | |
| 37 | |
| 38 // Remove illegal characters. | |
| 39 for (string::iterator i = mutable_component.begin(); | |
| 40 i != mutable_component.end();) { | |
| 41 if ((string::npos != string("<>:\"/\\|*?").find(*i)) || | |
| 42 ((static_cast<unsigned short>(*i) >= 0) && | |
| 43 (static_cast<unsigned short>(*i) <= 31))) { | |
| 44 mutable_component.erase(i); | |
| 45 } else { | |
| 46 ++i; | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 // Remove trailing spaces or periods. | |
| 51 while (mutable_component.size() && | |
| 52 ((mutable_component.at(mutable_component.size() - 1) == ' ') || | |
| 53 (mutable_component.at(mutable_component.size() - 1) == '.'))) | |
| 54 mutable_component.resize(mutable_component.size() - 1, ' '); | |
| 55 | |
| 56 // Remove a bunch of forbidden names. windows only seems to mind if | |
| 57 // a forbidden name matches our name exactly (e.g. "prn") or if the name is | |
| 58 // the forbidden name, followed by a dot, followed by anything | |
| 59 // (e.g., "prn.anything.foo.bar") | |
| 60 | |
| 61 // From this point out, we break mutable_component into two strings, and use | |
| 62 // them this way: we save anything after and including the first dot (usually | |
| 63 // the extension) and only mess with stuff before the first dot. | |
| 64 string::size_type first_dot = mutable_component.find_first_of('.'); | |
| 65 if (string::npos == first_dot) | |
| 66 first_dot = mutable_component.size(); | |
| 67 string sub = mutable_component.substr(0, first_dot); | |
| 68 string postsub = mutable_component.substr(first_dot); | |
| 69 CHECK(sub + postsub == mutable_component); | |
| 70 for (int i = 0; i < ARRAYSIZE(kWindowsIllegalBaseFilenames); i++) { | |
| 71 // ComparePathNames(a, b) == 0 -> same | |
| 72 if (syncable::ComparePathNames(kWindowsIllegalBaseFilenames[i], sub) == 0) { | |
| 73 sub.append("~1"); | |
| 74 break; | |
| 75 } | |
| 76 } | |
| 77 if (("" == sub) && ("" == postsub)) { | |
| 78 sub = "~1"; | |
| 79 } | |
| 80 | |
| 81 // Return the new name, only if it differs from the original. | |
| 82 if ((sub + postsub) == component) | |
| 83 return ""; | |
| 84 return (sub + postsub); | |
| 85 } | |
| OLD | NEW |