/src/mozilla-central/toolkit/components/url-classifier/tests/gtest/TestProtocolParser.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* Any copyright is dedicated to the Public Domain. |
2 | | * http://creativecommons.org/publicdomain/zero/1.0/ */ |
3 | | |
4 | | #include "gtest/gtest.h" |
5 | | #include "ProtocolParser.h" |
6 | | #include "mozilla/EndianUtils.h" |
7 | | |
8 | | using namespace mozilla; |
9 | | using namespace mozilla::safebrowsing; |
10 | | |
11 | | typedef FetchThreatListUpdatesResponse_ListUpdateResponse ListUpdateResponse; |
12 | | |
13 | | static bool |
14 | | InitUpdateResponse(ListUpdateResponse* aUpdateResponse, |
15 | | ThreatType aThreatType, |
16 | | const nsACString& aState, |
17 | | const nsACString& aChecksum, |
18 | | bool isFullUpdate, |
19 | | const nsTArray<uint32_t>& aFixedLengthPrefixes, |
20 | | bool aDoPrefixEncoding); |
21 | | |
22 | | static void |
23 | | DumpBinary(const nsACString& aBinary); |
24 | | |
25 | | TEST(UrlClassifierProtocolParser, UpdateWait) |
26 | 0 | { |
27 | 0 | // Top level response which contains a list of update response |
28 | 0 | // for different lists. |
29 | 0 | FetchThreatListUpdatesResponse response; |
30 | 0 |
|
31 | 0 | auto r = response.mutable_list_update_responses()->Add(); |
32 | 0 | InitUpdateResponse(r, SOCIAL_ENGINEERING_PUBLIC, |
33 | 0 | nsCString("sta\x00te", 6), |
34 | 0 | nsCString("check\x0sum", 9), |
35 | 0 | true, |
36 | 0 | {0, 1, 2, 3}, |
37 | 0 | false /* aDoPrefixEncoding */ ); |
38 | 0 |
|
39 | 0 | // Set min wait duration. |
40 | 0 | auto minWaitDuration = response.mutable_minimum_wait_duration(); |
41 | 0 | minWaitDuration->set_seconds(8); |
42 | 0 | minWaitDuration->set_nanos(1 * 1000000000); |
43 | 0 |
|
44 | 0 | std::string s; |
45 | 0 | response.SerializeToString(&s); |
46 | 0 |
|
47 | 0 | DumpBinary(nsCString(s.c_str(), s.length())); |
48 | 0 |
|
49 | 0 | ProtocolParser* p = new ProtocolParserProtobuf(); |
50 | 0 | p->AppendStream(nsCString(s.c_str(), s.length())); |
51 | 0 | p->End(); |
52 | 0 | ASSERT_EQ(p->UpdateWaitSec(), 9u); |
53 | 0 | delete p; |
54 | 0 | } |
55 | | |
56 | | TEST(UrlClassifierProtocolParser, SingleValueEncoding) |
57 | 0 | { |
58 | 0 | // Top level response which contains a list of update response |
59 | 0 | // for different lists. |
60 | 0 | FetchThreatListUpdatesResponse response; |
61 | 0 |
|
62 | 0 | auto r = response.mutable_list_update_responses()->Add(); |
63 | 0 |
|
64 | 0 | const char* expectedPrefix = "\x00\x01\x02\x00"; |
65 | 0 | if (!InitUpdateResponse(r, SOCIAL_ENGINEERING_PUBLIC, |
66 | 0 | nsCString("sta\x00te", 6), |
67 | 0 | nsCString("check\x0sum", 9), |
68 | 0 | true, |
69 | 0 | // As per spec, we should interpret the prefix as uint32 |
70 | 0 | // in little endian before encoding. |
71 | 0 | {LittleEndian::readUint32(expectedPrefix)}, |
72 | 0 | true /* aDoPrefixEncoding */ )) { |
73 | 0 | printf("Failed to initialize update response."); |
74 | 0 | ASSERT_TRUE(false); |
75 | 0 | return; |
76 | 0 | } |
77 | 0 | |
78 | 0 | // Set min wait duration. |
79 | 0 | auto minWaitDuration = response.mutable_minimum_wait_duration(); |
80 | 0 | minWaitDuration->set_seconds(8); |
81 | 0 | minWaitDuration->set_nanos(1 * 1000000000); |
82 | 0 |
|
83 | 0 | std::string s; |
84 | 0 | response.SerializeToString(&s); |
85 | 0 |
|
86 | 0 | // Feed data to the protocol parser. |
87 | 0 | ProtocolParser* p = new ProtocolParserProtobuf(); |
88 | 0 | p->SetRequestedTables({ nsCString("googpub-phish-proto") }); |
89 | 0 | p->AppendStream(nsCString(s.c_str(), s.length())); |
90 | 0 | p->End(); |
91 | 0 |
|
92 | 0 | const TableUpdateArray& tus = p->GetTableUpdates(); |
93 | 0 | RefPtr<const TableUpdateV4> tuv4 = TableUpdate::Cast<TableUpdateV4>(tus[0]); |
94 | 0 | auto& prefixMap = tuv4->Prefixes(); |
95 | 0 | for (auto iter = prefixMap.ConstIter(); !iter.Done(); iter.Next()) { |
96 | 0 | // This prefix map should contain only a single 4-byte prefixe. |
97 | 0 | ASSERT_EQ(iter.Key(), 4u); |
98 | 0 |
|
99 | 0 | // The fixed-length prefix string from ProtocolParser should |
100 | 0 | // exactly match the expected prefix string. |
101 | 0 | nsCString* prefix = iter.Data(); |
102 | 0 | ASSERT_TRUE(prefix->Equals(nsCString(expectedPrefix, 4))); |
103 | 0 | } |
104 | 0 |
|
105 | 0 | delete p; |
106 | 0 | } |
107 | | |
108 | | static bool |
109 | | InitUpdateResponse(ListUpdateResponse* aUpdateResponse, |
110 | | ThreatType aThreatType, |
111 | | const nsACString& aState, |
112 | | const nsACString& aChecksum, |
113 | | bool isFullUpdate, |
114 | | const nsTArray<uint32_t>& aFixedLengthPrefixes, |
115 | | bool aDoPrefixEncoding) |
116 | 0 | { |
117 | 0 | aUpdateResponse->set_threat_type(aThreatType); |
118 | 0 | aUpdateResponse->set_new_client_state(aState.BeginReading(), aState.Length()); |
119 | 0 | aUpdateResponse->mutable_checksum()->set_sha256(aChecksum.BeginReading(), aChecksum.Length()); |
120 | 0 | aUpdateResponse->set_response_type(isFullUpdate ? ListUpdateResponse::FULL_UPDATE |
121 | 0 | : ListUpdateResponse::PARTIAL_UPDATE); |
122 | 0 |
|
123 | 0 | auto additions = aUpdateResponse->mutable_additions()->Add(); |
124 | 0 |
|
125 | 0 | if (!aDoPrefixEncoding) { |
126 | 0 | additions->set_compression_type(RAW); |
127 | 0 | auto rawHashes = additions->mutable_raw_hashes(); |
128 | 0 | rawHashes->set_prefix_size(4); |
129 | 0 | auto prefixes = rawHashes->mutable_raw_hashes(); |
130 | 0 | for (auto p : aFixedLengthPrefixes) { |
131 | 0 | char buffer[4]; |
132 | 0 | NativeEndian::copyAndSwapToBigEndian(buffer, &p, 1); |
133 | 0 | prefixes->append(buffer, 4); |
134 | 0 | } |
135 | 0 | return true; |
136 | 0 | } |
137 | 0 |
|
138 | 0 | if (1 != aFixedLengthPrefixes.Length()) { |
139 | 0 | printf("This function only supports single value encoding.\n"); |
140 | 0 | return false; |
141 | 0 | } |
142 | 0 | |
143 | 0 | uint32_t firstValue = aFixedLengthPrefixes[0]; |
144 | 0 | additions->set_compression_type(RICE); |
145 | 0 | auto riceHashes = additions->mutable_rice_hashes(); |
146 | 0 | riceHashes->set_first_value(firstValue); |
147 | 0 | riceHashes->set_num_entries(0); |
148 | 0 |
|
149 | 0 | return true; |
150 | 0 | } |
151 | | |
152 | | static void DumpBinary(const nsACString& aBinary) |
153 | 0 | { |
154 | 0 | nsCString s; |
155 | 0 | for (size_t i = 0; i < aBinary.Length(); i++) { |
156 | 0 | s.AppendPrintf("\\x%.2X", (uint8_t)aBinary[i]); |
157 | 0 | } |
158 | 0 | printf("%s\n", s.get()); |
159 | 0 | } |