#include <errno.h>
-#include "base/file_util.h"
+#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
}
bool DataPack::LoadFromFile(base::File file) {
+ return LoadFromFileRegion(file.Pass(),
+ base::MemoryMappedFile::Region::kWholeFile);
+}
+
+bool DataPack::LoadFromFileRegion(
+ base::File file,
+ const base::MemoryMappedFile::Region& region) {
mmap_.reset(new base::MemoryMappedFile);
- if (!mmap_->Initialize(file.Pass())) {
+ if (!mmap_->Initialize(file.Pass(), region)) {
DLOG(ERROR) << "Failed to mmap datapack";
UMA_HISTOGRAM_ENUMERATION("DataPack.Load", INIT_FAILED_FROM_FILE,
LOAD_ERRORS_COUNT);
}
// Sanity check the file.
- // 1) Check we have enough entries.
- if (kHeaderLength + resource_count_ * sizeof(DataPackEntry) >
+ // 1) Check we have enough entries. There's an extra entry after the last item
+ // which gives the length of the last item.
+ if (kHeaderLength + (resource_count_ + 1) * sizeof(DataPackEntry) >
mmap_->length()) {
LOG(ERROR) << "Data pack file corruption: too short for number of "
"entries specified.";
}
const DataPackEntry* next_entry = target + 1;
- size_t length = next_entry->file_offset - target->file_offset;
+ // If the next entry points beyond the end of the file this data pack's entry
+ // table is corrupt. Log an error and return false. See
+ // http://crbug.com/371301.
+ if (next_entry->file_offset > mmap_->length()) {
+ size_t entry_index = target -
+ reinterpret_cast<const DataPackEntry*>(mmap_->data() + kHeaderLength);
+ LOG(ERROR) << "Entry #" << entry_index << " in data pack points off end "
+ << "of file. This should have been caught when loading. Was the "
+ << "file modified?";
+ return false;
+ }
- data->set(mmap_->data() + target->file_offset, length);
+ size_t length = next_entry->file_offset - target->file_offset;
+ data->set(reinterpret_cast<const char*>(mmap_->data() + target->file_offset),
+ length);
return true;
}
if (!GetStringPiece(resource_id, &piece))
return NULL;
- return new base::RefCountedStaticMemory(
- reinterpret_cast<const unsigned char*>(piece.data()), piece.length());
+ return new base::RefCountedStaticMemory(piece.data(), piece.length());
}
ResourceHandle::TextEncodingType DataPack::GetTextEncodingType() const {
return false;
}
- uint8 write_buffer = textEncodingType;
+ uint8 write_buffer = static_cast<uint8>(textEncodingType);
if (fwrite(&write_buffer, sizeof(uint8), 1, file) != 1) {
LOG(ERROR) << "Failed to write file text resources encoding";
base::CloseFile(file);