Bug 1244259 - Limit PrefixSet read and write buffer sizes to file size. r=froydnj

This commit is contained in:
Gian-Carlo Pascutto 2016-02-12 08:54:12 +01:00
parent 435a715411
commit 3161f46444
2 changed files with 27 additions and 7 deletions

View File

@ -24,6 +24,7 @@
#include "mozilla/FileUtils.h"
#include "mozilla/Logging.h"
#include "mozilla/unused.h"
#include <algorithm>
using namespace mozilla;
@ -35,6 +36,9 @@ static const PRLogModuleInfo *gUrlClassifierPrefixSetLog = nullptr;
NS_IMPL_ISUPPORTS(
nsUrlClassifierPrefixSet, nsIUrlClassifierPrefixSet, nsIMemoryReporter)
// Definition required due to std::max<>()
const uint32_t nsUrlClassifierPrefixSet::MAX_BUFFER_SIZE;
nsUrlClassifierPrefixSet::nsUrlClassifierPrefixSet()
: mLock("nsUrlClassifierPrefixSet.mLock")
, mTotalPrefixes(0)
@ -315,8 +319,21 @@ nsUrlClassifierPrefixSet::LoadFromFile(nsIFile* aFile)
PR_RDONLY | nsIFile::OS_READAHEAD);
NS_ENSURE_SUCCESS(rv, rv);
// Calculate how big the file is, make sure our read buffer isn't bigger
// than the file itself which is just wasting memory.
int64_t fileSize;
rv = aFile->GetFileSize(&fileSize);
NS_ENSURE_SUCCESS(rv, rv);
if (fileSize < 0 || fileSize > UINT32_MAX) {
return NS_ERROR_FAILURE;
}
uint32_t bufferSize = std::min<uint32_t>(static_cast<uint32_t>(fileSize),
MAX_BUFFER_SIZE);
// Convert to buffered stream
nsCOMPtr<nsIInputStream> in = NS_BufferInputStream(localInFile, BUFFER_SIZE);
nsCOMPtr<nsIInputStream> in = NS_BufferInputStream(localInFile, bufferSize);
uint32_t magic;
uint32_t read;
@ -401,22 +418,25 @@ nsUrlClassifierPrefixSet::StoreToFile(nsIFile* aFile)
PR_WRONLY | PR_TRUNCATE | PR_CREATE_FILE);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t fileSize;
// Preallocate the file storage
{
nsCOMPtr<nsIFileOutputStream> fos(do_QueryInterface(localOutFile));
Telemetry::AutoTimer<Telemetry::URLCLASSIFIER_PS_FALLOCATE_TIME> timer;
int64_t size = 4 * sizeof(uint32_t);
fileSize = 4 * sizeof(uint32_t);
uint32_t deltas = mTotalPrefixes - mIndexPrefixes.Length();
size += 2 * mIndexPrefixes.Length() * sizeof(uint32_t);
size += deltas * sizeof(uint16_t);
fileSize += 2 * mIndexPrefixes.Length() * sizeof(uint32_t);
fileSize += deltas * sizeof(uint16_t);
// Ignore failure, the preallocation is a hint and we write out the entire
// file later on
Unused << fos->Preallocate(size);
Unused << fos->Preallocate(fileSize);
}
// Convert to buffered stream
nsCOMPtr<nsIOutputStream> out = NS_BufferOutputStream(localOutFile, BUFFER_SIZE);
nsCOMPtr<nsIOutputStream> out =
NS_BufferOutputStream(localOutFile, std::min(fileSize, MAX_BUFFER_SIZE));
uint32_t written;
uint32_t writelen = sizeof(uint32_t);

View File

@ -44,7 +44,7 @@ public:
private:
virtual ~nsUrlClassifierPrefixSet();
static const uint32_t BUFFER_SIZE = 64 * 1024;
static const uint32_t MAX_BUFFER_SIZE = 64 * 1024;
static const uint32_t DELTAS_LIMIT = 120;
static const uint32_t MAX_INDEX_DIFF = (1 << 16);
static const uint32_t PREFIXSET_VERSION_MAGIC = 1;