Coverage Report

Created: 2018-09-25 14:53

/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
}