diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabase.java b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabase.java index 3dda73adf..09b324178 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabase.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabase.java @@ -21,7 +21,7 @@ package com.kunzisoft.keepass.database; import com.kunzisoft.keepass.database.exception.InvalidKeyFileException; import com.kunzisoft.keepass.database.exception.KeyFileEmptyException; -import com.kunzisoft.keepass.utils.Util; +import com.kunzisoft.keepass.utils.MemUtil; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -128,7 +128,7 @@ public abstract class PwDatabase assert(keyInputStream != null); ByteArrayOutputStream bos = new ByteArrayOutputStream(); - Util.copyStream(keyInputStream, bos); + MemUtil.copyStream(keyInputStream, bos); byte[] keyData = bos.toByteArray(); ByteArrayInputStream bis = new ByteArrayInputStream(keyData); @@ -430,6 +430,6 @@ public abstract class PwDatabase */ public abstract void initNew(String dbPath); - public void clearCache() {} + public abstract void clearCache(); } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV3.java b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV3.java index 3c813614e..8be18ff21 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV3.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV3.java @@ -376,4 +376,7 @@ public class PwDatabaseV3 extends PwDatabase { return !(omitBackup && isBackup(group)); } + + @Override + public void clearCache() {} } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV4.java b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV4.java index a20ad5a0a..bf7490bf6 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV4.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/PwDatabaseV4.java @@ -756,7 +756,6 @@ public class PwDatabaseV4 extends PwDatabase { @Override public void clearCache() { - super.clearCache(); binPool.clear(); } } \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/database/load/ImporterV4.java b/app/src/main/java/com/kunzisoft/keepass/database/load/ImporterV4.java index 7dda69710..221aece5d 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/load/ImporterV4.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/load/ImporterV4.java @@ -65,10 +65,8 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.text.ParseException; import java.util.Arrays; -import java.util.Calendar; import java.util.Date; import java.util.Stack; -import java.util.TimeZone; import java.util.UUID; import java.util.zip.GZIPInputStream; @@ -83,13 +81,10 @@ public class ImporterV4 extends Importer { private PwDatabaseV4 db; private byte[] hashOfHeader = null; - private byte[] pbHeader = null; private long version; - Calendar utcCal; private File streamDir; public ImporterV4(File streamDir) { - this.utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); this.streamDir = streamDir; } @@ -116,7 +111,7 @@ public class ImporterV4 extends Importer { version = header.getVersion(); hashOfHeader = hh.hash; - pbHeader = hh.header; + byte[] pbHeader = hh.header; db.retrieveMasterKey(password, keyInputStream); db.makeFinalKey(header.masterSeed); @@ -190,7 +185,6 @@ public class ImporterV4 extends Importer { } if ( header.innerRandomStreamKey == null ) { - assert(false); throw new IOException("Invalid stream key."); } @@ -259,7 +253,6 @@ public class ImporterV4 extends Importer { break; default: - assert(false); break; } @@ -354,20 +347,17 @@ public class ImporterV4 extends Importer { } switch ( xpp.getEventType() ) { - case XmlPullParser.START_TAG: - ctx = ReadXmlElement(ctx, xpp); - break; - - case XmlPullParser.END_TAG: - ctx = EndXmlElement(ctx, xpp); - break; + case XmlPullParser.START_TAG: + ctx = ReadXmlElement(ctx, xpp); + break; - default: - assert(false); - break; - + case XmlPullParser.END_TAG: + ctx = EndXmlElement(ctx, xpp); + break; + + default: + break; } - } // Error checks @@ -539,8 +529,8 @@ public class ImporterV4 extends Importer { case Root: if ( name.equalsIgnoreCase(PwDatabaseV4XML.ElemGroup) ) { - assert(ctxGroups.size() == 0); - if ( ctxGroups.size() != 0 ) throw new IOException("Group list should be empty."); + if ( ctxGroups.size() != 0 ) + throw new IOException("Group list should be empty."); db.setRootGroup(new PwGroupV4()); ctxGroups.push(db.getRootGroup()); @@ -639,8 +629,6 @@ public class ImporterV4 extends Importer { } else if ( name.equalsIgnoreCase(PwDatabaseV4XML.ElemCustomData)) { return SwitchContext(ctx, KdbContext.EntryCustomData, xpp); } else if ( name.equalsIgnoreCase(PwDatabaseV4XML.ElemHistory) ) { - assert(!entryInHistory); - if ( ! entryInHistory ) { ctxHistoryBase = ctxEntry; return SwitchContext(ctx, KdbContext.EntryHistory, xpp); @@ -780,8 +768,8 @@ public class ImporterV4 extends Importer { } private KdbContext EndXmlElement(KdbContext ctx, XmlPullParser xpp) throws XmlPullParserException { - assert(xpp.getEventType() == XmlPullParser.END_TAG); - + // (xpp.getEventType() == XmlPullParser.END_TAG); + String name = xpp.getName(); if ( ctx == KdbContext.KeePassFile && name.equalsIgnoreCase(PwDatabaseV4XML.ElemDocNode) ) { return KdbContext.Null; @@ -798,7 +786,7 @@ public class ImporterV4 extends Importer { PwIconCustom icon = new PwIconCustom(customIconID, customIconData); db.addCustomIcon(icon); db.getIconFactory().put(icon); - } else assert(false); + } customIconID = PwDatabase.UUID_ZERO; customIconData = null; @@ -811,7 +799,7 @@ public class ImporterV4 extends Importer { } else if ( ctx == KdbContext.CustomDataItem && name.equalsIgnoreCase(PwDatabaseV4XML.ElemStringDictExItem) ) { if ( customDataKey != null && customDataValue != null) { db.putCustomData(customDataKey, customDataValue); - } else assert(false); + } customDataKey = null; customDataValue = null; @@ -838,8 +826,6 @@ public class ImporterV4 extends Importer { } else if ( ctx == KdbContext.GroupCustomDataItem && name.equalsIgnoreCase(PwDatabaseV4XML.ElemStringDictExItem)) { if (groupCustomDataKey != null && groupCustomDataValue != null) { ctxGroup.putCustomData(groupCustomDataKey, groupCustomDataKey); - } else { - assert(false); } groupCustomDataKey = null; @@ -885,8 +871,6 @@ public class ImporterV4 extends Importer { } else if ( ctx == KdbContext.EntryCustomDataItem && name.equalsIgnoreCase(PwDatabaseV4XML.ElemStringDictExItem)) { if (entryCustomDataKey != null && entryCustomDataValue != null) { ctxEntry.putCustomData(entryCustomDataKey, entryCustomDataValue); - } else { - assert(false); } entryCustomDataKey = null; @@ -902,8 +886,6 @@ public class ImporterV4 extends Importer { ctxDeletedObject = null; return KdbContext.RootDeletedObjects; } else { - assert(false); - String contextName = ""; if (ctx != null) { contextName = ctx.name(); @@ -949,35 +931,24 @@ public class ImporterV4 extends Importer { } private void ReadUnknown(XmlPullParser xpp) throws XmlPullParserException, IOException { - assert(false); - if ( xpp.isEmptyElementTag() ) return; - - String unknownName = xpp.getName(); + ProcessNode(xpp); - while (xpp.next() != XmlPullParser.END_DOCUMENT ) { if ( xpp.getEventType() == XmlPullParser.END_TAG ) break; if ( xpp.getEventType() == XmlPullParser.START_TAG ) continue; ReadUnknown(xpp); } - - assert(xpp.getName().equals(unknownName)); - } private boolean ReadBool(XmlPullParser xpp, boolean bDefault) throws IOException, XmlPullParserException { - String str = ReadString(xpp); - - if ( str.equalsIgnoreCase("true") ) { - return true; - } else if ( str.equalsIgnoreCase("false") ) { - return false; - } else { - return bDefault; - } - } + String str = ReadString(xpp); + + return str.equalsIgnoreCase("true") + || !str.equalsIgnoreCase("false") + && bDefault; + } private UUID ReadUuid(XmlPullParser xpp) throws IOException, XmlPullParserException { String encoded = ReadString(xpp); @@ -1113,8 +1084,8 @@ public class ImporterV4 extends Importer { } private byte[] ProcessNode(XmlPullParser xpp) throws XmlPullParserException, IOException { - assert(xpp.getEventType() == XmlPullParser.START_TAG); - + //(xpp.getEventType() == XmlPullParser.START_TAG); + byte[] buf = null; if ( xpp.getAttributeCount() > 0 ) { diff --git a/app/src/main/java/com/kunzisoft/keepass/database/save/PwDbV4Output.java b/app/src/main/java/com/kunzisoft/keepass/database/save/PwDbV4Output.java index 2b4a85657..810e5ba9e 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/save/PwDbV4Output.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/save/PwDbV4Output.java @@ -402,7 +402,7 @@ public class PwDbV4Output extends PwDbOutput { } - private void writeObject(String key, ProtectedBinary value, boolean allowRef) throws IllegalArgumentException, IllegalStateException, IOException { + private void writeObject(String key, ProtectedBinary value) throws IllegalArgumentException, IllegalStateException, IOException { assert(key != null && value != null); xml.startTag(null, PwDatabaseV4XML.ElemBinary); @@ -411,11 +411,8 @@ public class PwDbV4Output extends PwDbOutput { xml.endTag(null, PwDatabaseV4XML.ElemKey); xml.startTag(null, PwDatabaseV4XML.ElemValue); - String strRef = null; - if (allowRef) { - int ref = mPM.getBinPool().findKey(value); - strRef = Integer.toString(ref); - } + int ref = mPM.getBinPool().findKey(value); + String strRef = Integer.toString(ref); if (strRef != null) { xml.attribute(null, PwDatabaseV4XML.AttrRef, strRef); @@ -429,10 +426,10 @@ public class PwDbV4Output extends PwDbOutput { } private void subWriteValue(ProtectedBinary value) throws IllegalArgumentException, IllegalStateException, IOException { - int valLength = (int) value.length(); // TODO verify + + int valLength = (int) value.length(); // TODO verify if (valLength > 0) { byte[] buffer = new byte[valLength]; - value.getData().read(buffer, 0, valLength); // TODO Nullable if (value.isProtected()) { @@ -637,7 +634,7 @@ public class PwDbV4Output extends PwDbOutput { assert(binaries != null); for (Entry pair : binaries.entrySet()) { - writeObject(pair.getKey(), pair.getValue(), true); + writeObject(pair.getKey(), pair.getValue()); } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java b/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java index 51c6bc961..2f1e373e2 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java +++ b/app/src/main/java/com/kunzisoft/keepass/database/security/ProtectedBinary.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft. + * Copyright 2018 Jeremy Jamet / Kunzisoft. * * This file is part of KeePass DX. * @@ -45,10 +45,14 @@ public class ProtectedBinary implements Parcelable { } public long length() { - return size; + if (data != null) + return data.length; + if (dataFile != null) + return size; + return 0; } - public ProtectedBinary() { + private ProtectedBinary() { this.protect = false; this.data = null; this.dataFile = null; @@ -59,7 +63,10 @@ public class ProtectedBinary implements Parcelable { this.protect = enableProtection; this.data = data; this.dataFile = null; - this.size = data.length; + if (data != null) + this.size = data.length; + else + this.size = 0; } public ProtectedBinary(boolean enableProtection, File dataFile, int size) { @@ -69,7 +76,7 @@ public class ProtectedBinary implements Parcelable { this.size = size; } - public ProtectedBinary(Parcel in) { + private ProtectedBinary(Parcel in) { protect = in.readByte() != 0; in.readByteArray(data); dataFile = new File(in.readString()); diff --git a/app/src/main/java/com/kunzisoft/keepass/stream/LEDataInputStream.java b/app/src/main/java/com/kunzisoft/keepass/stream/LEDataInputStream.java index 5d4cbfb88..1af163754 100644 --- a/app/src/main/java/com/kunzisoft/keepass/stream/LEDataInputStream.java +++ b/app/src/main/java/com/kunzisoft/keepass/stream/LEDataInputStream.java @@ -19,12 +19,9 @@ */ package com.kunzisoft.keepass.stream; -import com.kunzisoft.keepass.utils.Types; - import java.io.IOException; import java.io.InputStream; import java.util.Arrays; -import java.util.UUID; /** Little endian version of the DataInputStream @@ -33,7 +30,7 @@ import java.util.UUID; */ public class LEDataInputStream extends InputStream { - public static final long INT_TO_LONG_MASK = 0xffffffffL; + private static final long INT_TO_LONG_MASK = 0xffffffffL; private InputStream baseStream; @@ -129,7 +126,7 @@ public class LEDataInputStream extends InputStream { } public void readBytes(int length, ActionReadBytes actionReadBytes) throws IOException { - int bufferSize = 256; + int bufferSize = 256 * 3; // TODO Buffer size byte[] buffer = new byte[bufferSize]; int offset = 0; @@ -175,11 +172,11 @@ public class LEDataInputStream extends InputStream { * @return */ public static int readUShort( byte[] buf, int offset ) { - return (buf[offset + 0] & 0xFF) + ((buf[offset + 1] & 0xFF) << 8); + return (buf[offset] & 0xFF) + ((buf[offset + 1] & 0xFF) << 8); } public static long readLong( byte buf[], int offset ) { - return ((long)buf[offset + 0] & 0xFF) + (((long)buf[offset + 1] & 0xFF) << 8) + return ((long)buf[offset] & 0xFF) + (((long)buf[offset + 1] & 0xFF) << 8) + (((long)buf[offset + 2] & 0xFF) << 16) + (((long)buf[offset + 3] & 0xFF) << 24) + (((long)buf[offset + 4] & 0xFF) << 32) + (((long)buf[offset + 5] & 0xFF) << 40) + (((long)buf[offset + 6] & 0xFF) << 48) + (((long)buf[offset + 7] & 0xFF) << 56); @@ -209,14 +206,8 @@ public class LEDataInputStream extends InputStream { * @return */ public static int readInt( byte buf[], int offset ) { - return (buf[offset + 0] & 0xFF) + ((buf[offset + 1] & 0xFF) << 8) + ((buf[offset + 2] & 0xFF) << 16) + return (buf[offset] & 0xFF) + ((buf[offset + 1] & 0xFF) << 8) + ((buf[offset + 2] & 0xFF) << 16) + ((buf[offset + 3] & 0xFF) << 24); } - public UUID readUUID() throws IOException { - byte[] buf = readBytes(16); - - return Types.bytestoUUID(buf); - } - } diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/MemUtil.java b/app/src/main/java/com/kunzisoft/keepass/utils/MemUtil.java index 70004d304..d783c93ac 100644 --- a/app/src/main/java/com/kunzisoft/keepass/utils/MemUtil.java +++ b/app/src/main/java/com/kunzisoft/keepass/utils/MemUtil.java @@ -25,18 +25,33 @@ import android.os.Parcelable; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.HashMap; import java.util.Map; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; public class MemUtil { + + public static void copyStream(InputStream in, OutputStream out) throws IOException { + byte[] buf = new byte[1024]; + int read; + try { + while ((read = in.read(buf)) != -1) { + out.write(buf, 0, read); + } + } catch (OutOfMemoryError error) { + throw new IOException(error); + } + } + public static byte[] decompress(byte[] input) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream(input); GZIPInputStream gzis = new GZIPInputStream(bais); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - Util.copyStream(gzis, baos); + copyStream(gzis, baos); return baos.toByteArray(); } @@ -46,7 +61,7 @@ public class MemUtil { ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPOutputStream gzos = new GZIPOutputStream(baos); - Util.copyStream(bais, gzos); + copyStream(bais, gzos); gzos.close(); return baos.toByteArray(); diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/Util.java b/app/src/main/java/com/kunzisoft/keepass/utils/Util.java index c6b90e84d..ae8c899f0 100644 --- a/app/src/main/java/com/kunzisoft/keepass/utils/Util.java +++ b/app/src/main/java/com/kunzisoft/keepass/utils/Util.java @@ -27,16 +27,11 @@ import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.graphics.Typeface; import android.net.Uri; -import android.util.TypedValue; import android.widget.EditText; import android.widget.TextView; import com.kunzisoft.keepass.R; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - public class Util { public static void gotoUrl(Context context, String url) throws ActivityNotFoundException { @@ -49,20 +44,8 @@ public class Util { public static void gotoUrl(Context context, int resId) throws ActivityNotFoundException { gotoUrl(context, context.getString(resId)); } - - public static void copyStream(InputStream in, OutputStream out) throws IOException { - byte[] buf = new byte[1024]; - int read; - try { - while ((read = in.read(buf)) != -1) { - out.write(buf, 0, read); - } - } catch (OutOfMemoryError error) { - throw new IOException(error); - } - } - /** + /** * Replace font by monospace, must be called after seText() */ public static void applyFontVisibilityTo(final Context context, final TextView textView) {