Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4478)

Unified Diff: chrome/browser/safe_browsing/protocol_parser.cc

Issue 8873004: Fix safe-browsing sub parsing for download whitelist. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/safe_browsing/protocol_parser.cc
diff --git a/chrome/browser/safe_browsing/protocol_parser.cc b/chrome/browser/safe_browsing/protocol_parser.cc
index f09a26fbebed18f29da5ea25e700d9c27cea9e57..00756dd302011be1494382952fb3d9aa5b4520dc 100644
--- a/chrome/browser/safe_browsing/protocol_parser.cc
+++ b/chrome/browser/safe_browsing/protocol_parser.cc
@@ -346,11 +346,16 @@ bool SafeBrowsingProtocolParser::ParseAddChunk(const std::string& list_name,
hosts->push_back(chunk_host);
if (!ReadPrefixes(&chunk_data, &remaining, chunk_host.entry, prefix_count))
return false;
+ DCHECK_GE(remaining, 0);
} else {
SBPrefix host;
const int min_size = sizeof(SBPrefix) + 1;
while (remaining >= min_size) {
- ReadHostAndPrefixCount(&chunk_data, &remaining, &host, &prefix_count);
+ if (!ReadHostAndPrefixCount(&chunk_data, &remaining,
+ &host, &prefix_count)) {
+ return false;
+ }
+ DCHECK_GE(remaining, 0);
SBChunkHost chunk_host;
chunk_host.host = host;
chunk_host.entry = SBEntry::Create(type, prefix_count);
@@ -358,6 +363,7 @@ bool SafeBrowsingProtocolParser::ParseAddChunk(const std::string& list_name,
if (!ReadPrefixes(&chunk_data, &remaining, chunk_host.entry,
prefix_count))
return false;
+ DCHECK_GE(remaining, 0);
}
}
return remaining == 0;
@@ -374,7 +380,8 @@ bool SafeBrowsingProtocolParser::ParseSubChunk(const std::string& list_name,
SBEntry::Type type = hash_len == sizeof(SBPrefix) ?
SBEntry::SUB_PREFIX : SBEntry::SUB_FULL_HASH;
- if (list_name == safe_browsing_util::kBinHashList) {
+ if (list_name == safe_browsing_util::kBinHashList ||
+ list_name == safe_browsing_util::kDownloadWhiteList) {
SBChunkHost chunk_host;
// Set host to 0 and it won't be used for kBinHashList.
chunk_host.host = 0;
@@ -384,31 +391,43 @@ bool SafeBrowsingProtocolParser::ParseSubChunk(const std::string& list_name,
chunk_host.entry = SBEntry::Create(type, prefix_count);
if (!ReadPrefixes(&chunk_data, &remaining, chunk_host.entry, prefix_count))
return false;
+ DCHECK_GE(remaining, 0);
hosts->push_back(chunk_host);
} else {
SBPrefix host;
const int min_size = 2 * sizeof(SBPrefix) + 1;
while (remaining >= min_size) {
- ReadHostAndPrefixCount(&chunk_data, &remaining, &host, &prefix_count);
+ if (!ReadHostAndPrefixCount(&chunk_data, &remaining,
+ &host, &prefix_count)) {
+ return false;
+ }
+ DCHECK_GE(remaining, 0);
SBChunkHost chunk_host;
chunk_host.host = host;
chunk_host.entry = SBEntry::Create(type, prefix_count);
hosts->push_back(chunk_host);
if (prefix_count == 0) {
// There is only an add chunk number (no prefixes).
- chunk_host.entry->set_chunk_id(ReadChunkId(&chunk_data, &remaining));
+ int chunk_id;
+ if (!ReadChunkId(&chunk_data, &remaining, &chunk_id))
+ return false;
+ DCHECK_GE(remaining, 0);
+ chunk_host.entry->set_chunk_id(chunk_id);
continue;
}
if (!ReadPrefixes(&chunk_data, &remaining, chunk_host.entry,
prefix_count))
return false;
+ DCHECK_GE(remaining, 0);
}
}
return remaining == 0;
}
-void SafeBrowsingProtocolParser::ReadHostAndPrefixCount(
+bool SafeBrowsingProtocolParser::ReadHostAndPrefixCount(
const char** data, int* remaining, SBPrefix* host, int* count) {
+ if (static_cast<size_t>(*remaining) < sizeof(SBPrefix) + 1)
+ return false;
// Next 4 bytes are the host prefix.
memcpy(host, *data, sizeof(SBPrefix));
*data += sizeof(SBPrefix);
@@ -418,15 +437,23 @@ void SafeBrowsingProtocolParser::ReadHostAndPrefixCount(
*count = static_cast<unsigned char>(**data);
*data += 1;
*remaining -= 1;
+ DCHECK_GE(*remaining, 0);
+ return true;
}
-int SafeBrowsingProtocolParser::ReadChunkId(
- const char** data, int* remaining) {
- int chunk_number;
- memcpy(&chunk_number, *data, sizeof(chunk_number));
- *data += sizeof(chunk_number);
- *remaining -= sizeof(chunk_number);
- return htonl(chunk_number);
+bool SafeBrowsingProtocolParser::ReadChunkId(
+ const char** data, int* remaining, int* chunk_id) {
+ // Protocol says four bytes, not sizeof(int). Make sure those
+ // values are the same.
+ DCHECK_EQ(sizeof(*chunk_id), 4u);
noelutz 2011/12/08 03:26:54 good call.
Scott Hess - ex-Googler 2011/12/08 04:12:44 For all that I said "I don't have time to rewrite
+ if (static_cast<size_t>(*remaining) < sizeof(*chunk_id))
+ return false;
+ memcpy(chunk_id, *data, sizeof(*chunk_id));
+ *data += sizeof(*chunk_id);
+ *remaining -= sizeof(*chunk_id);
+ *chunk_id = htonl(*chunk_id);
+ DCHECK_GE(*remaining, 0);
+ return true;
}
bool SafeBrowsingProtocolParser::ReadPrefixes(
@@ -434,20 +461,25 @@ bool SafeBrowsingProtocolParser::ReadPrefixes(
int hash_len = entry->HashLen();
for (int i = 0; i < count; ++i) {
if (entry->IsSub()) {
- entry->SetChunkIdAtPrefix(i, ReadChunkId(data, remaining));
- if (*remaining <= 0)
+ int chunk_id;
+ if (!ReadChunkId(data, remaining, &chunk_id))
return false;
+ DCHECK_GE(*remaining, 0);
+ entry->SetChunkIdAtPrefix(i, chunk_id);
}
+ if (*remaining < hash_len)
+ return false;
if (entry->IsPrefix()) {
+ DCHECK_EQ(hash_len, (int)sizeof(SBPrefix));
entry->SetPrefixAt(i, *reinterpret_cast<const SBPrefix*>(*data));
} else {
+ DCHECK_EQ(hash_len, (int)sizeof(SBFullHash));
entry->SetFullHashAt(i, *reinterpret_cast<const SBFullHash*>(*data));
}
*data += hash_len;
*remaining -= hash_len;
- if (*remaining < 0)
- return false;
+ DCHECK_GE(*remaining, 0);
}
return true;
« no previous file with comments | « chrome/browser/safe_browsing/protocol_parser.h ('k') | chrome/browser/safe_browsing/protocol_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698