Bug 988186 - HTTP cache v2: store all fields in CacheFileMetadata in network order on disk, r=honzab

This commit is contained in:
Michal Novotny 2014-04-07 22:07:38 +02:00
parent 8371acf5d5
commit 3b8a819410
2 changed files with 61 additions and 16 deletions

View File

@ -232,7 +232,7 @@ CacheFileMetadata::WriteMetadata(uint32_t aOffset,
char *p = mWriteBuf + sizeof(uint32_t);
memcpy(p, mHashArray, mHashCount * sizeof(CacheHash::Hash16_t));
p += mHashCount * sizeof(CacheHash::Hash16_t);
memcpy(p, &mMetaHdr, sizeof(CacheFileMetadataHeader));
mMetaHdr.WriteToBuf(p);
p += sizeof(CacheFileMetadataHeader);
memcpy(p, mKey.get(), mKey.Length());
p += mKey.Length();
@ -244,9 +244,9 @@ CacheFileMetadata::WriteMetadata(uint32_t aOffset,
CacheHash::Hash32_t hash;
hash = CacheHash::Hash(mWriteBuf + sizeof(uint32_t),
p - mWriteBuf - sizeof(uint32_t));
*reinterpret_cast<uint32_t *>(mWriteBuf) = PR_htonl(hash);
NetworkEndian::writeUint32(mWriteBuf, hash);
*reinterpret_cast<uint32_t *>(p) = PR_htonl(aOffset);
NetworkEndian::writeUint32(p, aOffset);
p += sizeof(uint32_t);
char * writeBuffer;
@ -319,7 +319,7 @@ CacheFileMetadata::SyncReadMetadata(nsIFile *aFile)
return NS_ERROR_FAILURE;
}
metaOffset = PR_ntohl(metaOffset);
metaOffset = NetworkEndian::readUint32(&metaOffset);
if (metaOffset > fileSize) {
PR_Close(fd);
return NS_ERROR_FAILURE;
@ -433,7 +433,7 @@ CacheHash::Hash16_t
CacheFileMetadata::GetHash(uint32_t aIndex)
{
MOZ_ASSERT(aIndex < mHashCount);
return PR_ntohs(mHashArray[aIndex]);
return NetworkEndian::readUint16(&mHashArray[aIndex]);
}
nsresult
@ -462,7 +462,7 @@ CacheFileMetadata::SetHash(uint32_t aIndex, CacheHash::Hash16_t aHash)
mHashCount++;
}
mHashArray[aIndex] = PR_htons(aHash);
NetworkEndian::writeUint16(&mHashArray[aIndex], aHash);
DoMemoryReport(MemoryUsage());
@ -592,8 +592,8 @@ CacheFileMetadata::OnDataRead(CacheFileHandle *aHandle, char *aBuf,
}
// check whether we have read all necessary data
uint32_t realOffset = PR_ntohl(*(reinterpret_cast<uint32_t *>(
mBuf + mBufSize - sizeof(uint32_t))));
uint32_t realOffset = NetworkEndian::readUint32(mBuf + mBufSize -
sizeof(uint32_t));
int64_t size = mHandle->FileSize();
MOZ_ASSERT(size != -1);
@ -769,13 +769,15 @@ CacheFileMetadata::ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset,
}
// check metadata hash (data from hashesOffset to metaposOffset)
CacheHash::Hash32_t hash;
hash = CacheHash::Hash(mBuf + hashesOffset, metaposOffset - hashesOffset);
CacheHash::Hash32_t hashComputed, hashExpected;
hashComputed = CacheHash::Hash(mBuf + hashesOffset,
metaposOffset - hashesOffset);
hashExpected = NetworkEndian::readUint32(mBuf + aBufOffset);
if (hash != PR_ntohl(*(reinterpret_cast<uint32_t *>(mBuf + aBufOffset)))) {
if (hashComputed != hashExpected) {
LOG(("CacheFileMetadata::ParseMetadata() - Metadata hash mismatch! Hash of "
"the metadata is %x, hash in file is %x [this=%p]", hash,
PR_ntohl(*(reinterpret_cast<uint32_t *>(mBuf + aBufOffset))), this));
"the metadata is %x, hash in file is %x [this=%p]", hashComputed,
hashExpected, this));
return NS_ERROR_FILE_CORRUPTED;
}
@ -792,7 +794,7 @@ CacheFileMetadata::ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset,
memcpy(mHashArray, mBuf + hashesOffset, mHashArraySize);
}
memcpy(&mMetaHdr, mBuf + hdrOffset, sizeof(CacheFileMetadataHeader));
mMetaHdr.ReadFromBuf(mBuf + hdrOffset);
mMetaHdr.mFetchCount++;
MarkDirty();

View File

@ -9,6 +9,7 @@
#include "CacheStorageService.h"
#include "CacheHashUtils.h"
#include "CacheObserver.h"
#include "mozilla/Endian.h"
#include "nsAutoPtr.h"
#include "nsString.h"
@ -25,14 +26,56 @@ namespace net {
#define INT2FRECENCY(aInt) \
((double)(aInt) / (double)CacheObserver::HalfLifeSeconds())
typedef struct {
#pragma pack(push)
#pragma pack(1)
class CacheFileMetadataHeader {
public:
uint32_t mFetchCount;
uint32_t mLastFetched;
uint32_t mLastModified;
uint32_t mFrecency;
uint32_t mExpirationTime;
uint32_t mKeySize;
} CacheFileMetadataHeader;
void WriteToBuf(void *aBuf)
{
EnsureCorrectClassSize();
uint8_t* ptr = static_cast<uint8_t*>(aBuf);
NetworkEndian::writeUint32(ptr, mFetchCount); ptr += sizeof(uint32_t);
NetworkEndian::writeUint32(ptr, mLastFetched); ptr += sizeof(uint32_t);
NetworkEndian::writeUint32(ptr, mLastModified); ptr += sizeof(uint32_t);
NetworkEndian::writeUint32(ptr, mFrecency); ptr += sizeof(uint32_t);
NetworkEndian::writeUint32(ptr, mExpirationTime); ptr += sizeof(uint32_t);
NetworkEndian::writeUint32(ptr, mKeySize);
}
void ReadFromBuf(const void *aBuf)
{
EnsureCorrectClassSize();
const uint8_t* ptr = static_cast<const uint8_t*>(aBuf);
mFetchCount = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
mLastFetched = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
mLastModified = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
mFrecency = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
mExpirationTime = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t);
mKeySize = BigEndian::readUint32(ptr);
}
inline void EnsureCorrectClassSize()
{
static_assert((sizeof(mFetchCount) + sizeof(mLastFetched) +
sizeof(mLastModified) + sizeof(mFrecency) + sizeof(mExpirationTime) +
sizeof(mKeySize)) == sizeof(CacheFileMetadataHeader),
"Unexpected sizeof(CacheFileMetadataHeader)!");
}
};
#pragma pack(pop)
#define CACHEFILEMETADATALISTENER_IID \
{ /* a9e36125-3f01-4020-9540-9dafa8d31ba7 */ \