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 |