зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset fc8099c8f98a (bug 1311935)
This commit is contained in:
Родитель
81e1f786ea
Коммит
49d5b0cb36
|
@ -318,44 +318,6 @@ typedef nsClassHashtable<nsUint32HashKey, nsCString> PrefixStringMap;
|
|||
|
||||
typedef nsDataHashtable<nsCStringHashKey, int64_t> TableFreshnessMap;
|
||||
|
||||
typedef nsCStringHashKey VLHashPrefixString;
|
||||
typedef nsCStringHashKey FullHashString;
|
||||
|
||||
typedef nsDataHashtable<FullHashString, int64_t> FullHashExpiryCache;
|
||||
|
||||
struct CachedFullHashResponse {
|
||||
int64_t negativeCacheExpirySec;
|
||||
|
||||
// Map contains all matches found in Fullhash response, this field might be empty.
|
||||
FullHashExpiryCache fullHashes;
|
||||
|
||||
CachedFullHashResponse& operator=(const CachedFullHashResponse& aOther) {
|
||||
negativeCacheExpirySec = aOther.negativeCacheExpirySec;
|
||||
|
||||
fullHashes.Clear();
|
||||
for (auto iter = aOther.fullHashes.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
fullHashes.Put(iter.Key(), iter.Data());
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const CachedFullHashResponse& aOther) const {
|
||||
if (negativeCacheExpirySec != aOther.negativeCacheExpirySec ||
|
||||
fullHashes.Count() != aOther.fullHashes.Count()) {
|
||||
return false;
|
||||
}
|
||||
for (auto iter = fullHashes.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
if (iter.Data() != aOther.fullHashes.Get(iter.Key())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef nsClassHashtable<VLHashPrefixString, CachedFullHashResponse> FullHashResponseMap;
|
||||
|
||||
} // namespace safebrowsing
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -193,19 +193,6 @@ TableUpdateV4::NewChecksum(const std::string& aChecksum)
|
|||
mChecksum.Assign(aChecksum.data(), aChecksum.size());
|
||||
}
|
||||
|
||||
nsresult
|
||||
TableUpdateV4::NewFullHashResponse(const nsACString& aPrefix,
|
||||
CachedFullHashResponse& aResponse)
|
||||
{
|
||||
CachedFullHashResponse* response =
|
||||
mFullHashResponseMap.LookupOrAdd(aPrefix);
|
||||
if (!response) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
*response = aResponse;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
HashStore::HashStore(const nsACString& aTableName,
|
||||
const nsACString& aProvider,
|
||||
nsIFile* aRootStoreDir)
|
||||
|
|
|
@ -159,9 +159,7 @@ public:
|
|||
|
||||
bool Empty() const override
|
||||
{
|
||||
return mPrefixesMap.IsEmpty() &&
|
||||
mRemovalIndiceArray.IsEmpty() &&
|
||||
mFullHashResponseMap.IsEmpty();
|
||||
return mPrefixesMap.IsEmpty() && mRemovalIndiceArray.IsEmpty();
|
||||
}
|
||||
|
||||
bool IsFullUpdate() const { return mFullUpdate; }
|
||||
|
@ -169,7 +167,6 @@ public:
|
|||
RemovalIndiceArray& RemovalIndices() { return mRemovalIndiceArray; }
|
||||
const nsACString& ClientState() const { return mClientState; }
|
||||
const nsACString& Checksum() const { return mChecksum; }
|
||||
const FullHashResponseMap& FullHashResponse() const { return mFullHashResponseMap; }
|
||||
|
||||
// For downcasting.
|
||||
static const int TAG = 4;
|
||||
|
@ -179,8 +176,6 @@ public:
|
|||
void NewRemovalIndices(const uint32_t* aIndices, size_t aNumOfIndices);
|
||||
void SetNewClientState(const nsACString& aState) { mClientState = aState; }
|
||||
void NewChecksum(const std::string& aChecksum);
|
||||
nsresult NewFullHashResponse(const nsACString& aPrefix,
|
||||
CachedFullHashResponse& aResponse);
|
||||
|
||||
private:
|
||||
virtual int Tag() const override { return TAG; }
|
||||
|
@ -190,9 +185,6 @@ private:
|
|||
RemovalIndiceArray mRemovalIndiceArray;
|
||||
nsCString mClientState;
|
||||
nsCString mChecksum;
|
||||
|
||||
// This is used to store response from fullHashes.find.
|
||||
FullHashResponseMap mFullHashResponseMap;
|
||||
};
|
||||
|
||||
// There is one hash store per table.
|
||||
|
|
|
@ -40,9 +40,6 @@ extern mozilla::LazyLogModule gUrlClassifierDbServiceLog;
|
|||
namespace mozilla {
|
||||
namespace safebrowsing {
|
||||
|
||||
const int CacheResultV2::VER = CacheResult::V2;
|
||||
const int CacheResultV4::VER = CacheResult::V4;
|
||||
|
||||
const int LookupCacheV2::VER = 2;
|
||||
|
||||
LookupCache::LookupCache(const nsACString& aTableName,
|
||||
|
|
|
@ -103,68 +103,18 @@ public:
|
|||
|
||||
typedef nsTArray<LookupResult> LookupResultArray;
|
||||
|
||||
class CacheResult {
|
||||
public:
|
||||
enum { V2, V4 };
|
||||
|
||||
virtual int Ver() const = 0;
|
||||
virtual bool findCompletion(const Completion& aCompletion) const = 0;
|
||||
|
||||
virtual ~CacheResult() {}
|
||||
|
||||
template<typename T>
|
||||
static T* Cast(CacheResult* aThat) {
|
||||
return ((aThat && T::VER == aThat->Ver()) ?
|
||||
reinterpret_cast<T*>(aThat) : nullptr);
|
||||
}
|
||||
|
||||
struct CacheResult {
|
||||
AddComplete entry;
|
||||
nsCString table;
|
||||
|
||||
bool operator==(const CacheResult& aOther) const {
|
||||
if (entry != aOther.entry) {
|
||||
return false;
|
||||
}
|
||||
return table == aOther.table;
|
||||
}
|
||||
};
|
||||
|
||||
class CacheResultV2 final : public CacheResult
|
||||
{
|
||||
public:
|
||||
static const int VER;
|
||||
|
||||
Completion completion;
|
||||
uint32_t addChunk;
|
||||
|
||||
bool operator==(const CacheResultV2& aOther) const {
|
||||
return table == aOther.table &&
|
||||
completion == aOther.completion &&
|
||||
addChunk == aOther.addChunk;
|
||||
}
|
||||
|
||||
bool findCompletion(const Completion& aCompletion) const override {
|
||||
return completion == aCompletion;
|
||||
}
|
||||
|
||||
virtual int Ver() const override { return VER; }
|
||||
};
|
||||
|
||||
class CacheResultV4 final : public CacheResult
|
||||
{
|
||||
public:
|
||||
static const int VER;
|
||||
|
||||
nsCString prefix;
|
||||
CachedFullHashResponse response;
|
||||
|
||||
bool operator==(const CacheResultV4& aOther) const {
|
||||
return prefix == aOther.prefix &&
|
||||
response == aOther.response;
|
||||
}
|
||||
|
||||
bool findCompletion(const Completion& aCompletion) const override {
|
||||
nsDependentCSubstring completion(
|
||||
reinterpret_cast<const char*>(aCompletion.buf), COMPLETE_SIZE);
|
||||
return response.fullHashes.Contains(completion);
|
||||
}
|
||||
|
||||
virtual int Ver() const override { return VER; }
|
||||
};
|
||||
|
||||
typedef nsTArray<UniquePtr<CacheResult>> CacheResultArray;
|
||||
typedef nsTArray<CacheResult> CacheResultArray;
|
||||
|
||||
class LookupCache {
|
||||
public:
|
||||
|
|
|
@ -4,23 +4,6 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIArray;
|
||||
|
||||
/**
|
||||
* This interface contains feilds in Matches object of FullHashResponse(V4).
|
||||
* Reference from:
|
||||
* https://developers.google.com/safe-browsing/v4/update-api#http-post-response_2
|
||||
*/
|
||||
[scriptable, uuid(aabeb50e-d9f7-418e-9469-2cd9608958c0)]
|
||||
interface nsIFullHashMatch : nsISupports
|
||||
{
|
||||
readonly attribute ACString tableName;
|
||||
|
||||
readonly attribute ACString fullHash;
|
||||
|
||||
readonly attribute uint32_t cacheDuration;
|
||||
};
|
||||
|
||||
/**
|
||||
* This interface is implemented by nsIUrlClassifierHashCompleter clients.
|
||||
*/
|
||||
|
@ -33,33 +16,15 @@ interface nsIUrlClassifierHashCompleterCallback : nsISupports
|
|||
* nsIUrlClassifierCompleter::complete() call.
|
||||
*
|
||||
* @param hash
|
||||
* The 256-bit hash that was discovered.
|
||||
* The 128-bit hash that was discovered.
|
||||
* @param table
|
||||
* The name of the table that this hash belongs to.
|
||||
* @param chunkId
|
||||
* The database chunk that this hash belongs to.
|
||||
*/
|
||||
void completionV2(in ACString hash,
|
||||
in ACString table,
|
||||
in uint32_t chunkId);
|
||||
|
||||
/**
|
||||
* This will be called when a fullhash response is received and parsed
|
||||
* no matter if any full hash has been found.
|
||||
*
|
||||
* @param partialHash
|
||||
* The hash that was sent for completion.
|
||||
* @param table
|
||||
* The name of the table that this hash belongs to.
|
||||
* @param negativeCacheDuration
|
||||
* The negative cache duration in millisecond.
|
||||
* @param fullHashes
|
||||
* Array of fullhashes that match the prefix.
|
||||
*/
|
||||
void completionV4(in ACString partialHash,
|
||||
in ACString table,
|
||||
in uint32_t negativeCacheDuration,
|
||||
in nsIArray fullHashes);
|
||||
void completion(in ACString hash,
|
||||
in ACString table,
|
||||
in uint32_t chunkId);
|
||||
|
||||
/**
|
||||
* The completion is complete. This method is called once per
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsICryptoHash.h"
|
||||
#include "nsICryptoHMAC.h"
|
||||
|
@ -123,9 +122,6 @@ LazyLogModule gUrlClassifierDbServiceLog("UrlClassifierDbService");
|
|||
#define CONFIRM_AGE_PREF "urlclassifier.max-complete-age"
|
||||
#define CONFIRM_AGE_DEFAULT_SEC (45 * 60)
|
||||
|
||||
// 30 minutes as the maximum negative cache duration.
|
||||
#define MAXIMUM_NEGATIVE_CACHE_DURATION_SEC (30 * 60 * 1000)
|
||||
|
||||
// TODO: The following two prefs are to be removed after we
|
||||
// roll out full v4 hash completion. See Bug 1331534.
|
||||
#define TAKE_V4_COMPLETION_RESULT_PREF "browser.safebrowsing.temporary.take_v4_completion_result"
|
||||
|
@ -842,26 +838,19 @@ nsUrlClassifierDBServiceWorker::CacheCompletions(CacheResultArray *results)
|
|||
}
|
||||
|
||||
LOG(("nsUrlClassifierDBServiceWorker::CacheCompletions [%p]", this));
|
||||
if (!mClassifier) {
|
||||
if (!mClassifier)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Ownership is transferred in to us
|
||||
nsAutoPtr<CacheResultArray> resultsPtr(results);
|
||||
|
||||
if (resultsPtr->Length() == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (IsSameAsLastResults(*resultsPtr)) {
|
||||
if (mLastResults == *resultsPtr) {
|
||||
LOG(("Skipping completions that have just been cached already."));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoPtr<ProtocolParser> pParse;
|
||||
pParse = resultsPtr->ElementAt(0)->Ver() == CacheResult::V2 ?
|
||||
static_cast<ProtocolParser*>(new ProtocolParserV2()) :
|
||||
static_cast<ProtocolParser*>(new ProtocolParserProtobuf());
|
||||
nsAutoPtr<ProtocolParserV2> pParse(new ProtocolParserV2());
|
||||
nsTArray<TableUpdate*> updates;
|
||||
|
||||
// Only cache results for tables that we have, don't take
|
||||
// in tables we might accidentally have hit during a completion.
|
||||
|
@ -870,28 +859,37 @@ nsUrlClassifierDBServiceWorker::CacheCompletions(CacheResultArray *results)
|
|||
nsresult rv = mClassifier->ActiveTables(tables);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsTArray<TableUpdate*> updates;
|
||||
|
||||
for (uint32_t i = 0; i < resultsPtr->Length(); i++) {
|
||||
bool activeTable = false;
|
||||
CacheResult* result = resultsPtr->ElementAt(i).get();
|
||||
|
||||
for (uint32_t table = 0; table < tables.Length(); table++) {
|
||||
if (tables[table].Equals(result->table)) {
|
||||
if (tables[table].Equals(resultsPtr->ElementAt(i).table)) {
|
||||
activeTable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (activeTable) {
|
||||
TableUpdate* tu = pParse->GetTableUpdate(result->table);
|
||||
TableUpdateV2* tuV2 = TableUpdate::Cast<TableUpdateV2>(
|
||||
pParse->GetTableUpdate(resultsPtr->ElementAt(i).table));
|
||||
|
||||
rv = CacheResultToTableUpdate(result, tu);
|
||||
// Ignore V4 for now.
|
||||
if (!tuV2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG(("CacheCompletion Addchunk %d hash %X", resultsPtr->ElementAt(i).entry.addChunk,
|
||||
resultsPtr->ElementAt(i).entry.ToUint32()));
|
||||
rv = tuV2->NewAddComplete(resultsPtr->ElementAt(i).entry.addChunk,
|
||||
resultsPtr->ElementAt(i).entry.complete);
|
||||
if (NS_FAILED(rv)) {
|
||||
// We can bail without leaking here because ForgetTableUpdates
|
||||
// hasn't been called yet.
|
||||
return rv;
|
||||
}
|
||||
updates.AppendElement(tu);
|
||||
rv = tuV2->NewAddChunk(resultsPtr->ElementAt(i).entry.addChunk);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
updates.AppendElement(tuV2);
|
||||
pParse->ForgetTableUpdates();
|
||||
} else {
|
||||
LOG(("Completion received, but table is not active, so not caching."));
|
||||
|
@ -899,53 +897,10 @@ nsUrlClassifierDBServiceWorker::CacheCompletions(CacheResultArray *results)
|
|||
}
|
||||
|
||||
mClassifier->ApplyFullHashes(&updates);
|
||||
mLastResults = Move(resultsPtr);
|
||||
mLastResults = *resultsPtr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUrlClassifierDBServiceWorker::CacheResultToTableUpdate(CacheResult* aCacheResult,
|
||||
TableUpdate* aUpdate)
|
||||
{
|
||||
auto tuV2 = TableUpdate::Cast<TableUpdateV2>(aUpdate);
|
||||
if (tuV2) {
|
||||
auto result = CacheResult::Cast<CacheResultV2>(aCacheResult);
|
||||
MOZ_ASSERT(result);
|
||||
|
||||
LOG(("CacheCompletion hash %X, Addchunk %d", result->completion.ToUint32(),
|
||||
result->addChunk));
|
||||
|
||||
nsresult rv = tuV2->NewAddComplete(result->addChunk, result->completion);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = tuV2->NewAddChunk(result->addChunk);
|
||||
return rv;
|
||||
}
|
||||
|
||||
auto tuV4 = TableUpdate::Cast<TableUpdateV4>(aUpdate);
|
||||
if (tuV4) {
|
||||
auto result = CacheResult::Cast<CacheResultV4>(aCacheResult);
|
||||
MOZ_ASSERT(result);
|
||||
|
||||
if (LOG_ENABLED()) {
|
||||
const FullHashExpiryCache& fullHashes = result->response.fullHashes;
|
||||
for (auto iter = fullHashes.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
Completion completion;
|
||||
completion.Assign(iter.Key());
|
||||
LOG(("CacheCompletion(v4) hash %X, CacheExpireTime %" PRId64, completion.ToUint32(),
|
||||
iter.Data()));
|
||||
}
|
||||
}
|
||||
|
||||
tuV4->NewFullHashResponse(result->prefix, result->response);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// tableUpdate object should be either v2 or v4.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUrlClassifierDBServiceWorker::CacheMisses(PrefixArray *results)
|
||||
{
|
||||
|
@ -1007,39 +962,10 @@ NS_IMETHODIMP
|
|||
nsUrlClassifierDBServiceWorker::ClearLastResults()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread(), "Must be on the background thread");
|
||||
if (mLastResults) {
|
||||
mLastResults->Clear();
|
||||
}
|
||||
mLastResults.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsUrlClassifierDBServiceWorker::IsSameAsLastResults(CacheResultArray& aResult)
|
||||
{
|
||||
if (!mLastResults || mLastResults->Length() != aResult.Length()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool equal = true;
|
||||
for (uint32_t i = 0; i < mLastResults->Length() && equal; i++) {
|
||||
CacheResult* lhs = mLastResults->ElementAt(i).get();
|
||||
CacheResult* rhs = aResult[i].get();
|
||||
|
||||
if (lhs->Ver() != rhs->Ver()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lhs->Ver() == CacheResult::V2) {
|
||||
equal = *(CacheResult::Cast<CacheResultV2>(lhs)) ==
|
||||
*(CacheResult::Cast<CacheResultV2>(rhs));
|
||||
} else if (lhs->Ver() == CacheResult::V4) {
|
||||
equal = *(CacheResult::Cast<CacheResultV4>(lhs)) ==
|
||||
*(CacheResult::Cast<CacheResultV4>(rhs));
|
||||
}
|
||||
}
|
||||
|
||||
return equal;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// nsUrlClassifierLookupCallback
|
||||
|
@ -1068,7 +994,6 @@ private:
|
|||
~nsUrlClassifierLookupCallback();
|
||||
|
||||
nsresult HandleResults();
|
||||
nsresult ProcessComplete(CacheResult* aCacheResult);
|
||||
|
||||
RefPtr<nsUrlClassifierDBService> mDBService;
|
||||
nsAutoPtr<LookupResultArray> mResults;
|
||||
|
@ -1184,95 +1109,30 @@ nsUrlClassifierLookupCallback::CompletionFinished(nsresult status)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierLookupCallback::CompletionV2(const nsACString& aCompleteHash,
|
||||
const nsACString& aTableName,
|
||||
uint32_t aChunkId)
|
||||
nsUrlClassifierLookupCallback::Completion(const nsACString& completeHash,
|
||||
const nsACString& tableName,
|
||||
uint32_t chunkId)
|
||||
{
|
||||
LOG(("nsUrlClassifierLookupCallback::Completion [%p, %s, %d]",
|
||||
this, PromiseFlatCString(aTableName).get(), aChunkId));
|
||||
this, PromiseFlatCString(tableName).get(), chunkId));
|
||||
|
||||
MOZ_ASSERT(!StringEndsWith(aTableName, NS_LITERAL_CSTRING("-proto")));
|
||||
mozilla::safebrowsing::Completion hash;
|
||||
hash.Assign(completeHash);
|
||||
|
||||
auto result = new CacheResultV2;
|
||||
|
||||
result->table = aTableName;
|
||||
result->completion.Assign(aCompleteHash);
|
||||
result->addChunk = aChunkId;
|
||||
|
||||
return ProcessComplete(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierLookupCallback::CompletionV4(const nsACString& aPartialHash,
|
||||
const nsACString& aTableName,
|
||||
uint32_t aNegativeCacheDuration,
|
||||
nsIArray* aFullHashes)
|
||||
{
|
||||
LOG(("nsUrlClassifierLookupCallback::CompletionV4 [%p, %s, %d]",
|
||||
this, PromiseFlatCString(aTableName).get(), aNegativeCacheDuration));
|
||||
|
||||
MOZ_ASSERT(StringEndsWith(aTableName, NS_LITERAL_CSTRING("-proto")));
|
||||
|
||||
if(!aFullHashes) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!Preferences::GetBool(TAKE_V4_COMPLETION_RESULT_PREF,
|
||||
TAKE_V4_COMPLETION_RESULT_DEFAULT)) {
|
||||
// Bug 1331534 - We temporarily ignore hash completion result
|
||||
// for v4 tables.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aNegativeCacheDuration > MAXIMUM_NEGATIVE_CACHE_DURATION_SEC) {
|
||||
LOG(("Negative cache duration too large, clamping it down to"
|
||||
"a reasonable value."));
|
||||
aNegativeCacheDuration = MAXIMUM_NEGATIVE_CACHE_DURATION_SEC;
|
||||
}
|
||||
|
||||
auto result = new CacheResultV4;
|
||||
|
||||
int64_t nowSec = PR_Now() / PR_USEC_PER_SEC;
|
||||
|
||||
result->table = aTableName;
|
||||
result->prefix = aPartialHash;
|
||||
result->response.negativeCacheExpirySec = nowSec + aNegativeCacheDuration;
|
||||
|
||||
// Fill in positive cache entries.
|
||||
uint32_t fullHashCount = 0;
|
||||
nsresult rv = aFullHashes->GetLength(&fullHashCount);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < fullHashCount; i++) {
|
||||
nsCOMPtr<nsIFullHashMatch> match = do_QueryElementAt(aFullHashes, i);
|
||||
|
||||
nsCString fullHash;
|
||||
match->GetFullHash(fullHash);
|
||||
|
||||
uint32_t duration;
|
||||
match->GetCacheDuration(&duration);
|
||||
|
||||
result->response.fullHashes.Put(fullHash, nowSec + duration);
|
||||
}
|
||||
|
||||
return ProcessComplete(result);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsUrlClassifierLookupCallback::ProcessComplete(CacheResult* aCacheResult)
|
||||
{
|
||||
// Send this completion to the store for caching.
|
||||
if (!mCacheResults) {
|
||||
mCacheResults = new CacheResultArray();
|
||||
if (!mCacheResults) {
|
||||
if (!mCacheResults)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
CacheResult result;
|
||||
result.entry.addChunk = chunkId;
|
||||
result.entry.complete = hash;
|
||||
result.table = tableName;
|
||||
|
||||
// OK if this fails, we just won't cache the item.
|
||||
mCacheResults->AppendElement(aCacheResult);
|
||||
mCacheResults->AppendElement(result);
|
||||
|
||||
// Check if this matched any of our results.
|
||||
for (uint32_t i = 0; i < mResults->Length(); i++) {
|
||||
|
@ -1280,8 +1140,8 @@ nsUrlClassifierLookupCallback::ProcessComplete(CacheResult* aCacheResult)
|
|||
|
||||
// Now, see if it verifies a lookup
|
||||
if (!result.mNoise
|
||||
&& result.mTableName.Equals(aCacheResult->table)
|
||||
&& aCacheResult->findCompletion(result.CompleteHash())) {
|
||||
&& result.CompleteHash() == hash
|
||||
&& result.mTableName.Equals(tableName)) {
|
||||
result.mProtocolConfirmed = true;
|
||||
}
|
||||
}
|
||||
|
@ -1364,6 +1224,14 @@ nsUrlClassifierLookupCallback::HandleResults()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (StringEndsWith(result.mTableName, NS_LITERAL_CSTRING("-proto")) &&
|
||||
!Preferences::GetBool(TAKE_V4_COMPLETION_RESULT_PREF,
|
||||
TAKE_V4_COMPLETION_RESULT_DEFAULT)) {
|
||||
// Bug 1331534 - We temporarily ignore hash completion result
|
||||
// for v4 tables.
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG(("Confirmed result %s from table %s",
|
||||
result.PartialHashHex().get(), result.mTableName.get()));
|
||||
|
||||
|
|
|
@ -218,11 +218,6 @@ private:
|
|||
uint32_t aCount,
|
||||
LookupResultArray& results);
|
||||
|
||||
nsresult CacheResultToTableUpdate(CacheResult* aCacheResult,
|
||||
TableUpdate* aUpdate);
|
||||
|
||||
bool IsSameAsLastResults(CacheResultArray& aResult);
|
||||
|
||||
// Can only be used on the background thread
|
||||
nsCOMPtr<nsICryptoHash> mCryptoHash;
|
||||
|
||||
|
@ -244,7 +239,7 @@ private:
|
|||
PrefixArray mMissCache;
|
||||
|
||||
// Stores the last results that triggered a table update.
|
||||
nsAutoPtr<CacheResultArray> mLastResults;
|
||||
CacheResultArray mLastResults;
|
||||
|
||||
nsresult mUpdateStatus;
|
||||
nsTArray<nsCString> mUpdateTables;
|
||||
|
|
|
@ -149,20 +149,6 @@ function httpStatusToBucket(httpStatus) {
|
|||
return statusBucket;
|
||||
}
|
||||
|
||||
function FullHashMatch(table, hash, duration) {
|
||||
this.tableName = table;
|
||||
this.fullHash = hash;
|
||||
this.cacheDuration = duration;
|
||||
}
|
||||
|
||||
FullHashMatch.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFullHashMatch]),
|
||||
|
||||
tableName : null,
|
||||
fullHash : null,
|
||||
cacheDuration : null,
|
||||
};
|
||||
|
||||
function HashCompleter() {
|
||||
// The current HashCompleterRequest in flight. Once it is started, it is set
|
||||
// to null. It may be used by multiple calls to |complete| in succession to
|
||||
|
@ -329,8 +315,7 @@ HashCompleterRequest.prototype = {
|
|||
this._requests.push({
|
||||
partialHash: aPartialHash,
|
||||
callback: aCallback,
|
||||
tableName: aTableName,
|
||||
response: { matches:[] },
|
||||
responses: []
|
||||
});
|
||||
|
||||
if (aTableName) {
|
||||
|
@ -531,7 +516,7 @@ HashCompleterRequest.prototype = {
|
|||
httpChannel.requestMethod = "POST";
|
||||
},
|
||||
|
||||
// Parses the response body and eventually adds items to the |response.matches| array
|
||||
// Parses the response body and eventually adds items to the |responses| array
|
||||
// for elements of |this._requests|.
|
||||
handleResponse: function HCR_handleResponse() {
|
||||
if (this._response == "") {
|
||||
|
@ -552,8 +537,6 @@ HashCompleterRequest.prototype = {
|
|||
|
||||
handleResponseV4: function HCR_handleResponseV4() {
|
||||
let callback = {
|
||||
// onCompleteHashFound will be called for each fullhash found in
|
||||
// FullHashResponse.
|
||||
onCompleteHashFound : (aCompleteHash,
|
||||
aTableNames,
|
||||
aPerHashCacheDuration) => {
|
||||
|
@ -573,16 +556,11 @@ HashCompleterRequest.prototype = {
|
|||
log("WARNING: Got complete hash which has ambigious threat type.");
|
||||
}
|
||||
|
||||
this.handleItem({
|
||||
completeHash: aCompleteHash,
|
||||
tableName: filteredTables[0],
|
||||
cacheDuration: aPerHashCacheDuration
|
||||
});
|
||||
this.handleItem(aCompleteHash, filteredTables[0], 0);
|
||||
|
||||
// TODO: Bug 1311935 - Implement v4 cache.
|
||||
},
|
||||
|
||||
// onResponseParsed will be called no matter if there is match in
|
||||
// FullHashResponse, the callback is mainly used to pass negative cache
|
||||
// duration and minimum wait duration.
|
||||
onResponseParsed : (aMinWaitDuration,
|
||||
aNegCacheDuration) => {
|
||||
log("V4 fullhash response parsed callback: " +
|
||||
|
@ -592,22 +570,15 @@ HashCompleterRequest.prototype = {
|
|||
let minWaitDuration = aMinWaitDuration;
|
||||
|
||||
if (aMinWaitDuration > MIN_WAIT_DURATION_MAX_VALUE) {
|
||||
log("WARNING: Minimum wait duration too large, clamping it down " +
|
||||
"to a reasonable value.");
|
||||
minWaitDuration = MIN_WAIT_DURATION_MAX_VALUE;
|
||||
} else if (aMinWaitDuration < 0) {
|
||||
log("WARNING: Minimum wait duration is negative, reset it to 0");
|
||||
minWaitDuration = 0;
|
||||
}
|
||||
|
||||
this._completer._nextGethashTimeMs[this.gethashUrl] =
|
||||
Date.now() + minWaitDuration;
|
||||
|
||||
// A fullhash request may contain more than one prefix, so the negative
|
||||
// cache duration should be set for all the prefixes in the request.
|
||||
this._requests.forEach(request => {
|
||||
request.response.negCacheDuration = aNegCacheDuration;
|
||||
});
|
||||
// TODO: Bug 1311935 - Implement v4 cache.
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -644,11 +615,8 @@ HashCompleterRequest.prototype = {
|
|||
|
||||
let data = body.substr(newlineIndex + 1, dataLength);
|
||||
for (let i = 0; i < (dataLength / COMPLETE_LENGTH); i++) {
|
||||
this.handleItem({
|
||||
completeHash: data.substr(i * COMPLETE_LENGTH, COMPLETE_LENGTH),
|
||||
tableName: list,
|
||||
chunkId: addChunk
|
||||
});
|
||||
this.handleItem(data.substr(i * COMPLETE_LENGTH, COMPLETE_LENGTH), list,
|
||||
addChunk);
|
||||
}
|
||||
|
||||
return aStart + newlineIndex + 1 + dataLength;
|
||||
|
@ -656,11 +624,15 @@ HashCompleterRequest.prototype = {
|
|||
|
||||
// This adds a complete hash to any entry in |this._requests| that matches
|
||||
// the hash.
|
||||
handleItem: function HCR_handleItem(aData) {
|
||||
handleItem: function HCR_handleItem(aData, aTableName, aChunkId) {
|
||||
for (let i = 0; i < this._requests.length; i++) {
|
||||
let request = this._requests[i];
|
||||
if (aData.completeHash.startsWith(request.partialHash)) {
|
||||
request.response.matches.push(aData);
|
||||
if (aData.startsWith(request.partialHash)) {
|
||||
request.responses.push({
|
||||
completeHash: aData,
|
||||
tableName: aTableName,
|
||||
chunkId: aChunkId,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -670,32 +642,16 @@ HashCompleterRequest.prototype = {
|
|||
// while notifyFailure only makes a |completionFinished| call with the error
|
||||
// code.
|
||||
notifySuccess: function HCR_notifySuccess() {
|
||||
// V2 completion handler
|
||||
let completionV2 = (req) => {
|
||||
req.response.matches.forEach((m) => {
|
||||
req.callback.completionV2(m.completeHash, m.tableName, m.chunkId);
|
||||
});
|
||||
for (let i = 0; i < this._requests.length; i++) {
|
||||
let request = this._requests[i];
|
||||
for (let j = 0; j < request.responses.length; j++) {
|
||||
let response = request.responses[j];
|
||||
request.callback.completion(response.completeHash, response.tableName,
|
||||
response.chunkId);
|
||||
}
|
||||
|
||||
req.callback.completionFinished(Cr.NS_OK);
|
||||
};
|
||||
|
||||
// V4 completion handler
|
||||
let completionV4 = (req) => {
|
||||
let matches = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
|
||||
|
||||
req.response.matches.forEach(m => {
|
||||
matches.appendElement(
|
||||
new FullHashMatch(m.tableName, m.completeHash, m.cacheDuration), false);
|
||||
});
|
||||
|
||||
req.callback.completionV4(req.partialHash, req.tableName,
|
||||
req.response.negCacheDuration, matches);
|
||||
|
||||
req.callback.completionFinished(Cr.NS_OK);
|
||||
};
|
||||
|
||||
let completion = this.isV4 ? completionV4 : completionV2;
|
||||
this._requests.forEach((req) => { completion(req); });
|
||||
request.callback.completionFinished(Cr.NS_OK);
|
||||
}
|
||||
},
|
||||
|
||||
notifyFailure: function HCR_notifyFailure(aStatus) {
|
||||
|
|
|
@ -459,7 +459,7 @@ nsUrlClassifierUtils::ParseFindFullHashResponseV4(const nsACString& aResponse,
|
|||
continue; // Ignore un-convertable threat type.
|
||||
}
|
||||
auto& hash = m.threat().hash();
|
||||
auto cacheDuration = m.cache_duration().seconds();
|
||||
auto cacheDuration = DurationToMs(m.cache_duration());
|
||||
aCallback->OnCompleteHashFound(nsCString(hash.c_str(), hash.length()),
|
||||
tableNames, cacheDuration);
|
||||
|
||||
|
@ -468,7 +468,7 @@ nsUrlClassifierUtils::ParseFindFullHashResponseV4(const nsACString& aResponse,
|
|||
}
|
||||
|
||||
auto minWaitDuration = DurationToMs(r.minimum_wait_duration());
|
||||
auto negCacheDuration = r.negative_cache_duration().seconds();
|
||||
auto negCacheDuration = DurationToMs(r.negative_cache_duration());
|
||||
|
||||
aCallback->OnResponseParsed(minWaitDuration, negCacheDuration);
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ public:
|
|||
OnResponseParsed(uint32_t aMinWaitDuration,
|
||||
uint32_t aNegCacheDuration) override
|
||||
{
|
||||
VerifyDuration(aMinWaitDuration / 1000, EXPECTED_MIN_WAIT_DURATION);
|
||||
VerifyDuration(aMinWaitDuration, EXPECTED_MIN_WAIT_DURATION);
|
||||
VerifyDuration(aNegCacheDuration, EXPECTED_NEG_CACHE_DURATION);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -191,7 +191,7 @@ private:
|
|||
void
|
||||
VerifyDuration(uint32_t aToVerify, const MyDuration& aExpected)
|
||||
{
|
||||
ASSERT_TRUE(aToVerify == aExpected.mSecs);
|
||||
ASSERT_TRUE(aToVerify == (aExpected.mSecs * 1000));
|
||||
}
|
||||
|
||||
~MyParseCallback() {}
|
||||
|
|
|
@ -355,7 +355,7 @@ function callback(completion) {
|
|||
}
|
||||
|
||||
callback.prototype = {
|
||||
completionV2: function completion(hash, table, chunkId, trusted) {
|
||||
completion: function completion(hash, table, chunkId, trusted) {
|
||||
do_check_true(this._completion.expectCompletion);
|
||||
if (this._completion.multipleCompletions) {
|
||||
for (let completion of this._completion.completions) {
|
||||
|
|
|
@ -90,18 +90,11 @@ add_test(function test_getHashRequestV4() {
|
|||
let completeFinishedCnt = 0;
|
||||
|
||||
gCompleter.complete("0123", TEST_TABLE_DATA_V4.gethashUrl, TEST_TABLE_DATA_V4.tableName, {
|
||||
completionV4(hash, table, duration, fullhashes) {
|
||||
equal(hash, "0123");
|
||||
completion(hash, table, chunkId) {
|
||||
equal(hash, "01234567890123456789012345678901");
|
||||
equal(table, TEST_TABLE_DATA_V4.tableName);
|
||||
equal(duration, 120);
|
||||
equal(fullhashes.length, 1);
|
||||
|
||||
let match = fullhashes.QueryInterface(Ci.nsIArray)
|
||||
.queryElementAt(0, Ci.nsIFullHashMatch);
|
||||
|
||||
equal(match.fullHash, "01234567890123456789012345678901");
|
||||
equal(match.cacheDuration, 8)
|
||||
do_print("completion: " + match.fullHash + ", " + table);
|
||||
equal(chunkId, 0);
|
||||
do_print("completion: " + hash + ", " + table + ", " + chunkId);
|
||||
},
|
||||
|
||||
completionFinished(status) {
|
||||
|
@ -114,18 +107,11 @@ add_test(function test_getHashRequestV4() {
|
|||
});
|
||||
|
||||
gCompleter.complete("1234567", TEST_TABLE_DATA_V4.gethashUrl, TEST_TABLE_DATA_V4.tableName, {
|
||||
completionV4(hash, table, duration, fullhashes) {
|
||||
equal(hash, "1234567");
|
||||
completion(hash, table, chunkId) {
|
||||
equal(hash, "12345678901234567890123456789012");
|
||||
equal(table, TEST_TABLE_DATA_V4.tableName);
|
||||
equal(duration, 120);
|
||||
equal(fullhashes.length, 1);
|
||||
|
||||
let match = fullhashes.QueryInterface(Ci.nsIArray)
|
||||
.queryElementAt(0, Ci.nsIFullHashMatch);
|
||||
|
||||
equal(match.fullHash, "12345678901234567890123456789012");
|
||||
equal(match.cacheDuration, 7)
|
||||
do_print("completion: " + match.fullHash + ", " + table);
|
||||
equal(chunkId, 0);
|
||||
do_print("completion: " + hash + ", " + table + ", " + chunkId);
|
||||
},
|
||||
|
||||
completionFinished(status) {
|
||||
|
@ -138,11 +124,8 @@ add_test(function test_getHashRequestV4() {
|
|||
});
|
||||
|
||||
gCompleter.complete("1111", TEST_TABLE_DATA_V4.gethashUrl, TEST_TABLE_DATA_V4.tableName, {
|
||||
completionV4(hash, table, duration, fullhashes) {
|
||||
equal(hash, "1111");
|
||||
equal(table, TEST_TABLE_DATA_V4.tableName);
|
||||
equal(duration, 120);
|
||||
equal(fullhashes.length, 0);
|
||||
completion(hash, table, chunkId) {
|
||||
ok(false, "1111 is not the prefix of " + hash);
|
||||
},
|
||||
|
||||
completionFinished(status) {
|
||||
|
@ -166,17 +149,11 @@ add_test(function test_minWaitDuration() {
|
|||
|
||||
let successComplete = function() {
|
||||
gCompleter.complete("1234567", TEST_TABLE_DATA_V4.gethashUrl, TEST_TABLE_DATA_V4.tableName, {
|
||||
completionV4(hash, table, duration, fullhashes) {
|
||||
equal(hash, "1234567");
|
||||
completion(hash, table, chunkId) {
|
||||
equal(hash, "12345678901234567890123456789012");
|
||||
equal(table, TEST_TABLE_DATA_V4.tableName);
|
||||
equal(fullhashes.length, 1);
|
||||
|
||||
let match = fullhashes.QueryInterface(Ci.nsIArray)
|
||||
.queryElementAt(0, Ci.nsIFullHashMatch);
|
||||
|
||||
equal(match.fullHash, "12345678901234567890123456789012");
|
||||
equal(match.cacheDuration, 7)
|
||||
do_print("completion: " + match.fullHash + ", " + table);
|
||||
equal(chunkId, 0);
|
||||
do_print("completion: " + hash + ", " + table + ", " + chunkId);
|
||||
},
|
||||
|
||||
completionFinished(status) {
|
||||
|
|
|
@ -35,7 +35,7 @@ complete: function(partialHash, gethashUrl, tableName, cb)
|
|||
for (var i = 0; i < fragments[partialHash].length; i++) {
|
||||
var chunkId = fragments[partialHash][i][0];
|
||||
var hash = fragments[partialHash][i][1];
|
||||
cb.completionV2(hash, self.tableName, chunkId);
|
||||
cb.completion(hash, self.tableName, chunkId);
|
||||
}
|
||||
}
|
||||
cb.completionFinished(0);
|
||||
|
|
Загрузка…
Ссылка в новой задаче