Chromium Code Reviews| Index: components/history/core/browser/download_database.cc |
| diff --git a/components/history/core/browser/download_database.cc b/components/history/core/browser/download_database.cc |
| index 93b707c9fe22f76c0bfbac30ce721b4710e40289..8303b48b2d2696258d437ffb45d678dd34591de1 100644 |
| --- a/components/history/core/browser/download_database.cc |
| +++ b/components/history/core/browser/download_database.cc |
| @@ -192,27 +192,54 @@ bool DownloadDatabase::MigrateHashHttpMethodAndGenerateGuids() { |
| !EnsureColumnExists("http_method", "VARCHAR NOT NULL DEFAULT ''")) |
| return false; |
| - // Generate GUIDs for each download. The GUID is generated thusly: |
| + // Generate GUIDs for each download. GUIDs based on random data should conform |
| + // with RFC 4122 section 4.4. Given the following field layout (based on RFC |
| + // 4122): |
| // |
| - // XXXXXXXX-RRRR-RRRR-RRRR-RRRRRRRRRRRR |
| + // 0 1 2 3 |
| + // 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 |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + // | time_low | |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + // | time_mid | time_hi_and_version | |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + // |clk_seq_hi_res | clk_seq_low | node (0-1) | |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + // | node (2-5) | |
| + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| + // |
| + // * Bits 4-7 of time_hi_and_version should be set to 0b0100 == 4 |
| + // * Bits 6-7 of clk_seq_hi_res should be set to 0b10 |
| + // * All other bits should be random or pseudorandom. |
| + // |
| + // We are going to take the liberty of setting time_low to the 32-bit download |
| + // ID. That will guarantee that no two randomly generated GUIDs will collide |
| + // even if the 90 bits of entropy doesn't save us. |
| + // |
| + // Translated to the canonical string representation, the GUID is generated |
| + // thusly: |
| + // |
| + // 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
|
| // \__ __/ \___________ ____________/ |
| // \/ \/ |
| - // | Random hex digits |
| + // | R = random hex digit. |
| + // | y = one of {'8','9','A','B'} selected randomly. |
| + // | 4 = the character '4'. |
| // | |
| // Hex representation of 32-bit download ID. |
| // |
| - // The 96 random bits provide entropy while the 32-bits from the download ID |
| - // ensure that the generated identifiers will at least be unique amongst the |
| - // download rows in the unlikely event there's a collision in the 96 entropy |
| - // bits. |
| - // |
| // This GUID generation scheme is only used for migrated download rows and |
| // assumes that the likelihood of a collision with a GUID generated via |
| // base::GenerateGUID() will be vanishingly small. |
| const char kMigrateGuidsQuery[] = |
| "UPDATE downloads SET guid = printf" |
| - "(\"%08X-%s-%s-%s-%s\", id, hex(randomblob(2)), hex(randomblob(2))," |
| - " hex(randomblob(2)), hex(randomblob(6)))"; |
| + "(\"%08X-%s-4%s-%01X%s-%s\"," |
| + " id," |
| + " hex(randomblob(2))," |
| + " substr(hex(randomblob(2)),2)," |
| + " (8 | (random() & 3))," |
| + " substr(hex(randomblob(2)),2)," |
| + " hex(randomblob(6)))"; |
| return GetDB().Execute(kMigrateGuidsQuery); |
| } |