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

Commit d934fb43 authored by Keisuke Kuroyanagi's avatar Keisuke Kuroyanagi
Browse files

Remove corrupted ver4 dictionaries.

Bug: 12916055
Change-Id: I2c390ab1dc483915691b47a605772cbc2dfeaf09
parent be81b75d
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin;

import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;

import com.android.inputmethod.annotations.UsedForTesting;
@@ -29,6 +30,7 @@ import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
import com.android.inputmethod.latin.makedict.WordProperty;
import com.android.inputmethod.latin.settings.NativeSuggestOptions;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.FileUtils;
import com.android.inputmethod.latin.utils.JniUtils;
import com.android.inputmethod.latin.utils.LanguageModelParam;
import com.android.inputmethod.latin.utils.StringUtils;
@@ -84,6 +86,7 @@ public final class BinaryDictionary extends Dictionary {
    private final Locale mLocale;
    private final long mDictSize;
    private final String mDictFilePath;
    private final boolean mIsUpdatable;
    private final int[] mInputCodePoints = new int[MAX_WORD_LENGTH];
    private final int[] mOutputCodePoints = new int[MAX_WORD_LENGTH * MAX_RESULTS];
    private final int[] mSpaceIndices = new int[MAX_RESULTS];
@@ -130,6 +133,7 @@ public final class BinaryDictionary extends Dictionary {
        mLocale = locale;
        mDictSize = length;
        mDictFilePath = filename;
        mIsUpdatable = isUpdatable;
        mNativeSuggestOptions.setUseFullEditDistance(useFullEditDistance);
        loadDictionary(filename, offset, length, isUpdatable);
    }
@@ -177,6 +181,7 @@ public final class BinaryDictionary extends Dictionary {
            int bigramProbability);
    private static native int setCurrentTimeForTestNative(int currentTime);
    private static native String getPropertyNative(long dict, String query);
    private static native boolean isCorruptedNative(long dict);

    public static boolean createEmptyDictFile(final String filePath, final long dictVersion,
            final Locale locale, final Map<String, String> attributeMap) {
@@ -198,6 +203,22 @@ public final class BinaryDictionary extends Dictionary {
        mNativeDict = openNative(path, startOffset, length, isUpdatable);
    }

    // TODO: Check isCorrupted() for main dictionaries.
    public boolean isCorrupted() {
        if (!isValidDictionary()) {
            return false;
        }
        if (!isCorruptedNative(mNativeDict)) {
            return false;
        }
        // TODO: Record the corruption.
        Log.e(TAG, "BinaryDictionary (" + mDictFilePath + ") is corrupted.");
        Log.e(TAG, "locale: " + mLocale);
        Log.e(TAG, "dict size: " + mDictSize);
        Log.e(TAG, "updatable: " + mIsUpdatable);
        return true;
    }

    @UsedForTesting
    public DictionaryHeader getHeader() throws UnsupportedFormatException {
        if (mNativeDict == 0) {
@@ -444,7 +465,7 @@ public final class BinaryDictionary extends Dictionary {
        // only be called for actual files. Right now it's only called by the flush() family of
        // functions, which require an updatable dictionary, so it's okay. But beware.
        loadDictionary(dictFile.getAbsolutePath(), 0 /* startOffset */,
                dictFile.length(), true /* isUpdatable */);
                dictFile.length(), mIsUpdatable);
    }

    public void flush() {
+16 −9
Original line number Diff line number Diff line
@@ -276,22 +276,26 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
        return attributeMap;
    }

    private void removeBinaryDictionaryLocked() {
        if (mBinaryDictionary != null) {
            mBinaryDictionary.close();
        }
        if (mDictFile.exists() && !FileUtils.deleteRecursively(mDictFile)) {
            Log.e(TAG, "Can't remove a file: " + mDictFile.getName());
        }
        mBinaryDictionary = null;
    }

    protected void clear() {
        final File dictFile = mDictFile;
        getExecutor(mDictName).execute(new Runnable() {
            @Override
            public void run() {
                if (mDictionaryWriter == null) {
                    if (mBinaryDictionary != null) {
                        mBinaryDictionary.close();
                    }
                    if (dictFile.exists() && !FileUtils.deleteRecursively(dictFile)) {
                        Log.e(TAG, "Can't remove a file: " + dictFile.getName());
                    }
                    BinaryDictionary.createEmptyDictFile(dictFile.getAbsolutePath(),
                    removeBinaryDictionaryLocked();
                    BinaryDictionary.createEmptyDictFile(mDictFile.getAbsolutePath(),
                            DICTIONARY_FORMAT_VERSION, mLocale, getHeaderAttributeMap());
                    mBinaryDictionary = new BinaryDictionary(
                            dictFile.getAbsolutePath(), 0 /* offset */, dictFile.length(),
                            mDictFile.getAbsolutePath(), 0 /* offset */, mDictFile.length(),
                            true /* useFullEditDistance */, mLocale, mDictType, mIsUpdatable);
                } else {
                    mDictionaryWriter.clear();
@@ -469,6 +473,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
                                proximityInfo, blockOffensiveWords, additionalFeaturesOptions,
                                sessionId);
                holder.set(binarySuggestion);
                if (mBinaryDictionary.isCorrupted()) {
                    removeBinaryDictionaryLocked();
                }
            }
        });
        return holder.get(null, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
+13 −0
Original line number Diff line number Diff line
@@ -529,6 +529,14 @@ static int latinime_BinaryDictionary_setCurrentTimeForTest(JNIEnv *env, jclass c
    return TimeKeeper::peekCurrentTime();
}

static bool latinime_BinaryDictionary_isCorruptedNative(JNIEnv *env, jclass clazz, jlong dict) {
    Dictionary *dictionary = reinterpret_cast<Dictionary *>(dict);
    if (!dictionary) {
        return false;
    }
    return dictionary->getDictionaryStructurePolicy()->isCorrupted();
}

static const JNINativeMethod sMethods[] = {
    {
        const_cast<char *>("createEmptyDictFileNative"),
@@ -642,6 +650,11 @@ static const JNINativeMethod sMethods[] = {
        const_cast<char *>("getPropertyNative"),
        const_cast<char *>("(JLjava/lang/String;)Ljava/lang/String;"),
        reinterpret_cast<void *>(latinime_BinaryDictionary_getProperty)
    },
    {
        const_cast<char *>("isCorruptedNative"),
        const_cast<char *>("(J)Z"),
        reinterpret_cast<void *>(latinime_BinaryDictionary_isCorruptedNative)
    }
};