Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "webkit/browser/database/database_util.h" | 5 #include "webkit/browser/database/database_util.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "webkit/browser/database/database_tracker.h" | 9 #include "webkit/browser/database/database_tracker.h" |
| 10 #include "webkit/browser/database/vfs_backend.h" | 10 #include "webkit/browser/database/vfs_backend.h" |
| 11 #include "webkit/common/database/database_identifier.h" | |
| 11 | 12 |
| 12 namespace webkit_database { | 13 namespace webkit_database { |
| 13 | 14 |
| 15 namespace { | |
| 16 | |
| 17 bool IsSafeSuffix(const base::string16& suffix) { | |
| 18 base::char16 prev_c = 0; | |
| 19 for (base::string16::const_iterator it = suffix.begin(); | |
| 20 it < suffix.end(); ++it) { | |
| 21 base::char16 c = *it; | |
| 22 if (!(IsAsciiAlpha(c) || IsAsciiDigit(c) || c == '-' || c == '.')) | |
| 23 return false; | |
| 24 if (c == '.' && prev_c == '.') | |
| 25 return false; | |
| 26 prev_c = c; | |
| 27 } | |
| 28 return true; | |
| 29 } | |
| 30 | |
| 31 } | |
| 32 | |
| 14 const char DatabaseUtil::kJournalFileSuffix[] = "-journal"; | 33 const char DatabaseUtil::kJournalFileSuffix[] = "-journal"; |
| 15 | 34 |
| 16 bool DatabaseUtil::CrackVfsFileName(const base::string16& vfs_file_name, | 35 bool DatabaseUtil::CrackVfsFileName(const base::string16& vfs_file_name, |
| 17 std::string* origin_identifier, | 36 std::string* origin_identifier, |
| 18 base::string16* database_name, | 37 base::string16* database_name, |
| 19 base::string16* sqlite_suffix) { | 38 base::string16* sqlite_suffix) { |
| 20 // 'vfs_file_name' is of the form <origin_identifier>/<db_name>#<suffix>. | 39 // 'vfs_file_name' is of the form <origin_identifier>/<db_name>#<suffix>. |
| 21 // <suffix> is optional. | 40 // <suffix> is optional. |
| 22 DCHECK(!vfs_file_name.empty()); | 41 DCHECK(!vfs_file_name.empty()); |
| 23 size_t first_slash_index = vfs_file_name.find('/'); | 42 size_t first_slash_index = vfs_file_name.find('/'); |
| 24 size_t last_pound_index = vfs_file_name.rfind('#'); | 43 size_t last_pound_index = vfs_file_name.rfind('#'); |
| 25 // '/' and '#' must be present in the string. Also, the string cannot start | 44 // '/' and '#' must be present in the string. Also, the string cannot start |
| 26 // with a '/' (origin_identifier cannot be empty) and '/' must come before '#' | 45 // with a '/' (origin_identifier cannot be empty) and '/' must come before '#' |
| 27 if ((first_slash_index == base::string16::npos) || | 46 if ((first_slash_index == base::string16::npos) || |
| 28 (last_pound_index == base::string16::npos) || | 47 (last_pound_index == base::string16::npos) || |
| 29 (first_slash_index == 0) || | 48 (first_slash_index == 0) || |
| 30 (first_slash_index > last_pound_index)) { | 49 (first_slash_index > last_pound_index)) { |
| 31 return false; | 50 return false; |
| 32 } | 51 } |
| 33 | 52 |
| 34 if (origin_identifier) { | 53 std::string origin_id = UTF16ToASCII( |
| 35 *origin_identifier = UTF16ToASCII( | |
| 36 vfs_file_name.substr(0, first_slash_index)); | 54 vfs_file_name.substr(0, first_slash_index)); |
| 37 } | 55 if (!IsValidOriginIdentifier(origin_id)) |
| 56 return false; | |
| 57 | |
| 58 base::string16 suffix = vfs_file_name.substr( | |
|
jschuh
2014/03/14 03:38:00
I can't tell how we verify host:port. Could you ch
michaeln
2014/03/14 03:55:56
Maybe DatabaseIdentifier::Parse should test for ':
| |
| 59 last_pound_index + 1, vfs_file_name.length() - last_pound_index - 1); | |
| 60 if (!IsSafeSuffix(suffix)) | |
| 61 return false; | |
| 62 | |
| 63 if (origin_identifier) | |
| 64 *origin_identifier = origin_id; | |
| 65 | |
| 38 if (database_name) { | 66 if (database_name) { |
| 39 *database_name = vfs_file_name.substr( | 67 *database_name = vfs_file_name.substr( |
| 40 first_slash_index + 1, last_pound_index - first_slash_index - 1); | 68 first_slash_index + 1, last_pound_index - first_slash_index - 1); |
| 41 } | 69 } |
| 42 if (sqlite_suffix) { | 70 |
| 43 *sqlite_suffix = vfs_file_name.substr( | 71 if (sqlite_suffix) |
| 44 last_pound_index + 1, vfs_file_name.length() - last_pound_index - 1); | 72 *sqlite_suffix = suffix; |
| 45 } | 73 |
| 46 return true; | 74 return true; |
| 47 } | 75 } |
| 48 | 76 |
| 49 base::FilePath DatabaseUtil::GetFullFilePathForVfsFile( | 77 base::FilePath DatabaseUtil::GetFullFilePathForVfsFile( |
| 50 DatabaseTracker* db_tracker, const base::string16& vfs_file_name) { | 78 DatabaseTracker* db_tracker, const base::string16& vfs_file_name) { |
| 51 std::string origin_identifier; | 79 std::string origin_identifier; |
| 52 base::string16 database_name; | 80 base::string16 database_name; |
| 53 base::string16 sqlite_suffix; | 81 base::string16 sqlite_suffix; |
| 54 if (!CrackVfsFileName(vfs_file_name, &origin_identifier, | 82 if (!CrackVfsFileName(vfs_file_name, &origin_identifier, |
| 55 &database_name, &sqlite_suffix)) { | 83 &database_name, &sqlite_suffix)) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 69 return base::FilePath(); | 97 return base::FilePath(); |
| 70 return full_path; | 98 return full_path; |
| 71 } | 99 } |
| 72 | 100 |
| 73 bool DatabaseUtil::IsValidOriginIdentifier( | 101 bool DatabaseUtil::IsValidOriginIdentifier( |
| 74 const std::string& origin_identifier) { | 102 const std::string& origin_identifier) { |
| 75 std::string dotdot = ".."; | 103 std::string dotdot = ".."; |
| 76 char forbidden[] = {'\\', '/', '\0'}; | 104 char forbidden[] = {'\\', '/', '\0'}; |
| 77 | 105 |
| 78 std::string::size_type pos = origin_identifier.find(dotdot); | 106 std::string::size_type pos = origin_identifier.find(dotdot); |
| 79 if (pos == std::string::npos) | 107 if (origin_identifier.find(dotdot) != std::string::npos) |
| 80 pos = origin_identifier.find_first_of(forbidden, 0, arraysize(forbidden)); | 108 return false; |
| 109 if (origin_identifier.find_first_of(forbidden, 0, arraysize(forbidden)) != | |
| 110 std::string::npos) { | |
| 111 return false; | |
| 112 } | |
| 81 | 113 |
| 82 return pos == std::string::npos; | 114 return GetOriginFromIdentifier(origin_identifier).is_valid(); |
| 83 } | 115 } |
| 84 | 116 |
| 85 } // namespace webkit_database | 117 } // namespace webkit_database |
| OLD | NEW |