Groups seem to be serialized correctly now. I'm still seeing some problems with writing

entries to the disk in the correct format.
This commit is contained in:
Brian Pellin
2009-04-25 00:00:19 -05:00
parent 3c920e15c8
commit 1aabc01456
6 changed files with 69 additions and 46 deletions

View File

@@ -40,6 +40,7 @@ public class PwEntryOutput {
//NOTE: Need be to careful about using ints. The actual type written to file is a unsigned int //NOTE: Need be to careful about using ints. The actual type written to file is a unsigned int
public void output() throws IOException { public void output() throws IOException {
// UUID // UUID
mOS.write(UUID_FIELD_TYPE); mOS.write(UUID_FIELD_TYPE);
mOS.write(UUID_FIELD_SIZE); mOS.write(UUID_FIELD_SIZE);
@@ -56,35 +57,29 @@ public class PwEntryOutput {
mOS.write(Types.writeInt(mPE.imageId)); mOS.write(Types.writeInt(mPE.imageId));
// Title // Title
byte[] title = mPE.title.getBytes("UTF-8"); //byte[] title = mPE.title.getBytes("UTF-8");
mOS.write(TITLE_FIELD_TYPE); mOS.write(TITLE_FIELD_TYPE);
mOS.write(Types.writeInt(title.length)); Types.writeCString(mPE.title, mOS);
mOS.write(title);
// URL // URL
byte[] url = mPE.url.getBytes("UTF-8");
mOS.write(URL_FIELD_TYPE); mOS.write(URL_FIELD_TYPE);
mOS.write(Types.writeInt(url.length)); Types.writeCString(mPE.url, mOS);
mOS.write(url);
// Username // Username
byte[] username = mPE.username.getBytes("UTF-8");
mOS.write(USERNAME_FIELD_TYPE); mOS.write(USERNAME_FIELD_TYPE);
mOS.write(Types.writeInt(username.length)); Types.writeCString(mPE.username, mOS);
mOS.write(username);
// Password // Password
byte[] password = mPE.getPassword(); byte[] password = mPE.getPassword();
mOS.write(PASSWORD_FIELD_TYPE); mOS.write(PASSWORD_FIELD_TYPE);
mOS.write(Types.writeInt(password.length)); mOS.write(Types.writeInt(password.length+1));
mOS.write(password); mOS.write(password);
mOS.write(0);
// Additional // Additional
byte[] additional = mPE.additional.getBytes("UTF-8");
mOS.write(ADDITIONAL_FIELD_TYPE); mOS.write(ADDITIONAL_FIELD_TYPE);
mOS.write(Types.writeInt(additional.length)); Types.writeCString(mPE.additional, mOS);
mOS.write(additional);
// Create date // Create date
mOS.write(CREATE_FIELD_TYPE); mOS.write(CREATE_FIELD_TYPE);
mOS.write(DATE_FIELD_SIZE); mOS.write(DATE_FIELD_SIZE);
@@ -99,24 +94,22 @@ public class PwEntryOutput {
mOS.write(ACCESS_FIELD_TYPE); mOS.write(ACCESS_FIELD_TYPE);
mOS.write(DATE_FIELD_SIZE); mOS.write(DATE_FIELD_SIZE);
mOS.write(Types.writeTime(mPE.tLastAccess)); mOS.write(Types.writeTime(mPE.tLastAccess));
// Expiration date // Expiration date
mOS.write(EXPIRE_FIELD_TYPE); mOS.write(EXPIRE_FIELD_TYPE);
mOS.write(DATE_FIELD_SIZE); mOS.write(DATE_FIELD_SIZE);
mOS.write(Types.writeTime(mPE.tExpire)); mOS.write(Types.writeTime(mPE.tExpire));
// Binary desc // Binary desc
byte[] binaryDesc = mPE.binaryDesc.getBytes("UTF-8");
mOS.write(BINARY_DESC_FIELD_TYPE); mOS.write(BINARY_DESC_FIELD_TYPE);
mOS.write(Types.writeInt(binaryDesc.length)); Types.writeCString(mPE.binaryDesc, mOS);
mOS.write(binaryDesc);
// Binary data // Binary data
byte[] data = mPE.getBinaryData(); byte[] data = mPE.getBinaryData();
mOS.write(BINARY_DATA_FIELD_TYPE); mOS.write(BINARY_DATA_FIELD_TYPE);
mOS.write(Types.writeInt(data.length)); mOS.write(Types.writeInt(data.length));
mOS.write(data); mOS.write(data);
// End // End
mOS.write(END_FIELD_TYPE); mOS.write(END_FIELD_TYPE);
mOS.write(ZERO_FIELD_SIZE); mOS.write(ZERO_FIELD_SIZE);
@@ -136,7 +129,7 @@ public class PwEntryOutput {
public static final byte[] EXPIRE_FIELD_TYPE = Types.writeShort(12); public static final byte[] EXPIRE_FIELD_TYPE = Types.writeShort(12);
public static final byte[] BINARY_DESC_FIELD_TYPE = Types.writeShort(13); public static final byte[] BINARY_DESC_FIELD_TYPE = Types.writeShort(13);
public static final byte[] BINARY_DATA_FIELD_TYPE = Types.writeShort(14); public static final byte[] BINARY_DATA_FIELD_TYPE = Types.writeShort(14);
public static final byte[] END_FIELD_TYPE = Types.writeUByte(0xFFFF); public static final byte[] END_FIELD_TYPE = Types.writeShort(0xFFFF);
public static final byte[] LONG_FOUR = Types.writeInt(4); public static final byte[] LONG_FOUR = Types.writeInt(4);
public static final byte[] UUID_FIELD_SIZE = Types.writeInt(16); public static final byte[] UUID_FIELD_SIZE = Types.writeInt(16);
public static final byte[] DATE_FIELD_SIZE = Types.writeInt(5); public static final byte[] DATE_FIELD_SIZE = Types.writeInt(5);
@@ -144,7 +137,7 @@ public class PwEntryOutput {
public static final byte[] LEVEL_FIELD_SIZE = LONG_FOUR; public static final byte[] LEVEL_FIELD_SIZE = LONG_FOUR;
public static final byte[] FLAGS_FIELD_SIZE = LONG_FOUR; public static final byte[] FLAGS_FIELD_SIZE = LONG_FOUR;
public static final byte[] ZERO_FIELD_SIZE = Types.writeInt(0); public static final byte[] ZERO_FIELD_SIZE = Types.writeInt(0);
public static final byte[] TEST = {0x33, 0x33, 0x33, 0x33};
} }

View File

@@ -46,10 +46,8 @@ public class PwGroupOutput {
mOS.write(Types.writeInt(mPG.groupId)); mOS.write(Types.writeInt(mPG.groupId));
// Name // Name
byte[] name = mPG.name.getBytes("UTF-8");
mOS.write(NAME_FIELD_TYPE); mOS.write(NAME_FIELD_TYPE);
mOS.write(name.length); Types.writeCString(mPG.name, mOS);
mOS.write(name);
// Create date // Create date
mOS.write(CREATE_FIELD_TYPE); mOS.write(CREATE_FIELD_TYPE);
@@ -100,14 +98,12 @@ public class PwGroupOutput {
public static final byte[] IMAGEID_FIELD_TYPE = Types.writeShort(7); public static final byte[] IMAGEID_FIELD_TYPE = Types.writeShort(7);
public static final byte[] LEVEL_FIELD_TYPE = Types.writeShort(8); public static final byte[] LEVEL_FIELD_TYPE = Types.writeShort(8);
public static final byte[] FLAGS_FIELD_TYPE = Types.writeShort(9); public static final byte[] FLAGS_FIELD_TYPE = Types.writeShort(9);
public static final byte[] END_FIELD_TYPE = Types.writeUByte(0xFFFF); public static final byte[] END_FIELD_TYPE = Types.writeShort(0xFFFF);
public static final byte[] LONG_FOUR = Types.writeInt(4); public static final byte[] LONG_FOUR = Types.writeInt(4);
public static final byte[] GROUPID_FIELD_SIZE = LONG_FOUR; public static final byte[] GROUPID_FIELD_SIZE = LONG_FOUR;
public static final byte[] DATE_FIELD_SIZE = Types.writeInt(5); public static final byte[] DATE_FIELD_SIZE = Types.writeInt(5);
public static final byte[] IMAGEID_FIELD_SIZE = LONG_FOUR; public static final byte[] IMAGEID_FIELD_SIZE = LONG_FOUR;
public static final byte[] LEVEL_FIELD_SIZE = Types.writeInt(2); public static final byte[] LEVEL_FIELD_SIZE = Types.writeInt(2);
public static final byte[] FLAGS_FIELD_SIZE = LONG_FOUR; public static final byte[] FLAGS_FIELD_SIZE = LONG_FOUR;
public static final byte[] ZERO_FIELD_SIZE = Types.writeInt(0); public static final byte[] ZERO_FIELD_SIZE = Types.writeInt(0);
} }

View File

@@ -24,6 +24,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
package org.phoneid.keepassj2me; package org.phoneid.keepassj2me;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
@@ -146,12 +149,12 @@ public class Types {
buf[offset] = (byte)(val & 0xFF); buf[offset] = (byte)(val & 0xFF);
} }
public static byte[] writeUByte(int val) { public static byte writeUByte(int val) {
byte[] buf = new byte[2]; byte[] buf = new byte[1];
writeUByte(val, buf, 0); writeUByte(val, buf, 0);
return buf; return buf[0];
} }
/** /**
@@ -201,34 +204,46 @@ public class Types {
// Unpack 5 byte structure to date and time // Unpack 5 byte structure to date and time
int year = (dw1 << 6) | (dw2 >> 2); int year = (dw1 << 6) | (dw2 >> 2);
int month = ((dw2 & 0x00000003) << 2) | (dw3 >> 6); int month = ((dw2 & 0x00000003) << 2) | (dw3 >> 6);
int day = (dw3 >> 1) & 0x0000001F; int day = (dw3 >> 1) & 0x0000001F;
int hour = ((dw3 & 0x00000001) << 4) | (dw4 >> 4); int hour = ((dw3 & 0x00000001) << 4) | (dw4 >> 4);
int minute = ((dw4 & 0x0000000F) << 2) | (dw5 >> 6); int minute = ((dw4 & 0x0000000F) << 2) | (dw5 >> 6);
int second = dw5 & 0x0000003F; int second = dw5 & 0x0000003F;
Calendar time = Calendar.getInstance(); Calendar time = Calendar.getInstance();
time.set( year, month, day, hour, minute, second ); // File format is a 1 based month, java Calendar uses a zero based month
time.set( year, month-1, day, hour, minute, second );
return time.getTime(); return time.getTime();
//return null; //return null;
} }
public static void writeCString(String str, OutputStream os) throws IOException {
byte[] initial = str.getBytes("UTF-8");
int length = initial.length;
os.write(writeInt(length+1));
os.write(initial);
os.write(0x00);
}
public static byte[] writeTime(Date date) { public static byte[] writeTime(Date date) {
byte[] buf = new byte[5]; byte[] buf = new byte[5];
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.setTime(date); cal.setTime(date);
int year = cal.get(Calendar.YEAR); int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH); // File format is a 1 based month, java Calendar uses a zero based month
int month = cal.get(Calendar.MONTH)+1;
int day = cal.get(Calendar.DAY_OF_MONTH); int day = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY); int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE); int minute = cal.get(Calendar.MINUTE);
int second = cal.get(Calendar.SECOND); int second = cal.get(Calendar.SECOND);
buf[0] = (byte)((year >> 6) & 0x0000003F); buf[0] = writeUByte(((year >> 6) & 0x0000003F));
buf[1] = (byte)(((year & 0x0000003F) << 2) | ((month >> 2) & 3) ); buf[1] = writeUByte(((year & 0x0000003F) << 2) | ((month >> 2) & 0x00000003) );
buf[2] = (byte)(((month & 0x00000003) << 6) | ((day & 0x0000001F) << 1) | ((hour >> 4) & 0x00000001)); buf[2] = (byte)(((month & 0x00000003) << 6) | ((day & 0x0000001F) << 1) | ((hour >> 4) & 0x00000001));
buf[3] = (byte)(((hour & 0x0000000F) << 4) | ((minute >> 2) & 0x0000000F)); buf[3] = (byte)(((hour & 0x0000000F) << 4) | ((minute >> 2) & 0x0000000F));
buf[4] = (byte)(((minute & 0x00000003) << 6) | (second & 0x0000003F)); buf[4] = (byte)(((minute & 0x00000003) << 6) | (second & 0x0000003F));

View File

@@ -53,9 +53,9 @@ public class PwEntryTest extends TestCase {
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.setTime(mPE.tCreation); cal.setTime(mPE.tCreation);
assertTrue("Incorrect year.", cal.get(Calendar.YEAR) == 2009); assertEquals("Incorrect year.", cal.get(Calendar.YEAR), 2009);
assertTrue("Incorrect month.", cal.get(Calendar.MONTH) == 4); assertEquals("Incorrect month.", cal.get(Calendar.MONTH), 3);
assertTrue("Incorrect day.", cal.get(Calendar.DAY_OF_MONTH) == 23); assertEquals("Incorrect day.", cal.get(Calendar.DAY_OF_MONTH), 23);
} }
} }

View File

@@ -27,6 +27,7 @@ import java.io.IOException;
import java.security.DigestOutputStream; import java.security.DigestOutputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import junit.framework.TestCase; import junit.framework.TestCase;
@@ -65,9 +66,11 @@ public class PwGroupOutputTest extends TestCase {
peo.output(); peo.output();
} }
Calendar cal = Calendar.getInstance();
cal.setTime(mPM.groups.get(1).tCreation);
byte[] buf = bos.toByteArray(); byte[] buf = bos.toByteArray();
for (int i = 0; i < buf.length; i++) { for (int i = 0; i < buf.length; i++) {
assertEquals("Difference at byte " + i, mPM.postHeader[i], buf[i]); assertEquals("Buf31: " + mPM.postHeader[31] + " Buf32: " + mPM.postHeader[32] + "Buf33: " + mPM.postHeader[33] + " Year: " + cal.get(Calendar.YEAR) + " Month: " + cal.get(Calendar.MONTH) + " Difference at byte " + i, mPM.postHeader[i], buf[i]);
} }
//assertArrayEquals(mPM.postHeader, bos.toByteArray()); //assertArrayEquals(mPM.postHeader, bos.toByteArray());

View File

@@ -19,6 +19,8 @@
*/ */
package com.android.keepass.tests; package com.android.keepass.tests;
import java.util.Calendar;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.phoneid.keepassj2me.Types; import org.phoneid.keepassj2me.Types;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@@ -116,5 +118,19 @@ public class TypesTest extends TestCase {
Types.writeUByte(one, dest, 0); Types.writeUByte(one, dest, 0);
} }
} public void testDate() {
Calendar expected = Calendar.getInstance();
expected.set(2008, 1, 2, 3, 4, 5);
byte[] buf = Types.writeTime(expected.getTime());
Calendar actual = Calendar.getInstance();
actual.setTime(Types.readTime(buf, 0));
assertEquals("Year mismatch: ", 2008, actual.get(Calendar.YEAR));
assertEquals("Month mismatch: ", 1, actual.get(Calendar.MONTH));
assertEquals("Day mismatch: ", 2, actual.get(Calendar.DAY_OF_MONTH));
assertEquals("Hour mismatch: ", 3, actual.get(Calendar.HOUR_OF_DAY));
assertEquals("Minute mismatch: ", 4, actual.get(Calendar.MINUTE));
assertEquals("Second mismatch: ", 5, actual.get(Calendar.SECOND));
}
}