Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/url-classifier/Classifier.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 Classifier_h__
7
#define Classifier_h__
8
9
#include "Entries.h"
10
#include "HashStore.h"
11
#include "ProtocolParser.h"
12
#include "LookupCache.h"
13
#include "nsCOMPtr.h"
14
#include "nsString.h"
15
#include "nsIFile.h"
16
#include "nsDataHashtable.h"
17
18
class nsIThread;
19
20
namespace mozilla {
21
namespace safebrowsing {
22
23
/**
24
 * Maintains the stores and LookupCaches for the url classifier.
25
 */
26
class Classifier {
27
public:
28
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Classifier);
29
30
  Classifier();
31
32
  nsresult Open(nsIFile& aCacheDirectory);
33
  void Close();
34
  void Reset(); // Not including any intermediary for update.
35
36
  /**
37
   * Clear data for specific tables.
38
   * If ClearType is Clear_Cache, this function will only clear cache in lookup
39
   * cache, otherwise, it will clear data in lookup cache and data stored on disk.
40
   */
41
  enum ClearType {
42
    Clear_Cache,
43
    Clear_All,
44
  };
45
  void ResetTables(ClearType aType, const nsTArray<nsCString>& aTables);
46
47
  /**
48
   * Get the list of active tables and their chunks in a format
49
   * suitable for an update request.
50
   */
51
  void TableRequest(nsACString& aResult);
52
53
  /*
54
   * Get all tables that we know about.
55
   */
56
  nsresult ActiveTables(nsTArray<nsCString>& aTables) const;
57
58
  /**
59
   * Check a URL against the specified tables.
60
   */
61
  nsresult Check(const nsACString& aSpec,
62
                 const nsACString& tables,
63
                 LookupResultArray& aResults);
64
65
  /**
66
   * Asynchronously apply updates to the in-use databases. When the
67
   * update is complete, the caller can be notified by |aCallback|, which
68
   * will occur on the caller thread.
69
   */
70
  using AsyncUpdateCallback = std::function<void(nsresult)>;
71
  nsresult AsyncApplyUpdates(const TableUpdateArray& aUpdates,
72
                             const AsyncUpdateCallback& aCallback);
73
74
  /**
75
   * Wait until the ongoing async update is finished and callback
76
   * is fired. Once this function returns, AsyncApplyUpdates is
77
   * no longer available.
78
   */
79
  void FlushAndDisableAsyncUpdate();
80
81
  /**
82
   * Apply full hashes retrived from gethash to cache.
83
   */
84
  nsresult ApplyFullHashes(ConstTableUpdateArray& aUpdates);
85
86
  /*
87
   * Get a bunch of extra prefixes to query for completion
88
   * and mask the real entry being requested
89
   */
90
  nsresult ReadNoiseEntries(const Prefix& aPrefix,
91
                            const nsACString& aTableName,
92
                            uint32_t aCount,
93
                            PrefixArray& aNoiseEntries);
94
95
#ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
96
  nsresult DumpRawTableUpdates(const nsACString& aRawUpdates);
97
#endif
98
99
  static void SplitTables(const nsACString& str, nsTArray<nsCString>& tables);
100
101
  // Given a root store directory, return a private store directory
102
  // based on the table name. To avoid migration issue, the private
103
  // store directory is only different from root directory for V4 tables.
104
  //
105
  // For V4 tables (suffixed by '-proto'), the private directory would
106
  // be [root directory path]/[provider]. The provider of V4 tables is
107
  // 'google4'.
108
  //
109
  // Note that if the table name is not owned by any provider, just use
110
  // the root directory.
111
  static nsresult GetPrivateStoreDirectory(nsIFile* aRootStoreDirectory,
112
                                           const nsACString& aTableName,
113
                                           const nsACString& aProvider,
114
                                           nsIFile** aPrivateStoreDirectory);
115
116
  // Swap in in-memory and on-disk database and remove all
117
  // update intermediaries.
118
  nsresult SwapInNewTablesAndCleanup();
119
120
  RefPtr<LookupCache> GetLookupCache(const nsACString& aTable,
121
                                     bool aForUpdate = false);
122
123
  void GetCacheInfo(const nsACString& aTable,
124
                    nsIUrlClassifierCacheInfo** aCache);
125
126
private:
127
  ~Classifier();
128
129
  void DropStores();
130
  void DeleteTables(nsIFile* aDirectory, const nsTArray<nsCString>& aTables);
131
132
  nsresult CreateStoreDirectory();
133
  nsresult SetupPathNames();
134
  nsresult RecoverBackups();
135
  nsresult CleanToDelete();
136
  nsresult CopyInUseDirForUpdate();
137
  nsresult CopyDirectoryInterruptible(nsCOMPtr<nsIFile>& aDestDir, nsCOMPtr<nsIFile>& aSourceDir);
138
  nsresult RegenActiveTables();
139
140
  void MergeNewLookupCaches(); // Merge mNewLookupCaches into mLookupCaches.
141
142
  void CopyAndInvalidateFullHashCache();
143
144
  // Remove any intermediary for update, including in-memory
145
  // and on-disk data.
146
  void RemoveUpdateIntermediaries();
147
148
#ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
149
  already_AddRefed<nsIFile> GetFailedUpdateDirectroy();
150
  nsresult DumpFailedUpdate();
151
#endif
152
153
  nsresult ScanStoreDir(nsIFile* aDirectory, nsTArray<nsCString>& aTables);
154
155
  nsresult UpdateHashStore(TableUpdateArray& aUpdates,
156
                           const nsACString& aTable);
157
158
  nsresult UpdateTableV4(TableUpdateArray& aUpdates,
159
                         const nsACString& aTable);
160
161
  nsresult UpdateCache(RefPtr<const TableUpdate> aUpdates);
162
163
0
  RefPtr<LookupCache> GetLookupCacheForUpdate(const nsACString& aTable) {
164
0
    return GetLookupCache(aTable, true);
165
0
  }
166
167
  RefPtr<LookupCache> GetLookupCacheFrom(const nsACString& aTable,
168
                                         LookupCacheArray& aLookupCaches,
169
                                         nsIFile* aRootStoreDirectory);
170
171
172
  bool CheckValidUpdate(TableUpdateArray& aUpdates,
173
                        const nsACString& aTable);
174
175
  nsresult LoadMetadata(nsIFile* aDirectory, nsACString& aResult);
176
177
  static nsCString GetProvider(const nsACString& aTableName);
178
179
  /**
180
   * The "background" part of ApplyUpdates. Once the background update
181
   * is called, the foreground update has to be called along with the
182
   * background result no matter whether the background update is
183
   * successful or not.
184
   */
185
  nsresult ApplyUpdatesBackground(TableUpdateArray& aUpdates,
186
                                  nsACString& aFailedTableName);
187
188
  /**
189
   * The "foreground" part of ApplyUpdates. The in-use data (in-memory and
190
   * on-disk) will be touched so this MUST be mutually exclusive to other
191
   * member functions.
192
   *
193
   * If |aBackgroundRv| is successful, the return value is the result of
194
   * bringing stuff to the foreground. Otherwise, the foreground table may
195
   * be reset according to the background update failed reason and
196
   * |aBackgroundRv| will be returned to forward the background update result.
197
   */
198
  nsresult ApplyUpdatesForeground(nsresult aBackgroundRv,
199
                                  const nsACString& aFailedTableName);
200
201
  // Root dir of the Local profile.
202
  nsCOMPtr<nsIFile> mCacheDirectory;
203
  // Main directory where to store the databases.
204
  nsCOMPtr<nsIFile> mRootStoreDirectory;
205
  // Used for atomically updating the other dirs.
206
  nsCOMPtr<nsIFile> mBackupDirectory;
207
  nsCOMPtr<nsIFile> mUpdatingDirectory; // For update only.
208
  nsCOMPtr<nsIFile> mToDeleteDirectory;
209
  LookupCacheArray mLookupCaches; // For query only.
210
  nsTArray<nsCString> mActiveTablesCache;
211
  uint32_t mHashKey;
212
213
  // In-memory cache for the result of TableRequest. See
214
  // nsIUrlClassifierDBService.getTables for the format.
215
  nsCString mTableRequestResult;
216
217
  // Whether mTableRequestResult is outdated and needs to
218
  // be reloaded from disk.
219
  bool mIsTableRequestResultOutdated;
220
221
  // The copy of mLookupCaches for update only.
222
  LookupCacheArray mNewLookupCaches;
223
224
  bool mUpdateInterrupted;
225
226
  nsCOMPtr<nsIThread> mUpdateThread; // For async update.
227
228
  // Identical to mRootStoreDirectory but for update only because
229
  // nsIFile is not thread safe and mRootStoreDirectory needs to
230
  // be accessed in CopyInUseDirForUpdate().
231
  // It will be initialized right before update on the worker thread.
232
  nsCOMPtr<nsIFile> mRootStoreDirectoryForUpdate;
233
234
  bool mIsClosed; // true once Close() has been called
235
};
236
237
} // namespace safebrowsing
238
} // namespace mozilla
239
240
#endif