Skip to content
Snippets Groups Projects
Commit f0a98096 authored by Jean Chalard's avatar Jean Chalard
Browse files

Check the binary dictionary magic number

...and return NULL if it does not matched an expected value.

Bug: 5052486
Change-Id: I1dc7955d2785ee080bc5c22398be9befe332f096
parent 597b1157
No related branches found
No related tags found
No related merge requests found
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#define LOG_TAG "LatinIME: jni: BinaryDictionary" #define LOG_TAG "LatinIME: jni: BinaryDictionary"
#include "binary_format.h"
#include "com_android_inputmethod_latin_BinaryDictionary.h" #include "com_android_inputmethod_latin_BinaryDictionary.h"
#include "dictionary.h" #include "dictionary.h"
#include "jni.h" #include "jni.h"
...@@ -38,6 +39,8 @@ ...@@ -38,6 +39,8 @@
namespace latinime { namespace latinime {
void releaseDictBuf(void* dictBuf, const size_t length, int fd);
static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object, static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
jstring sourceDir, jlong dictOffset, jlong dictSize, jstring sourceDir, jlong dictOffset, jlong dictSize,
jint typedLetterMultiplier, jint fullWordMultiplier, jint maxWordLength, jint maxWords, jint typedLetterMultiplier, jint fullWordMultiplier, jint maxWordLength, jint maxWords,
...@@ -104,8 +107,18 @@ static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object, ...@@ -104,8 +107,18 @@ static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
LOGE("DICT: dictBuf is null"); LOGE("DICT: dictBuf is null");
return 0; return 0;
} }
Dictionary *dictionary = new Dictionary(dictBuf, dictSize, fd, adjust, typedLetterMultiplier, Dictionary *dictionary = NULL;
fullWordMultiplier, maxWordLength, maxWords, maxAlternatives); 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_END(66);
PROF_CLOSE; PROF_CLOSE;
return (jint)dictionary; return (jint)dictionary;
...@@ -180,19 +193,27 @@ static void latinime_BinaryDictionary_close(JNIEnv *env, jobject object, jint di ...@@ -180,19 +193,27 @@ static void latinime_BinaryDictionary_close(JNIEnv *env, jobject object, jint di
void *dictBuf = dictionary->getDict(); void *dictBuf = dictionary->getDict();
if (!dictBuf) return; if (!dictBuf) return;
#ifdef USE_MMAP_FOR_DICTIONARY #ifdef USE_MMAP_FOR_DICTIONARY
int ret = munmap((void *)((char *)dictBuf - dictionary->getDictBufAdjust()), releaseDictBuf((void *)((char *)dictBuf - dictionary->getDictBufAdjust()),
dictionary->getDictSize() + 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) { if (ret != 0) {
LOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno); LOGE("DICT: Failure in munmap. ret=%d errno=%d", ret, errno);
} }
ret = close(dictionary->getMmapFd()); ret = close(fd);
if (ret != 0) { if (ret != 0) {
LOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno); LOGE("DICT: Failure in close. ret=%d errno=%d", ret, errno);
} }
#else // USE_MMAP_FOR_DICTIONARY #else // USE_MMAP_FOR_DICTIONARY
free(dictBuf); free(dictBuf);
#endif // USE_MMAP_FOR_DICTIONARY #endif // USE_MMAP_FOR_DICTIONARY
delete dictionary;
} }
static JNINativeMethod sMethods[] = { static JNINativeMethod sMethods[] = {
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#ifndef LATINIME_BINARY_FORMAT_H #ifndef LATINIME_BINARY_FORMAT_H
#define LATINIME_BINARY_FORMAT_H #define LATINIME_BINARY_FORMAT_H
#include "unigram_dictionary.h"
namespace latinime { namespace latinime {
class BinaryFormat { class BinaryFormat {
...@@ -26,6 +28,11 @@ private: ...@@ -26,6 +28,11 @@ private:
const static int MULTIPLE_BYTE_CHARACTER_ADDITIONAL_SIZE = 2; const static int MULTIPLE_BYTE_CHARACTER_ADDITIONAL_SIZE = 2;
public: 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 int getGroupCountAndForwardPointer(const uint8_t* const dict, int* pos);
static uint8_t getFlagsAndForwardPointer(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); static int32_t getCharCodeAndForwardPointer(const uint8_t* const dict, int* pos);
...@@ -43,6 +50,12 @@ public: ...@@ -43,6 +50,12 @@ public:
int *pos); 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) { inline int BinaryFormat::getGroupCountAndForwardPointer(const uint8_t* const dict, int* pos) {
return dict[(*pos)++]; return dict[(*pos)++];
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment