From e1b8c7949738100e4747dd4109ef1f16e1bd99c4 Mon Sep 17 00:00:00 2001 From: Peng Wu Date: Mon, 1 Mar 2021 11:09:36 +0800 Subject: [PATCH] Check offset bounds in BinaryDict::NewFromFile method --- src/BinaryDict.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/BinaryDict.cpp b/src/BinaryDict.cpp index 2e66fd2b5..c57756615 100644 --- a/src/BinaryDict.cpp +++ b/src/BinaryDict.cpp @@ -67,6 +67,12 @@ void BinaryDict::SerializeToFile(FILE* fp) const { } BinaryDictPtr BinaryDict::NewFromFile(FILE* fp) { + size_t offsetBound, savedOffset; + savedOffset = ftell(fp); + fseek(fp, 0L, SEEK_END); + offsetBound = ftell(fp) - savedOffset; + fseek(fp, savedOffset, SEEK_SET); + BinaryDictPtr dict(new BinaryDict(LexiconPtr(new Lexicon))); // Number of items @@ -113,7 +119,7 @@ BinaryDictPtr BinaryDict::NewFromFile(FILE* fp) { // Key offset size_t keyOffset; unitsRead = fread(&keyOffset, sizeof(size_t), 1, fp); - if (unitsRead != 1) { + if (unitsRead != 1 || keyOffset >= offsetBound) { throw InvalidFormat("Invalid OpenCC binary dictionary (keyOffset)"); } std::string key = dict->keyBuffer.c_str() + keyOffset; @@ -122,7 +128,7 @@ BinaryDictPtr BinaryDict::NewFromFile(FILE* fp) { for (size_t j = 0; j < numValues; j++) { size_t valueOffset; unitsRead = fread(&valueOffset, sizeof(size_t), 1, fp); - if (unitsRead != 1) { + if (unitsRead != 1 || valueOffset >= offsetBound) { throw InvalidFormat("Invalid OpenCC binary dictionary (valueOffset)"); } const char* value = dict->valueBuffer.c_str() + valueOffset;