Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/url-classifier/ProtocolParser.h
Line
Count
Source (jump to first uncovered line)
1
//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#ifndef ProtocolParser_h__
7
#define ProtocolParser_h__
8
9
#include "HashStore.h"
10
#include "chromium/safebrowsing.pb.h"
11
12
namespace mozilla {
13
namespace safebrowsing {
14
15
/**
16
 * Abstract base class for parsing update data in multiple formats.
17
 */
18
class ProtocolParser {
19
public:
20
  struct ForwardedUpdate {
21
    nsCString table;
22
    nsCString url;
23
  };
24
25
  ProtocolParser();
26
  virtual ~ProtocolParser();
27
28
0
  nsresult Status() const { return mUpdateStatus; }
29
30
#ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
31
0
  virtual nsCString GetRawTableUpdates() const { return mPending; }
32
#endif
33
34
  virtual void SetCurrentTable(const nsACString& aTable) = 0;
35
36
  void SetRequestedTables(const nsTArray<nsCString>& aRequestTables)
37
0
  {
38
0
    mRequestedTables = aRequestTables;
39
0
  }
40
41
  nsresult Begin(const nsACString& aTable,
42
                 const nsTArray<nsCString>& aUpdateTables);
43
  virtual nsresult AppendStream(const nsACString& aData) = 0;
44
45
0
  uint32_t UpdateWaitSec() { return mUpdateWaitSec; }
46
47
  // Notify that the inbound data is ready for parsing if progressive
48
  // parsing is not supported, for example in V4.
49
  virtual void End() = 0;
50
51
  RefPtr<TableUpdate> GetTableUpdate(const nsACString& aTable);
52
0
  void ForgetTableUpdates() { mTableUpdates.Clear(); }
53
0
  const TableUpdateArray& GetTableUpdates() { return mTableUpdates; }
54
55
  // These are only meaningful to V2. Since they were originally public,
56
  // moving them to ProtocolParserV2 requires a dymamic cast in the call
57
  // sites. As a result, we will leave them until we remove support
58
  // for V2 entirely..
59
0
  virtual const nsTArray<ForwardedUpdate> &Forwards() const { return mForwards; }
60
0
  bool ResetRequested() const { return !mTablesToReset.IsEmpty(); }
61
0
  const nsTArray<nsCString>& TablesToReset() const { return mTablesToReset; }
62
63
protected:
64
  virtual RefPtr<TableUpdate> CreateTableUpdate(const nsACString& aTableName) const = 0;
65
66
  nsCString mPending;
67
  nsresult mUpdateStatus;
68
69
  // Keep track of updates to apply before passing them to the DBServiceWorkers.
70
  TableUpdateArray mTableUpdates;
71
72
  nsTArray<ForwardedUpdate> mForwards;
73
74
  // The table names that were requested from the client.
75
  nsTArray<nsCString> mRequestedTables;
76
77
  // The table names that failed to update and need to be reset.
78
  nsTArray<nsCString> mTablesToReset;
79
80
  // How long we should wait until the next update.
81
  uint32_t mUpdateWaitSec;
82
};
83
84
/**
85
 * Helpers to parse the "shavar", "digest256" and "simple" list formats.
86
 */
87
class ProtocolParserV2 final : public ProtocolParser {
88
public:
89
  ProtocolParserV2();
90
  virtual ~ProtocolParserV2();
91
92
  virtual void SetCurrentTable(const nsACString& aTable) override;
93
  virtual nsresult AppendStream(const nsACString& aData) override;
94
  virtual void End() override;
95
96
  // Update information.
97
0
  virtual const nsTArray<ForwardedUpdate> &Forwards() const override { return mForwards; }
98
99
#ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
100
  // Unfortunately we have to override to return mRawUpdate which
101
  // will not be modified during the parsing, unlike mPending.
102
0
  virtual nsCString GetRawTableUpdates() const override { return mRawUpdate; }
103
#endif
104
105
private:
106
  virtual RefPtr<TableUpdate> CreateTableUpdate(const nsACString& aTableName) const override;
107
108
  nsresult ProcessControl(bool* aDone);
109
  nsresult ProcessExpirations(const nsCString& aLine);
110
  nsresult ProcessChunkControl(const nsCString& aLine);
111
  nsresult ProcessForward(const nsCString& aLine);
112
  nsresult AddForward(const nsACString& aUrl);
113
  nsresult ProcessChunk(bool* done);
114
  // Remove this, it's only used for testing
115
  nsresult ProcessPlaintextChunk(const nsACString& aChunk);
116
  nsresult ProcessShaChunk(const nsACString& aChunk);
117
  nsresult ProcessHostAdd(const Prefix& aDomain, uint8_t aNumEntries,
118
                          const nsACString& aChunk, uint32_t* aStart);
119
  nsresult ProcessHostSub(const Prefix& aDomain, uint8_t aNumEntries,
120
                          const nsACString& aChunk, uint32_t* aStart);
121
  nsresult ProcessHostAddComplete(uint8_t aNumEntries, const nsACString& aChunk,
122
                                  uint32_t *aStart);
123
  nsresult ProcessHostSubComplete(uint8_t numEntries, const nsACString& aChunk,
124
                                  uint32_t* start);
125
  // Digest chunks are very similar to shavar chunks, except digest chunks
126
  // always contain the full hash, so there is no need for chunk data to
127
  // contain prefix sizes.
128
  nsresult ProcessDigestChunk(const nsACString& aChunk);
129
  nsresult ProcessDigestAdd(const nsACString& aChunk);
130
  nsresult ProcessDigestSub(const nsACString& aChunk);
131
  bool NextLine(nsACString& aLine);
132
133
  enum ParserState {
134
    PROTOCOL_STATE_CONTROL,
135
    PROTOCOL_STATE_CHUNK
136
  };
137
  ParserState mState;
138
139
  enum ChunkType {
140
    // Types for shavar tables.
141
    CHUNK_ADD,
142
    CHUNK_SUB,
143
    // Types for digest256 tables. digest256 tables differ in format from
144
    // shavar tables since they only contain complete hashes.
145
    CHUNK_ADD_DIGEST,
146
    CHUNK_SUB_DIGEST
147
  };
148
149
  struct ChunkState {
150
    ChunkType type;
151
    uint32_t num;
152
    uint32_t hashSize;
153
    uint32_t length;
154
0
    void Clear() { num = 0; hashSize = 0; length = 0; }
155
  };
156
  ChunkState mChunkState;
157
158
  // Updates to apply to the current table being parsed.
159
  RefPtr<TableUpdateV2> mTableUpdate;
160
161
#ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
162
  nsCString mRawUpdate; // Keep a copy of mPending before it's processed.
163
#endif
164
};
165
166
// Helpers to parse the "proto" list format.
167
class ProtocolParserProtobuf final : public ProtocolParser {
168
public:
169
  typedef FetchThreatListUpdatesResponse_ListUpdateResponse ListUpdateResponse;
170
  typedef google::protobuf::RepeatedPtrField<ThreatEntrySet> ThreatEntrySetList;
171
172
public:
173
  ProtocolParserProtobuf();
174
175
  virtual void SetCurrentTable(const nsACString& aTable) override;
176
  virtual nsresult AppendStream(const nsACString& aData) override;
177
  virtual void End() override;
178
179
private:
180
  virtual ~ProtocolParserProtobuf();
181
182
  virtual RefPtr<TableUpdate> CreateTableUpdate(const nsACString& aTableName) const override;
183
184
  // For parsing update info.
185
  nsresult ProcessOneResponse(const ListUpdateResponse& aResponse,
186
                              nsACString& aListName);
187
188
  nsresult ProcessAdditionOrRemoval(TableUpdateV4& aTableUpdate,
189
                                    const ThreatEntrySetList& aUpdate,
190
                                    bool aIsAddition);
191
192
  nsresult ProcessRawAddition(TableUpdateV4& aTableUpdate,
193
                              const ThreatEntrySet& aAddition);
194
195
  nsresult ProcessRawRemoval(TableUpdateV4& aTableUpdate,
196
                             const ThreatEntrySet& aRemoval);
197
198
  nsresult ProcessEncodedAddition(TableUpdateV4& aTableUpdate,
199
                                  const ThreatEntrySet& aAddition);
200
201
  nsresult ProcessEncodedRemoval(TableUpdateV4& aTableUpdate,
202
                                 const ThreatEntrySet& aRemoval);
203
};
204
205
} // namespace safebrowsing
206
} // namespace mozilla
207
208
#endif