Home | History | Annotate | Download | only in safe_browsing
      1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // Program to test the SafeBrowsing protocol parsing v2.1.
      6 
      7 #include "base/string_util.h"
      8 #include "chrome/browser/safe_browsing/protocol_parser.h"
      9 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 // Test parsing one add chunk.
     13 TEST(SafeBrowsingProtocolParsingTest, TestAddChunk) {
     14   std::string add_chunk("a:1:4:35\naaaax1111\0032222333344447777\00288889999");
     15   add_chunk[13] = '\0';
     16 
     17   // Run the parse.
     18   SafeBrowsingProtocolParser parser;
     19   bool re_key = false;
     20   SBChunkList chunks;
     21   bool result = parser.ParseChunk(
     22       safe_browsing_util::kMalwareList,
     23       add_chunk.data(),
     24       static_cast<int>(add_chunk.length()),
     25       "", "",  &re_key, &chunks);
     26   EXPECT_TRUE(result);
     27   EXPECT_FALSE(re_key);
     28   EXPECT_EQ(chunks.size(), 1U);
     29   EXPECT_EQ(chunks[0].chunk_number, 1);
     30   EXPECT_EQ(chunks[0].hosts.size(), 3U);
     31 
     32   EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
     33   SBEntry* entry = chunks[0].hosts[0].entry;
     34   EXPECT_TRUE(entry->IsAdd());
     35   EXPECT_TRUE(entry->IsPrefix());
     36   EXPECT_EQ(entry->prefix_count(), 0);
     37 
     38   EXPECT_EQ(chunks[0].hosts[1].host, 0x31313131);
     39   entry = chunks[0].hosts[1].entry;
     40   EXPECT_TRUE(entry->IsAdd());
     41   EXPECT_TRUE(entry->IsPrefix());
     42   EXPECT_EQ(entry->prefix_count(), 3);
     43   EXPECT_EQ(entry->PrefixAt(0), 0x32323232);
     44   EXPECT_EQ(entry->PrefixAt(1), 0x33333333);
     45   EXPECT_EQ(entry->PrefixAt(2), 0x34343434);
     46 
     47   EXPECT_EQ(chunks[0].hosts[2].host, 0x37373737);
     48   entry = chunks[0].hosts[2].entry;
     49   EXPECT_TRUE(entry->IsAdd());
     50   EXPECT_TRUE(entry->IsPrefix());
     51   EXPECT_EQ(entry->prefix_count(), 2);
     52   EXPECT_EQ(entry->PrefixAt(0), 0x38383838);
     53   EXPECT_EQ(entry->PrefixAt(1), 0x39393939);
     54 }
     55 
     56 // Test parsing one add chunk with full hashes.
     57 TEST(SafeBrowsingProtocolParsingTest, TestAddFullChunk) {
     58   std::string add_chunk("a:1:32:69\naaaa");
     59   add_chunk.push_back(2);
     60 
     61   SBFullHash full_hash1, full_hash2;
     62   for (int i = 0; i < 32; ++i) {
     63     full_hash1.full_hash[i] = i % 2 ? 1 : 2;
     64     full_hash2.full_hash[i] = i % 2 ? 3 : 4;
     65   }
     66 
     67   add_chunk.append(full_hash1.full_hash, 32);
     68   add_chunk.append(full_hash2.full_hash, 32);
     69 
     70   // Run the parse.
     71   SafeBrowsingProtocolParser parser;
     72   bool re_key = false;
     73   SBChunkList chunks;
     74   bool result = parser.ParseChunk(
     75       safe_browsing_util::kMalwareList,
     76       add_chunk.data(),
     77       static_cast<int>(add_chunk.length()),
     78       "", "", &re_key, &chunks);
     79   EXPECT_TRUE(result);
     80   EXPECT_FALSE(re_key);
     81   EXPECT_EQ(chunks.size(), 1U);
     82   EXPECT_EQ(chunks[0].chunk_number, 1);
     83   EXPECT_EQ(chunks[0].hosts.size(), 1U);
     84 
     85   EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
     86   SBEntry* entry = chunks[0].hosts[0].entry;
     87   EXPECT_TRUE(entry->IsAdd());
     88   EXPECT_FALSE(entry->IsPrefix());
     89   EXPECT_EQ(entry->prefix_count(), 2);
     90   EXPECT_TRUE(entry->FullHashAt(0) == full_hash1);
     91   EXPECT_TRUE(entry->FullHashAt(1) == full_hash2);
     92 }
     93 
     94 // Test parsing multiple add chunks. We'll use the same chunk as above, and add
     95 // one more after it.
     96 TEST(SafeBrowsingProtocolParsingTest, TestAddChunks) {
     97   std::string add_chunk("a:1:4:35\naaaax1111\0032222333344447777\00288889999"
     98                         "a:2:4:13\n5555\002ppppgggg");
     99   add_chunk[13] = '\0';
    100 
    101   // Run the parse.
    102   SafeBrowsingProtocolParser parser;
    103   bool re_key = false;
    104   SBChunkList chunks;
    105   bool result = parser.ParseChunk(
    106       safe_browsing_util::kMalwareList,
    107       add_chunk.data(),
    108       static_cast<int>(add_chunk.length()),
    109       "", "", &re_key, &chunks);
    110   EXPECT_TRUE(result);
    111   EXPECT_FALSE(re_key);
    112   EXPECT_EQ(chunks.size(), 2U);
    113   EXPECT_EQ(chunks[0].chunk_number, 1);
    114   EXPECT_EQ(chunks[0].hosts.size(), 3U);
    115 
    116   EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
    117   SBEntry* entry = chunks[0].hosts[0].entry;
    118   EXPECT_TRUE(entry->IsAdd());
    119   EXPECT_TRUE(entry->IsPrefix());
    120   EXPECT_EQ(entry->prefix_count(), 0);
    121 
    122   EXPECT_EQ(chunks[0].hosts[1].host, 0x31313131);
    123   entry = chunks[0].hosts[1].entry;
    124   EXPECT_TRUE(entry->IsAdd());
    125   EXPECT_TRUE(entry->IsPrefix());
    126   EXPECT_EQ(entry->prefix_count(), 3);
    127   EXPECT_EQ(entry->PrefixAt(0), 0x32323232);
    128   EXPECT_EQ(entry->PrefixAt(1), 0x33333333);
    129   EXPECT_EQ(entry->PrefixAt(2), 0x34343434);
    130 
    131   EXPECT_EQ(chunks[0].hosts[2].host, 0x37373737);
    132   entry = chunks[0].hosts[2].entry;
    133   EXPECT_TRUE(entry->IsAdd());
    134   EXPECT_TRUE(entry->IsPrefix());
    135   EXPECT_EQ(entry->prefix_count(), 2);
    136   EXPECT_EQ(entry->PrefixAt(0), 0x38383838);
    137   EXPECT_EQ(entry->PrefixAt(1), 0x39393939);
    138 
    139 
    140   EXPECT_EQ(chunks[1].chunk_number, 2);
    141   EXPECT_EQ(chunks[1].hosts.size(), 1U);
    142 
    143   EXPECT_EQ(chunks[1].hosts[0].host, 0x35353535);
    144   entry = chunks[1].hosts[0].entry;
    145   EXPECT_TRUE(entry->IsAdd());
    146   EXPECT_TRUE(entry->IsPrefix());
    147   EXPECT_EQ(entry->prefix_count(), 2);
    148   EXPECT_EQ(entry->PrefixAt(0), 0x70707070);
    149   EXPECT_EQ(entry->PrefixAt(1), 0x67676767);
    150 }
    151 
    152 // Test parsing one add chunk where a hostkey spans several entries.
    153 TEST(SafeBrowsingProtocolParsingTest, TestAddBigChunk) {
    154   std::string add_chunk("a:1:4:1050\naaaaX");
    155   add_chunk[add_chunk.size() - 1] |= 0xFF;
    156   for (int i = 0; i < 255; ++i)
    157     add_chunk.append(StringPrintf("%04d", i));
    158 
    159   add_chunk.append("aaaa");
    160   add_chunk.push_back(5);
    161   for (int i = 0; i < 5; ++i)
    162     add_chunk.append(StringPrintf("001%d", i));
    163 
    164   SafeBrowsingProtocolParser parser;
    165   bool re_key = false;
    166   SBChunkList chunks;
    167   bool result = parser.ParseChunk(
    168       safe_browsing_util::kMalwareList,
    169       add_chunk.data(),
    170       static_cast<int>(add_chunk.length()),
    171       "", "", &re_key, &chunks);
    172   EXPECT_TRUE(result);
    173   EXPECT_FALSE(re_key);
    174   EXPECT_EQ(chunks.size(), 1U);
    175   EXPECT_EQ(chunks[0].chunk_number, 1);
    176 
    177   EXPECT_EQ(chunks[0].hosts.size(), 2U);
    178 
    179   const SBChunkHost& host0 = chunks[0].hosts[0];
    180   EXPECT_EQ(host0.host, 0x61616161);
    181   EXPECT_EQ(host0.entry->prefix_count(), 255);
    182 
    183   const SBChunkHost& host1 = chunks[0].hosts[1];
    184   EXPECT_EQ(host1.host, 0x61616161);
    185   EXPECT_EQ(host1.entry->prefix_count(), 5);
    186 }
    187 
    188 // Test to make sure we could deal with truncated bin hash chunk.
    189 TEST(SafeBrowsingProtocolParsingTest, TestTruncatedBinHashChunk) {
    190   // This chunk delares there are 4 prefixes but actually only contains 2.
    191   const char add_chunk[] = "a:1:4:16\n11112222";
    192   SafeBrowsingProtocolParser parser;
    193   bool re_key = false;
    194   SBChunkList chunks;
    195   bool result = parser.ParseChunk(add_chunk,
    196                                   safe_browsing_util::kBinHashList,
    197                                   static_cast<int>(sizeof(add_chunk)),
    198                                   "", "", &re_key, &chunks);
    199   EXPECT_FALSE(result);
    200   EXPECT_FALSE(re_key);
    201   EXPECT_EQ(chunks.size(), 0U);
    202 }
    203 
    204 // Test to make sure we could deal with truncated malwarelist chunk.
    205 TEST(SafeBrowsingProtocolParsingTest, TestTruncatedUrlHashChunk) {
    206   // This chunk delares there are 4 prefixes but actually only contains 2.
    207   const char add_chunk[] = "a:1:4:21\naaaa\00411112222";
    208   SafeBrowsingProtocolParser parser;
    209   bool re_key = false;
    210   SBChunkList chunks;
    211 
    212   // For safe_browsing_util::kMalwareList.
    213   bool result = parser.ParseChunk(add_chunk,
    214                                   safe_browsing_util::kMalwareList,
    215                                   static_cast<int>(sizeof(add_chunk)),
    216                                   "", "", &re_key, &chunks);
    217   EXPECT_FALSE(result);
    218   EXPECT_FALSE(re_key);
    219   EXPECT_EQ(chunks.size(), 0U);
    220 
    221   // For safe_browsing_util::kPhishingList.
    222   result = parser.ParseChunk(add_chunk,
    223                              safe_browsing_util::kPhishingList,
    224                              static_cast<int>(sizeof(add_chunk)),
    225                              "", "", &re_key, &chunks);
    226   EXPECT_FALSE(result);
    227   EXPECT_FALSE(re_key);
    228   EXPECT_EQ(chunks.size(), 0U);
    229 
    230   // For safe_browsing_util::kBinUrlList.
    231   result = parser.ParseChunk(add_chunk,
    232                              safe_browsing_util::kBinUrlList,
    233                              static_cast<int>(sizeof(add_chunk)),
    234                              "", "", &re_key, &chunks);
    235   EXPECT_FALSE(result);
    236   EXPECT_FALSE(re_key);
    237   EXPECT_EQ(chunks.size(), 0U);
    238 }
    239 
    240 // Test parsing one sub chunk.
    241 TEST(SafeBrowsingProtocolParsingTest, TestSubChunk) {
    242   std::string sub_chunk("s:9:4:59\naaaaxkkkk1111\003"
    243                         "zzzz2222zzzz3333zzzz4444"
    244                         "7777\002yyyy8888yyyy9999");
    245   sub_chunk[13] = '\0';
    246 
    247   // Run the parse.
    248   SafeBrowsingProtocolParser parser;
    249   bool re_key = false;
    250   SBChunkList chunks;
    251   bool result = parser.ParseChunk(
    252       safe_browsing_util::kMalwareList,
    253       sub_chunk.data(),
    254       static_cast<int>(sub_chunk.length()),
    255       "", "", &re_key, &chunks);
    256   EXPECT_TRUE(result);
    257   EXPECT_FALSE(re_key);
    258   EXPECT_EQ(chunks.size(), 1U);
    259   EXPECT_EQ(chunks[0].chunk_number, 9);
    260   EXPECT_EQ(chunks[0].hosts.size(), 3U);
    261 
    262   EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
    263   SBEntry* entry = chunks[0].hosts[0].entry;
    264   EXPECT_TRUE(entry->IsSub());
    265   EXPECT_TRUE(entry->IsPrefix());
    266   EXPECT_EQ(entry->chunk_id(), 0x6b6b6b6b);
    267   EXPECT_EQ(entry->prefix_count(), 0);
    268 
    269   EXPECT_EQ(chunks[0].hosts[1].host, 0x31313131);
    270   entry = chunks[0].hosts[1].entry;
    271   EXPECT_TRUE(entry->IsSub());
    272   EXPECT_TRUE(entry->IsPrefix());
    273   EXPECT_EQ(entry->prefix_count(), 3);
    274   EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x7a7a7a7a);
    275   EXPECT_EQ(entry->PrefixAt(0), 0x32323232);
    276   EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x7a7a7a7a);
    277   EXPECT_EQ(entry->PrefixAt(1), 0x33333333);
    278   EXPECT_EQ(entry->ChunkIdAtPrefix(2), 0x7a7a7a7a);
    279   EXPECT_EQ(entry->PrefixAt(2), 0x34343434);
    280 
    281   EXPECT_EQ(chunks[0].hosts[2].host, 0x37373737);
    282   entry = chunks[0].hosts[2].entry;
    283   EXPECT_TRUE(entry->IsSub());
    284   EXPECT_TRUE(entry->IsPrefix());
    285   EXPECT_EQ(entry->prefix_count(), 2);
    286   EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x79797979);
    287   EXPECT_EQ(entry->PrefixAt(0), 0x38383838);
    288   EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x79797979);
    289   EXPECT_EQ(entry->PrefixAt(1), 0x39393939);
    290 }
    291 
    292 // Test parsing one sub chunk with full hashes.
    293 TEST(SafeBrowsingProtocolParsingTest, TestSubFullChunk) {
    294   std::string sub_chunk("s:1:32:77\naaaa");
    295   sub_chunk.push_back(2);
    296 
    297   SBFullHash full_hash1, full_hash2;
    298   for (int i = 0; i < 32; ++i) {
    299     full_hash1.full_hash[i] = i % 2 ? 1 : 2;
    300     full_hash2.full_hash[i] = i % 2 ? 3 : 4;
    301   }
    302 
    303   sub_chunk.append("yyyy");
    304   sub_chunk.append(full_hash1.full_hash, 32);
    305   sub_chunk.append("zzzz");
    306   sub_chunk.append(full_hash2.full_hash, 32);
    307 
    308   // Run the parse.
    309   SafeBrowsingProtocolParser parser;
    310   bool re_key = false;
    311   SBChunkList chunks;
    312   bool result = parser.ParseChunk(
    313       safe_browsing_util::kMalwareList,
    314       sub_chunk.data(),
    315       static_cast<int>(sub_chunk.length()),
    316       "", "", &re_key, &chunks);
    317   EXPECT_TRUE(result);
    318   EXPECT_FALSE(re_key);
    319   EXPECT_EQ(chunks.size(), 1U);
    320   EXPECT_EQ(chunks[0].chunk_number, 1);
    321   EXPECT_EQ(chunks[0].hosts.size(), 1U);
    322 
    323   EXPECT_EQ(chunks[0].hosts[0].host, 0x61616161);
    324   SBEntry* entry = chunks[0].hosts[0].entry;
    325   EXPECT_TRUE(entry->IsSub());
    326   EXPECT_FALSE(entry->IsPrefix());
    327   EXPECT_EQ(entry->prefix_count(), 2);
    328   EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x79797979);
    329   EXPECT_TRUE(entry->FullHashAt(0) == full_hash1);
    330   EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x7a7a7a7a);
    331   EXPECT_TRUE(entry->FullHashAt(1) == full_hash2);
    332 }
    333 
    334 // Test parsing the SafeBrowsing update response.
    335 TEST(SafeBrowsingProtocolParsingTest, TestChunkDelete) {
    336   std::string add_del("n:1700\ni:phishy\nad:1-7,43-597,44444,99999\n"
    337                       "i:malware\nsd:21-27,42,171717\n");
    338 
    339   SafeBrowsingProtocolParser parser;
    340   int next_query_sec = 0;
    341   bool re_key = false;
    342   bool reset = false;
    343   std::vector<SBChunkDelete> deletes;
    344   std::vector<ChunkUrl> urls;
    345   EXPECT_TRUE(parser.ParseUpdate(add_del.data(),
    346                                  static_cast<int>(add_del.length()), "",
    347                                  &next_query_sec, &re_key,
    348                                  &reset, &deletes, &urls));
    349 
    350   EXPECT_TRUE(urls.empty());
    351   EXPECT_FALSE(re_key);
    352   EXPECT_FALSE(reset);
    353   EXPECT_EQ(next_query_sec, 1700);
    354   EXPECT_EQ(deletes.size(), 2U);
    355 
    356   EXPECT_EQ(deletes[0].chunk_del.size(), 4U);
    357   EXPECT_TRUE(deletes[0].chunk_del[0] == ChunkRange(1, 7));
    358   EXPECT_TRUE(deletes[0].chunk_del[1] == ChunkRange(43, 597));
    359   EXPECT_TRUE(deletes[0].chunk_del[2] == ChunkRange(44444));
    360   EXPECT_TRUE(deletes[0].chunk_del[3] == ChunkRange(99999));
    361 
    362   EXPECT_EQ(deletes[1].chunk_del.size(), 3U);
    363   EXPECT_TRUE(deletes[1].chunk_del[0] == ChunkRange(21, 27));
    364   EXPECT_TRUE(deletes[1].chunk_del[1] == ChunkRange(42));
    365   EXPECT_TRUE(deletes[1].chunk_del[2] == ChunkRange(171717));
    366 
    367   // An update response with missing list name.
    368 
    369   next_query_sec = 0;
    370   deletes.clear();
    371   urls.clear();
    372   add_del = "n:1700\nad:1-7,43-597,44444,99999\ni:malware\nsd:4,21-27171717\n";
    373   EXPECT_FALSE(parser.ParseUpdate(add_del.data(),
    374                                   static_cast<int>(add_del.length()), "",
    375                                   &next_query_sec, &re_key,
    376                                   &reset, &deletes, &urls));
    377 }
    378 
    379 // Test parsing the SafeBrowsing update response.
    380 TEST(SafeBrowsingProtocolParsingTest, TestRedirects) {
    381   std::string redirects("i:goog-malware-shavar\n"
    382     "u:cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_1\n"
    383     "u:cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_2\n"
    384     "u:cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_3\n"
    385     "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8641-8800:8641-8689,"
    386     "8691-8731,8733-8786\n");
    387 
    388   SafeBrowsingProtocolParser parser;
    389   int next_query_sec = 0;
    390   bool re_key = false;
    391   bool reset = false;
    392   std::vector<SBChunkDelete> deletes;
    393   std::vector<ChunkUrl> urls;
    394   EXPECT_TRUE(parser.ParseUpdate(redirects.data(),
    395                                  static_cast<int>(redirects.length()), "",
    396                                  &next_query_sec, &re_key,
    397                                  &reset, &deletes, &urls));
    398 
    399   EXPECT_FALSE(re_key);
    400   EXPECT_FALSE(reset);
    401   EXPECT_EQ(urls.size(), 4U);
    402   EXPECT_EQ(urls[0].url,
    403       "cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_1");
    404   EXPECT_EQ(urls[1].url,
    405       "cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_2");
    406   EXPECT_EQ(urls[2].url,
    407       "cache.googlevideo.com/safebrowsing/rd/goog-malware-shavar_s_3");
    408   EXPECT_EQ(urls[3].url,
    409       "s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8641-8800:8641-8689,"
    410       "8691-8731,8733-8786");
    411   EXPECT_EQ(next_query_sec, 0);
    412   EXPECT_TRUE(deletes.empty());
    413 }
    414 
    415 TEST(SafeBrowsingProtocolParsingTest, TestRedirectsWithMac) {
    416   std::string redirects("i:goog-phish-shavar\n"
    417     "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6501-6505:6501-6505,"
    418     "pcY6iVeT9-CBQ3fdAF0rpnKjR1Y=\n"
    419     "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8001-8160:8001-8024,"
    420     "8026-8045,8048-8049,8051-8134,8136-8152,8155-8160,"
    421     "j6XXAEWnjYk9tVVLBSdQvIEq2Wg=\n");
    422 
    423   SafeBrowsingProtocolParser parser;
    424   int next_query_sec = 0;
    425   bool re_key = false;
    426   bool reset = false;
    427   const std::string key("58Lqn5WIP961x3zuLGo5Uw==");
    428   std::vector<SBChunkDelete> deletes;
    429   std::vector<ChunkUrl> urls;
    430   EXPECT_TRUE(parser.ParseUpdate(redirects.data(),
    431                                  static_cast<int>(redirects.length()), key,
    432                                  &next_query_sec, &re_key,
    433                                  &reset, &deletes, &urls));
    434 
    435   EXPECT_FALSE(re_key);
    436   EXPECT_FALSE(reset);
    437   EXPECT_EQ(urls.size(), 2U);
    438   EXPECT_EQ(urls[0].url,
    439       "s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6501-6505:6501-6505");
    440   EXPECT_EQ(urls[0].mac, "pcY6iVeT9-CBQ3fdAF0rpnKjR1Y=");
    441   EXPECT_EQ(urls[1].url,
    442       "s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8001-8160:8001-8024,"
    443       "8026-8045,8048-8049,8051-8134,8136-8152,8155-8160");
    444   EXPECT_EQ(urls[1].mac, "j6XXAEWnjYk9tVVLBSdQvIEq2Wg=");
    445 }
    446 
    447 // Test parsing various SafeBrowsing protocol headers.
    448 TEST(SafeBrowsingProtocolParsingTest, TestNextQueryTime) {
    449   std::string headers("n:1800\ni:goog-white-shavar\n");
    450   SafeBrowsingProtocolParser parser;
    451   int next_query_sec = 0;
    452   bool re_key = false;
    453   bool reset = false;
    454   std::vector<SBChunkDelete> deletes;
    455   std::vector<ChunkUrl> urls;
    456   EXPECT_TRUE(parser.ParseUpdate(headers.data(),
    457                                  static_cast<int>(headers.length()), "",
    458                                  &next_query_sec, &re_key,
    459                                  &reset, &deletes, &urls));
    460 
    461   EXPECT_EQ(next_query_sec, 1800);
    462   EXPECT_FALSE(re_key);
    463   EXPECT_FALSE(reset);
    464   EXPECT_TRUE(deletes.empty());
    465   EXPECT_TRUE(urls.empty());
    466 }
    467 
    468 // Test parsing data from a GetHashRequest
    469 TEST(SafeBrowsingProtocolParsingTest, TestGetHash) {
    470   std::string get_hash("goog-phish-shavar:19:96\n"
    471                        "00112233445566778899aabbccddeeff"
    472                        "00001111222233334444555566667777"
    473                        "ffffeeeeddddccccbbbbaaaa99998888");
    474   std::vector<SBFullHashResult> full_hashes;
    475   bool re_key = false;
    476   SafeBrowsingProtocolParser parser;
    477   EXPECT_TRUE(parser.ParseGetHash(get_hash.data(),
    478                                   static_cast<int>(get_hash.length()), "",
    479                                   &re_key,
    480                                   &full_hashes));
    481 
    482   EXPECT_FALSE(re_key);
    483   EXPECT_EQ(full_hashes.size(), 3U);
    484   EXPECT_EQ(memcmp(&full_hashes[0].hash,
    485                    "00112233445566778899aabbccddeeff",
    486                    sizeof(SBFullHash)), 0);
    487   EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar");
    488   EXPECT_EQ(memcmp(&full_hashes[1].hash,
    489                    "00001111222233334444555566667777",
    490                    sizeof(SBFullHash)), 0);
    491   EXPECT_EQ(full_hashes[1].list_name, "goog-phish-shavar");
    492   EXPECT_EQ(memcmp(&full_hashes[2].hash,
    493                    "ffffeeeeddddccccbbbbaaaa99998888",
    494                    sizeof(SBFullHash)), 0);
    495   EXPECT_EQ(full_hashes[2].list_name, "goog-phish-shavar");
    496 
    497   // Test multiple lists in the GetHash results.
    498   std::string get_hash2("goog-phish-shavar:19:32\n"
    499                         "00112233445566778899aabbccddeeff"
    500                         "goog-malware-shavar:19:64\n"
    501                         "cafebeefcafebeefdeaddeaddeaddead"
    502                         "zzzzyyyyxxxxwwwwvvvvuuuuttttssss");
    503   EXPECT_TRUE(parser.ParseGetHash(get_hash2.data(),
    504                                   static_cast<int>(get_hash2.length()), "",
    505                                   &re_key,
    506                                   &full_hashes));
    507 
    508   EXPECT_FALSE(re_key);
    509   EXPECT_EQ(full_hashes.size(), 3U);
    510   EXPECT_EQ(memcmp(&full_hashes[0].hash,
    511                    "00112233445566778899aabbccddeeff",
    512                    sizeof(SBFullHash)), 0);
    513   EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar");
    514   EXPECT_EQ(memcmp(&full_hashes[1].hash,
    515                    "cafebeefcafebeefdeaddeaddeaddead",
    516                    sizeof(SBFullHash)), 0);
    517   EXPECT_EQ(full_hashes[1].list_name, "goog-malware-shavar");
    518   EXPECT_EQ(memcmp(&full_hashes[2].hash,
    519                    "zzzzyyyyxxxxwwwwvvvvuuuuttttssss",
    520                    sizeof(SBFullHash)), 0);
    521   EXPECT_EQ(full_hashes[2].list_name, "goog-malware-shavar");
    522 }
    523 
    524 TEST(SafeBrowsingProtocolParsingTest, TestGetHashWithMac) {
    525   const unsigned char get_hash[] = {
    526     0x32, 0x56, 0x74, 0x6f, 0x6b, 0x36, 0x64, 0x41,
    527     0x51, 0x72, 0x65, 0x51, 0x62, 0x38, 0x51, 0x68,
    528     0x59, 0x45, 0x57, 0x51, 0x57, 0x4d, 0x52, 0x65,
    529     0x42, 0x63, 0x41, 0x3d, 0x0a, 0x67, 0x6f, 0x6f,
    530     0x67, 0x2d, 0x70, 0x68, 0x69, 0x73, 0x68, 0x2d,
    531     0x73, 0x68, 0x61, 0x76, 0x61, 0x72, 0x3a, 0x36,
    532     0x31, 0x36, 0x39, 0x3a, 0x33, 0x32, 0x0a, 0x17,
    533     0x7f, 0x03, 0x42, 0x28, 0x1c, 0x31, 0xb9, 0x0b,
    534     0x1c, 0x7b, 0x9d, 0xaf, 0x7b, 0x43, 0x99, 0x10,
    535     0xc1, 0xab, 0xe3, 0x1b, 0x35, 0x80, 0x38, 0x96,
    536     0xf9, 0x44, 0x4f, 0x28, 0xb4, 0xeb, 0x45
    537   };
    538 
    539   const unsigned char hash_result[] = {
    540     0x17, 0x7f, 0x03, 0x42, 0x28, 0x1c, 0x31, 0xb9,
    541     0x0b, 0x1c, 0x7b, 0x9d, 0xaf, 0x7b, 0x43, 0x99,
    542     0x10, 0xc1, 0xab, 0xe3, 0x1b, 0x35, 0x80, 0x38,
    543     0x96, 0xf9, 0x44, 0x4f, 0x28, 0xb4, 0xeb, 0x45
    544   };
    545 
    546   const std::string key = "58Lqn5WIP961x3zuLGo5Uw==";
    547   std::vector<SBFullHashResult> full_hashes;
    548   bool re_key = false;
    549   SafeBrowsingProtocolParser parser;
    550   EXPECT_TRUE(parser.ParseGetHash(reinterpret_cast<const char*>(get_hash),
    551                                   sizeof(get_hash),
    552                                   key,
    553                                   &re_key,
    554                                   &full_hashes));
    555   EXPECT_FALSE(re_key);
    556   EXPECT_EQ(full_hashes.size(), 1U);
    557   EXPECT_EQ(memcmp(hash_result, &full_hashes[0].hash, sizeof(SBFullHash)), 0);
    558 }
    559 
    560 TEST(SafeBrowsingProtocolParsingTest, TestGetHashWithUnknownList) {
    561   std::string hash_response = "goog-phish-shavar:1:32\n"
    562                               "12345678901234567890123456789012"
    563                               "googpub-phish-shavar:19:32\n"
    564                               "09876543210987654321098765432109";
    565   bool re_key = false;
    566   std::string key = "";
    567   std::vector<SBFullHashResult> full_hashes;
    568   SafeBrowsingProtocolParser parser;
    569   EXPECT_TRUE(parser.ParseGetHash(hash_response.data(),
    570                                   hash_response.size(),
    571                                   key,
    572                                   &re_key,
    573                                   &full_hashes));
    574 
    575   EXPECT_EQ(full_hashes.size(), 1U);
    576   EXPECT_EQ(memcmp("12345678901234567890123456789012",
    577                    &full_hashes[0].hash, sizeof(SBFullHash)), 0);
    578   EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar");
    579   EXPECT_EQ(full_hashes[0].add_chunk_id, 1);
    580 
    581   hash_response += "goog-malware-shavar:7:32\n"
    582                    "abcdefghijklmnopqrstuvwxyz123457";
    583   full_hashes.clear();
    584   EXPECT_TRUE(parser.ParseGetHash(hash_response.data(),
    585                                   hash_response.size(),
    586                                   key,
    587                                   &re_key,
    588                                   &full_hashes));
    589 
    590   EXPECT_EQ(full_hashes.size(), 2U);
    591   EXPECT_EQ(memcmp("12345678901234567890123456789012",
    592                    &full_hashes[0].hash, sizeof(SBFullHash)), 0);
    593   EXPECT_EQ(full_hashes[0].list_name, "goog-phish-shavar");
    594   EXPECT_EQ(full_hashes[0].add_chunk_id, 1);
    595   EXPECT_EQ(memcmp("abcdefghijklmnopqrstuvwxyz123457",
    596                    &full_hashes[1].hash, sizeof(SBFullHash)), 0);
    597   EXPECT_EQ(full_hashes[1].list_name, "goog-malware-shavar");
    598   EXPECT_EQ(full_hashes[1].add_chunk_id, 7);
    599 }
    600 
    601 TEST(SafeBrowsingProtocolParsingTest, TestFormatHash) {
    602   SafeBrowsingProtocolParser parser;
    603   std::vector<SBPrefix> prefixes;
    604   std::string get_hash;
    605 
    606   prefixes.push_back(0x34333231);
    607   prefixes.push_back(0x64636261);
    608   prefixes.push_back(0x73727170);
    609 
    610   parser.FormatGetHash(prefixes, &get_hash);
    611   EXPECT_EQ(get_hash, "4:12\n1234abcdpqrs");
    612 }
    613 
    614 TEST(SafeBrowsingProtocolParsingTest, TestGetKey) {
    615   SafeBrowsingProtocolParser parser;
    616   std::string key_response("clientkey:10:0123456789\n"
    617                            "wrappedkey:20:abcdefghijklmnopqrst\n");
    618 
    619   std::string client_key, wrapped_key;
    620   EXPECT_TRUE(parser.ParseNewKey(key_response.data(),
    621                                  static_cast<int>(key_response.length()),
    622                                  &client_key,
    623                                  &wrapped_key));
    624 
    625   EXPECT_EQ(client_key, "0123456789");
    626   EXPECT_EQ(wrapped_key, "abcdefghijklmnopqrst");
    627 }
    628 
    629 TEST(SafeBrowsingProtocolParsingTest, TestReKey) {
    630   SafeBrowsingProtocolParser parser;
    631   std::string update("n:1800\ni:phishy\ne:pleaserekey\n");
    632 
    633   bool re_key = false;
    634   bool reset = false;
    635   int next_update = -1;
    636   std::vector<SBChunkDelete> deletes;
    637   std::vector<ChunkUrl> urls;
    638   EXPECT_TRUE(parser.ParseUpdate(update.data(),
    639                                  static_cast<int>(update.size()), "",
    640                                  &next_update, &re_key,
    641                                  &reset, &deletes, &urls));
    642   EXPECT_TRUE(re_key);
    643 }
    644 
    645 TEST(SafeBrowsingProtocolParsingTest, TestReset) {
    646   SafeBrowsingProtocolParser parser;
    647   std::string update("n:1800\ni:phishy\nr:pleasereset\n");
    648 
    649   bool re_key = false;
    650   bool reset = false;
    651   int next_update = -1;
    652   std::vector<SBChunkDelete> deletes;
    653   std::vector<ChunkUrl> urls;
    654   EXPECT_TRUE(parser.ParseUpdate(update.data(),
    655                                  static_cast<int>(update.size()), "",
    656                                  &next_update, &re_key,
    657                                  &reset, &deletes, &urls));
    658   EXPECT_TRUE(reset);
    659 }
    660 
    661 // The SafeBrowsing service will occasionally send zero length chunks so that
    662 // client requests will have longer contiguous chunk number ranges, and thus
    663 // reduce the request size.
    664 TEST(SafeBrowsingProtocolParsingTest, TestZeroSizeAddChunk) {
    665   std::string add_chunk("a:1:4:0\n");
    666   SafeBrowsingProtocolParser parser;
    667   bool re_key = false;
    668   SBChunkList chunks;
    669 
    670   bool result = parser.ParseChunk(
    671       safe_browsing_util::kMalwareList,
    672       add_chunk.data(),
    673       static_cast<int>(add_chunk.length()),
    674       "", "", &re_key, &chunks);
    675   EXPECT_TRUE(result);
    676   EXPECT_EQ(chunks.size(), 1U);
    677   EXPECT_EQ(chunks[0].chunk_number, 1);
    678   EXPECT_EQ(chunks[0].hosts.size(), 0U);
    679 
    680   // Now test a zero size chunk in between normal chunks.
    681   chunks.clear();
    682   std::string add_chunks("a:1:4:18\n1234\001abcd5678\001wxyz"
    683                          "a:2:4:0\n"
    684                          "a:3:4:9\ncafe\001beef");
    685   result = parser.ParseChunk(
    686       safe_browsing_util::kMalwareList,
    687       add_chunks.data(),
    688       static_cast<int>(add_chunks.length()),
    689       "", "", &re_key, &chunks);
    690   EXPECT_TRUE(result);
    691   EXPECT_EQ(chunks.size(), 3U);
    692 
    693   // See that each chunk has the right content.
    694   EXPECT_EQ(chunks[0].chunk_number, 1);
    695   EXPECT_EQ(chunks[0].hosts.size(), 2U);
    696   EXPECT_EQ(chunks[0].hosts[0].host, 0x34333231);
    697   EXPECT_EQ(chunks[0].hosts[0].entry->PrefixAt(0), 0x64636261);
    698   EXPECT_EQ(chunks[0].hosts[1].host, 0x38373635);
    699   EXPECT_EQ(chunks[0].hosts[1].entry->PrefixAt(0), 0x7a797877);
    700 
    701   EXPECT_EQ(chunks[1].chunk_number, 2);
    702   EXPECT_EQ(chunks[1].hosts.size(), 0U);
    703 
    704   EXPECT_EQ(chunks[2].chunk_number, 3);
    705   EXPECT_EQ(chunks[2].hosts.size(), 1U);
    706   EXPECT_EQ(chunks[2].hosts[0].host, 0x65666163);
    707   EXPECT_EQ(chunks[2].hosts[0].entry->PrefixAt(0), 0x66656562);
    708 }
    709 
    710 // Test parsing a zero sized sub chunk.
    711 TEST(SafeBrowsingProtocolParsingTest, TestZeroSizeSubChunk) {
    712   std::string sub_chunk("s:9:4:0\n");
    713   SafeBrowsingProtocolParser parser;
    714   bool re_key = false;
    715   SBChunkList chunks;
    716 
    717   bool result = parser.ParseChunk(
    718       safe_browsing_util::kMalwareList,
    719       sub_chunk.data(),
    720       static_cast<int>(sub_chunk.length()),
    721       "", "", &re_key, &chunks);
    722   EXPECT_TRUE(result);
    723   EXPECT_EQ(chunks.size(), 1U);
    724   EXPECT_EQ(chunks[0].chunk_number, 9);
    725   EXPECT_EQ(chunks[0].hosts.size(), 0U);
    726   chunks.clear();
    727 
    728   // Test parsing a zero sized sub chunk mixed in with content carrying chunks.
    729   std::string sub_chunks("s:1:4:9\nabcdxwxyz"
    730                          "s:2:4:0\n"
    731                          "s:3:4:26\nefgh\0011234pqrscafe\0015678lmno");
    732   sub_chunks[12] = '\0';
    733 
    734   result = parser.ParseChunk(
    735       safe_browsing_util::kMalwareList,
    736       sub_chunks.data(),
    737       static_cast<int>(sub_chunks.length()),
    738       "", "", &re_key, &chunks);
    739   EXPECT_TRUE(result);
    740 
    741   EXPECT_EQ(chunks[0].chunk_number, 1);
    742   EXPECT_EQ(chunks[0].hosts.size(), 1U);
    743   EXPECT_EQ(chunks[0].hosts[0].host, 0x64636261);
    744   EXPECT_EQ(chunks[0].hosts[0].entry->prefix_count(), 0);
    745 
    746   EXPECT_EQ(chunks[1].chunk_number, 2);
    747   EXPECT_EQ(chunks[1].hosts.size(), 0U);
    748 
    749   EXPECT_EQ(chunks[2].chunk_number, 3);
    750   EXPECT_EQ(chunks[2].hosts.size(), 2U);
    751   EXPECT_EQ(chunks[2].hosts[0].host, 0x68676665);
    752   EXPECT_EQ(chunks[2].hosts[0].entry->prefix_count(), 1);
    753   EXPECT_EQ(chunks[2].hosts[0].entry->PrefixAt(0), 0x73727170);
    754   EXPECT_EQ(chunks[2].hosts[0].entry->ChunkIdAtPrefix(0), 0x31323334);
    755   EXPECT_EQ(chunks[2].hosts[1].host, 0x65666163);
    756   EXPECT_EQ(chunks[2].hosts[1].entry->prefix_count(), 1);
    757   EXPECT_EQ(chunks[2].hosts[1].entry->PrefixAt(0), 0x6f6e6d6c);
    758   EXPECT_EQ(chunks[2].hosts[1].entry->ChunkIdAtPrefix(0), 0x35363738);
    759 }
    760 
    761 TEST(SafeBrowsingProtocolParsingTest, TestVerifyUpdateMac) {
    762   SafeBrowsingProtocolParser parser;
    763 
    764   const std::string update =
    765       "m:XIU0LiQhAPJq6dynXwHbygjS5tw=\n"
    766       "n:1895\n"
    767       "i:goog-phish-shavar\n"
    768       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6501-6505:6501-6505,"
    769         "pcY6iVeT9-CBQ3fdAF0rpnKjR1Y=\n"
    770       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6506-6510:6506-6510,"
    771         "SDBrYC3rX3KEPe72LOypnP6QYac=\n"
    772       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6511-6520:6511-6520,"
    773         "9UQo-e7OkcsXT2wFWTAhOuWOsUs=\n"
    774       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6521-6560:6521-6560,"
    775         "qVNw6JIpR1q6PIXST7J4LJ9n3Zg=\n"
    776       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6561-6720:6561-6720,"
    777         "7OiJvCbiwvpzPITW-hQohY5NHuc=\n"
    778       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6721-6880:6721-6880,"
    779         "oBS3svhoi9deIa0sWZ_gnD0ujj8=\n"
    780       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_6881-7040:6881-7040,"
    781         "a0r8Xit4VvH39xgyQHZTPczKBIE=\n"
    782       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_s_7041-7200:7041-7163,"
    783         "q538LChutGknBw55s6kcE2wTcvU=\n"
    784       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8001-8160:8001-8024,"
    785         "8026-8045,8048-8049,8051-8134,8136-8152,8155-8160,"
    786         "j6XXAEWnjYk9tVVLBSdQvIEq2Wg=\n"
    787       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8161-8320:8161-8215,"
    788         "8217-8222,8224-8320,YaNfiqdQOt-uLCLWVLj46AZpAjQ=\n"
    789       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8321-8480:8321-8391,"
    790         "8393-8399,8402,8404-8419,8421-8425,8427,8431-8433,8435-8439,8441-8443,"
    791         "8445-8446,8448-8480,ALj31GQMwGiIeU3bM2ZYKITfU-U=\n"
    792       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8481-8640:8481-8500,"
    793         "8502-8508,8510-8511,8513-8517,8519-8525,8527-8531,8533,8536-8539,"
    794         "8541-8576,8578-8638,8640,TlQYRmS_kZ5PBAUIUyNQDq0Jprs=\n"
    795       "u:s.ytimg.com/safebrowsing/rd/goog-phish-shavar_a_8641-8800:8641-8689,"
    796         "8691-8731,8733-8786,x1Qf7hdNrO8b6yym03ZzNydDS1o=\n";
    797 
    798   bool re_key = false;
    799   bool reset = false;
    800   int next_update = -1;
    801   std::vector<SBChunkDelete> deletes;
    802   std::vector<ChunkUrl> urls;
    803   const std::string key("58Lqn5WIP961x3zuLGo5Uw==");
    804   EXPECT_TRUE(parser.ParseUpdate(update.data(),
    805                                  static_cast<int>(update.size()), key,
    806                                  &next_update, &re_key,
    807                                  &reset, &deletes, &urls));
    808   EXPECT_FALSE(re_key);
    809   EXPECT_EQ(next_update, 1895);
    810 }
    811 
    812 TEST(SafeBrowsingProtocolParsingTest, TestVerifyChunkMac) {
    813   SafeBrowsingProtocolParser parser;
    814 
    815   const unsigned char chunk[] = {
    816     0x73, 0x3a, 0x32, 0x30, 0x30, 0x32, 0x3a, 0x34,
    817     0x3a, 0x32, 0x32, 0x0a, 0x2f, 0x4f, 0x89, 0x7a,
    818     0x01, 0x00, 0x00, 0x0a, 0x59, 0xc8, 0x71, 0xdf,
    819     0x9d, 0x29, 0x0c, 0xba, 0xd7, 0x00, 0x00, 0x00,
    820     0x0a, 0x59
    821   };
    822 
    823   bool re_key = false;
    824   SBChunkList chunks;
    825   const std::string key("v_aDSz6jI92WeHCOoZ07QA==");
    826   const std::string mac("W9Xp2fUcQ9V66If6Cvsrstpa4Kk=");
    827 
    828   EXPECT_TRUE(parser.ParseChunk(
    829       safe_browsing_util::kMalwareList,
    830       reinterpret_cast<const char*>(chunk),
    831       sizeof(chunk), key, mac,
    832       &re_key, &chunks));
    833   EXPECT_FALSE(re_key);
    834 }
    835 
    836 TEST(SafeBrowsingProtocolParsingTest, TestAddBinHashChunks) {
    837   std::string add_chunk("a:1:4:16\naaaabbbbccccdddd"
    838                         "a:2:4:8\n11112222");
    839   // Run the parse.
    840   SafeBrowsingProtocolParser parser;
    841   bool re_key = false;
    842   SBChunkList chunks;
    843   bool result = parser.ParseChunk(
    844       safe_browsing_util::kBinHashList,
    845       add_chunk.data(),
    846       static_cast<int>(add_chunk.length()),
    847       "", "", &re_key, &chunks);
    848   EXPECT_TRUE(result);
    849   EXPECT_FALSE(re_key);
    850   EXPECT_EQ(chunks.size(), 2U);
    851   EXPECT_EQ(chunks[0].chunk_number, 1);
    852   EXPECT_EQ(chunks[0].hosts.size(), 1U);
    853 
    854   EXPECT_EQ(chunks[0].hosts[0].host, 0);
    855   SBEntry* entry = chunks[0].hosts[0].entry;
    856   EXPECT_TRUE(entry->IsAdd());
    857   EXPECT_TRUE(entry->IsPrefix());
    858   EXPECT_EQ(entry->prefix_count(), 4);
    859 
    860   EXPECT_EQ(chunks[1].chunk_number, 2);
    861   EXPECT_EQ(chunks[1].hosts.size(), 1U);
    862 
    863   EXPECT_EQ(chunks[1].hosts[0].host, 0);
    864   entry = chunks[1].hosts[0].entry;
    865   EXPECT_TRUE(entry->IsAdd());
    866   EXPECT_TRUE(entry->IsPrefix());
    867   EXPECT_EQ(entry->prefix_count(), 2);
    868   EXPECT_EQ(entry->PrefixAt(0), 0x31313131);
    869   EXPECT_EQ(entry->PrefixAt(1), 0x32323232);
    870 }
    871 
    872 // Test parsing one add chunk where a hostkey spans several entries.
    873 TEST(SafeBrowsingProtocolParsingTest, TestAddBigBinHashChunk) {
    874   std::string add_chunk("a:1:4:1028\n");
    875   for (int i = 0; i < 257; ++i)
    876     add_chunk.append(StringPrintf("%04d", i));
    877 
    878   SafeBrowsingProtocolParser parser;
    879   bool re_key = false;
    880   SBChunkList chunks;
    881   bool result = parser.ParseChunk(
    882       safe_browsing_util::kBinHashList,
    883       add_chunk.data(),
    884       static_cast<int>(add_chunk.length()),
    885       "", "", &re_key, &chunks);
    886   EXPECT_TRUE(result);
    887   EXPECT_FALSE(re_key);
    888   EXPECT_EQ(chunks.size(), 1U);
    889   EXPECT_EQ(chunks[0].chunk_number, 1);
    890 
    891   EXPECT_EQ(chunks[0].hosts.size(), 1U);
    892 
    893   const SBChunkHost& host0 = chunks[0].hosts[0];
    894   EXPECT_EQ(host0.host, 0);
    895   EXPECT_EQ(host0.entry->prefix_count(), 257);
    896 }
    897 
    898 // Test parsing one sub chunk.
    899 TEST(SafeBrowsingProtocolParsingTest, TestSubBinHashChunk) {
    900   std::string sub_chunk("s:9:4:16\n1111mmmm2222nnnn");
    901 
    902   // Run the parser.
    903   SafeBrowsingProtocolParser parser;
    904   bool re_key = false;
    905   SBChunkList chunks;
    906   bool result = parser.ParseChunk(
    907       safe_browsing_util::kBinHashList,
    908       sub_chunk.data(),
    909       static_cast<int>(sub_chunk.length()),
    910       "", "", &re_key, &chunks);
    911   EXPECT_TRUE(result);
    912   EXPECT_FALSE(re_key);
    913   EXPECT_EQ(chunks.size(), 1U);
    914   EXPECT_EQ(chunks[0].chunk_number, 9);
    915   EXPECT_EQ(chunks[0].hosts.size(), 1U);
    916 
    917   EXPECT_EQ(chunks[0].hosts[0].host, 0);
    918   SBEntry* entry = chunks[0].hosts[0].entry;
    919   EXPECT_TRUE(entry->IsSub());
    920   EXPECT_TRUE(entry->IsPrefix());
    921   EXPECT_EQ(entry->prefix_count(), 2);
    922   EXPECT_EQ(entry->ChunkIdAtPrefix(0), 0x31313131);
    923   EXPECT_EQ(entry->PrefixAt(0), 0x6d6d6d6d);
    924   EXPECT_EQ(entry->ChunkIdAtPrefix(1), 0x32323232);
    925   EXPECT_EQ(entry->PrefixAt(1), 0x6e6e6e6e);
    926 }
    927