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 "components/history/core/browser/download_database.h" | 5 #include "components/history/core/browser/download_database.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 return EnsureColumnExists("etag", "VARCHAR NOT NULL DEFAULT \"\"") && | 185 return EnsureColumnExists("etag", "VARCHAR NOT NULL DEFAULT \"\"") && |
186 EnsureColumnExists("last_modified", "VARCHAR NOT NULL DEFAULT \"\""); | 186 EnsureColumnExists("last_modified", "VARCHAR NOT NULL DEFAULT \"\""); |
187 } | 187 } |
188 | 188 |
189 bool DownloadDatabase::MigrateHashHttpMethodAndGenerateGuids() { | 189 bool DownloadDatabase::MigrateHashHttpMethodAndGenerateGuids() { |
190 if (!EnsureColumnExists("guid", "VARCHAR NOT NULL DEFAULT ''") || | 190 if (!EnsureColumnExists("guid", "VARCHAR NOT NULL DEFAULT ''") || |
191 !EnsureColumnExists("hash", "BLOB NOT NULL DEFAULT X''") || | 191 !EnsureColumnExists("hash", "BLOB NOT NULL DEFAULT X''") || |
192 !EnsureColumnExists("http_method", "VARCHAR NOT NULL DEFAULT ''")) | 192 !EnsureColumnExists("http_method", "VARCHAR NOT NULL DEFAULT ''")) |
193 return false; | 193 return false; |
194 | 194 |
195 // Generate GUIDs for each download. The GUID is generated thusly: | 195 // Generate GUIDs for each download. GUIDs based on random data should conform |
196 // with RFC 4122 section 4.4. Given the following field layout (based on RFC | |
197 // 4122): | |
196 // | 198 // |
197 // XXXXXXXX-RRRR-RRRR-RRRR-RRRRRRRRRRRR | 199 // 0 1 2 3 |
200 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
201 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
202 // | time_low | | |
203 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
204 // | time_mid | time_hi_and_version | | |
205 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
206 // |clk_seq_hi_res | clk_seq_low | node (0-1) | | |
207 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
208 // | node (2-5) | | |
209 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
210 // | |
211 // * Bits 4-7 of time_hi_and_version should be set to 0b0100 == 4 | |
212 // * Bits 6-7 of clk_seq_hi_res should be set to 0b10 | |
213 // * All other bits should be random or pseudorandom. | |
214 // | |
215 // We are going to take the liberty of setting time_low to the 32-bit download | |
216 // ID. That will guarantee that no two randomly generated GUIDs will collide | |
217 // even if the 90 bits of entropy doesn't save us. | |
218 // | |
219 // Translated to the canonical string representation, the GUID is generated | |
220 // thusly: | |
221 // | |
222 // XXXXXXXX-RRRR-4RRR-yRRR-RRRRRRRRRRRR | |
sky
2016/04/08 21:59:32
The old code may not have generated the 4 and y, r
asanka
2016/04/11 17:32:59
None at all. I'd have added migration code if it d
| |
198 // \__ __/ \___________ ____________/ | 223 // \__ __/ \___________ ____________/ |
199 // \/ \/ | 224 // \/ \/ |
200 // | Random hex digits | 225 // | R = random hex digit. |
226 // | y = one of {'8','9','A','B'} selected randomly. | |
227 // | 4 = the character '4'. | |
201 // | | 228 // | |
202 // Hex representation of 32-bit download ID. | 229 // Hex representation of 32-bit download ID. |
203 // | 230 // |
204 // The 96 random bits provide entropy while the 32-bits from the download ID | |
205 // ensure that the generated identifiers will at least be unique amongst the | |
206 // download rows in the unlikely event there's a collision in the 96 entropy | |
207 // bits. | |
208 // | |
209 // This GUID generation scheme is only used for migrated download rows and | 231 // This GUID generation scheme is only used for migrated download rows and |
210 // assumes that the likelihood of a collision with a GUID generated via | 232 // assumes that the likelihood of a collision with a GUID generated via |
211 // base::GenerateGUID() will be vanishingly small. | 233 // base::GenerateGUID() will be vanishingly small. |
212 const char kMigrateGuidsQuery[] = | 234 const char kMigrateGuidsQuery[] = |
213 "UPDATE downloads SET guid = printf" | 235 "UPDATE downloads SET guid = printf" |
214 "(\"%08X-%s-%s-%s-%s\", id, hex(randomblob(2)), hex(randomblob(2))," | 236 "(\"%08X-%s-4%s-%01X%s-%s\"," |
215 " hex(randomblob(2)), hex(randomblob(6)))"; | 237 " id," |
238 " hex(randomblob(2))," | |
239 " substr(hex(randomblob(2)),2)," | |
240 " (8 | (random() & 3))," | |
241 " substr(hex(randomblob(2)),2)," | |
242 " hex(randomblob(6)))"; | |
216 return GetDB().Execute(kMigrateGuidsQuery); | 243 return GetDB().Execute(kMigrateGuidsQuery); |
217 } | 244 } |
218 | 245 |
219 bool DownloadDatabase::InitDownloadTable() { | 246 bool DownloadDatabase::InitDownloadTable() { |
220 const char kSchema[] = | 247 const char kSchema[] = |
221 "CREATE TABLE downloads (" | 248 "CREATE TABLE downloads (" |
222 "id INTEGER PRIMARY KEY," // Primary key. | 249 "id INTEGER PRIMARY KEY," // Primary key. |
223 "guid VARCHAR NOT NULL," // GUID. | 250 "guid VARCHAR NOT NULL," // GUID. |
224 "current_path LONGVARCHAR NOT NULL," // Current disk location | 251 "current_path LONGVARCHAR NOT NULL," // Current disk location |
225 "target_path LONGVARCHAR NOT NULL," // Final disk location | 252 "target_path LONGVARCHAR NOT NULL," // Final disk location |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
614 size_t DownloadDatabase::CountDownloads() { | 641 size_t DownloadDatabase::CountDownloads() { |
615 EnsureInProgressEntriesCleanedUp(); | 642 EnsureInProgressEntriesCleanedUp(); |
616 | 643 |
617 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, | 644 sql::Statement statement(GetDB().GetCachedStatement(SQL_FROM_HERE, |
618 "SELECT count(*) from downloads")); | 645 "SELECT count(*) from downloads")); |
619 statement.Step(); | 646 statement.Step(); |
620 return statement.ColumnInt(0); | 647 return statement.ColumnInt(0); |
621 } | 648 } |
622 | 649 |
623 } // namespace history | 650 } // namespace history |
OLD | NEW |