Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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
Loading
Loading
Loading
Loading
+27 −6
Original line number Original line Diff line number Diff line
@@ -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 @@


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,
        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;
    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);
                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
    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[] = {
+13 −0
Original line number Original line Diff line number Diff line
@@ -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:
    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:
            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)++];
}
}