From f0a980966264fa98ef8e1b834650d9bf54de92ae Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Wed, 20 Jul 2011 18:42:32 +0900 Subject: [PATCH] Check the binary dictionary magic number ...and return NULL if it does not matched an expected value. Bug: 5052486 Change-Id: I1dc7955d2785ee080bc5c22398be9befe332f096 --- ...oid_inputmethod_latin_BinaryDictionary.cpp | 33 +++++++++++++++---- native/src/binary_format.h | 13 ++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index ce874d8d4..18c972444 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -17,6 +17,7 @@ #define LOG_TAG "LatinIME: jni: BinaryDictionary" +#include "binary_format.h" #include "com_android_inputmethod_latin_BinaryDictionary.h" #include "dictionary.h" #include "jni.h" @@ -38,6 +39,8 @@ namespace latinime { +void releaseDictBuf(void* dictBuf, const size_t length, int fd); + static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object, jstring sourceDir, jlong dictOffset, jlong dictSize, jint typedLetterMultiplier, jint fullWordMultiplier, jint maxWordLength, jint maxWords, @@ -104,8 +107,18 @@ static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object, LOGE("DICT: dictBuf is null"); return 0; } - Dictionary *dictionary = new Dictionary(dictBuf, dictSize, fd, adjust, typedLetterMultiplier, - fullWordMultiplier, maxWordLength, maxWords, maxAlternatives); + Dictionary *dictionary = NULL; + if (BinaryFormat::UNKNOWN_FORMAT == BinaryFormat::detectFormat((uint8_t*)dictBuf)) { + LOGE("DICT: dictionary format is unknown, bad magic number"); +#ifdef USE_MMAP_FOR_DICTIONARY + releaseDictBuf(((char*)dictBuf) - adjust, adjDictSize, fd); +#else // USE_MMAP_FOR_DICTIONARY + releaseDictBuf(dictBuf, 0, 0); +#endif // USE_MMAP_FOR_DICTIONARY + } else { + dictionary = new Dictionary(dictBuf, dictSize, fd, adjust, typedLetterMultiplier, + fullWordMultiplier, maxWordLength, maxWords, maxAlternatives); + } PROF_END(66); PROF_CLOSE; return (jint)dictionary; @@ -180,19 +193,27 @@ static void latinime_BinaryDictionary_close(JNIEnv *env, jobject object, jint di void *dictBuf = dictionary->getDict(); if (!dictBuf) return; #ifdef USE_MMAP_FOR_DICTIONARY - int ret = munmap((void *)((char *)dictBuf - dictionary->getDictBufAdjust()), - dictionary->getDictSize() + dictionary->getDictBufAdjust()); + releaseDictBuf((void *)((char *)dictBuf - dictionary->getDictBufAdjust()), + dictionary->getDictSize() + dictionary->getDictBufAdjust(), dictionary->getMmapFd()); +#else // USE_MMAP_FOR_DICTIONARY + releaseDictBuf(dictBuf, 0, 0); +#endif // USE_MMAP_FOR_DICTIONARY + delete dictionary; +} + +void releaseDictBuf(void* dictBuf, const size_t length, int fd) { +#ifdef USE_MMAP_FOR_DICTIONARY + int ret = munmap(dictBuf, length); if (ret != 0) { LOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno); } - ret = close(dictionary->getMmapFd()); + ret = close(fd); if (ret != 0) { LOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno); } #else // USE_MMAP_FOR_DICTIONARY free(dictBuf); #endif // USE_MMAP_FOR_DICTIONARY - delete dictionary; } static JNINativeMethod sMethods[] = { diff --git a/native/src/binary_format.h b/native/src/binary_format.h index e9f108e25..7deec27d3 100644 --- a/native/src/binary_format.h +++ b/native/src/binary_format.h @@ -17,6 +17,8 @@ #ifndef LATINIME_BINARY_FORMAT_H #define LATINIME_BINARY_FORMAT_H +#include "unigram_dictionary.h" + namespace latinime { class BinaryFormat { @@ -26,6 +28,11 @@ private: const static int MULTIPLE_BYTE_CHARACTER_ADDITIONAL_SIZE = 2; public: + const static int UNKNOWN_FORMAT = -1; + const static int FORMAT_VERSION_1 = 1; + const static uint16_t FORMAT_VERSION_1_MAGIC_NUMBER = 0x78B1; + + static int detectFormat(const uint8_t* const dict); static int getGroupCountAndForwardPointer(const uint8_t* const dict, int* pos); static uint8_t getFlagsAndForwardPointer(const uint8_t* const dict, int* pos); static int32_t getCharCodeAndForwardPointer(const uint8_t* const dict, int* pos); @@ -43,6 +50,12 @@ public: int *pos); }; +inline int BinaryFormat::detectFormat(const uint8_t* const dict) { + const uint16_t magicNumber = (dict[0] << 8) + dict[1]; // big endian + if (FORMAT_VERSION_1_MAGIC_NUMBER == magicNumber) return FORMAT_VERSION_1; + return UNKNOWN_FORMAT; +} + inline int BinaryFormat::getGroupCountAndForwardPointer(const uint8_t* const dict, int* pos) { return dict[(*pos)++]; }