diff options
Diffstat (limited to 'tools/dicttool/src')
-rw-r--r-- | tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java index 4c7187fcd..f169641f0 100644 --- a/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java +++ b/tools/dicttool/src/com/android/inputmethod/latin/dicttool/BinaryDictOffdeviceUtils.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.util.Arrays; import java.util.ArrayList; /** @@ -45,26 +46,43 @@ public final class BinaryDictOffdeviceUtils { private final static String PREFIX = "dicttool"; private final static String SUFFIX = ".tmp"; - public final static String COMPRESSION = "compressed"; - public final static String ENCRYPTION = "encrypted"; - - private final static int MAX_DECODE_DEPTH = 8; private final static int COPY_BUFFER_SIZE = 8192; public static class DecoderChainSpec { - ArrayList<String> mDecoderSpec = new ArrayList<>(); + public final static int COMPRESSION = 1; + public final static int ENCRYPTION = 2; + private final static int MAX_DECODE_DEPTH = 4; + + final int[] mDecoderSpec; File mFile; - public DecoderChainSpec addStep(final String stepDescription) { - mDecoderSpec.add(stepDescription); - return this; + public DecoderChainSpec() { + mDecoderSpec = new int[0]; + mFile = null; + } + + public DecoderChainSpec(final DecoderChainSpec src, final int newStep) { + mDecoderSpec = Arrays.copyOf(src.mDecoderSpec, src.mDecoderSpec.length + 1); + mDecoderSpec[src.mDecoderSpec.length] = newStep; + mFile = src.mFile; + } + + private String getStepDescription(final int step) { + switch (step) { + case COMPRESSION: + return "compression"; + case ENCRYPTION: + return "encryption"; + default: + return "unknown"; + } } public String describeChain() { final StringBuilder s = new StringBuilder("raw"); - for (final String step : mDecoderSpec) { + for (final int step : mDecoderSpec) { s.append(" > "); - s.append(step); + s.append(getStepDescription(step)); } return s.toString(); } @@ -91,11 +109,13 @@ public final class BinaryDictOffdeviceUtils { private static DecoderChainSpec getRawDictionaryOrNullInternal( final DecoderChainSpec spec, final File src, final int depth) { // Unfortunately the decoding scheme we use can consider any data to be encrypted - // and will product some output, meaning it's not possible to reliably detect encrypted + // and will produce some output, meaning it's not possible to reliably detect encrypted // data. Thus, some non-dictionary files (especially small) ones may successfully decrypt // over and over, ending in a stack overflow. Hence we limit the depth at which we try // decoding the file. - if (depth > MAX_DECODE_DEPTH) return null; + if (depth > DecoderChainSpec.MAX_DECODE_DEPTH) { + return null; + } if (BinaryDictDecoderUtils.isBinaryDictionary(src) || CombinedInputOutput.isCombinedDictionary(src.getAbsolutePath())) { spec.mFile = src; @@ -107,7 +127,7 @@ public final class BinaryDictOffdeviceUtils { final DecoderChainSpec newSpec = getRawDictionaryOrNullInternal(spec, uncompressedFile, depth + 1); if (null == newSpec) return null; - return newSpec.addStep(COMPRESSION); + return new DecoderChainSpec(newSpec, DecoderChainSpec.COMPRESSION); } // It's not a compressed either - try to see if it's crypted. final File decryptedFile = tryGetDecryptedFile(src); @@ -115,7 +135,7 @@ public final class BinaryDictOffdeviceUtils { final DecoderChainSpec newSpec = getRawDictionaryOrNullInternal(spec, decryptedFile, depth + 1); if (null == newSpec) return null; - return newSpec.addStep(ENCRYPTION); + return new DecoderChainSpec(newSpec, DecoderChainSpec.ENCRYPTION); } return null; } |