From f3307d6508ab5a609b9ed52efc0c6be3e78c8c3b Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Sun, 14 Nov 2010 15:05:24 +0000
Subject: [PATCH]     * Addressbook:       - Try to save files safely       -
 Catch bad B64 lengths

---
 .../java/src/net/i2p/addressbook/AddressBook.java   |  3 +++
 .../java/src/net/i2p/addressbook/ConfigParser.java  | 13 ++++++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/apps/addressbook/java/src/net/i2p/addressbook/AddressBook.java b/apps/addressbook/java/src/net/i2p/addressbook/AddressBook.java
index 6249cadaa0..30536f4ae4 100644
--- a/apps/addressbook/java/src/net/i2p/addressbook/AddressBook.java
+++ b/apps/addressbook/java/src/net/i2p/addressbook/AddressBook.java
@@ -196,6 +196,8 @@ public class AddressBook {
                 // null cert ends with AAAA but other zero-length certs would be AA
 		((dest.length() == MIN_DEST_LENGTH && dest.endsWith("AA")) ||
 		 (dest.length() > MIN_DEST_LENGTH && dest.length() <= MAX_DEST_LENGTH)) &&
+		// B64 comes in groups of 2, 3, or 4 chars, but never 1
+		((dest.length() % 4) != 1) &&
                 dest.replaceAll("[a-zA-Z0-9~-]", "").length() == 0
                 ;	
     }
@@ -253,6 +255,7 @@ public class AddressBook {
             try {
                 ConfigParser.write(this.addresses, file);
             } catch (IOException exp) {
+                System.err.println("Error writing addressbook " + file.getAbsolutePath() + " : " + exp.toString());
             }
         }
     }
diff --git a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java
index 6c95e2e196..c963ecce54 100644
--- a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java
+++ b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java
@@ -269,7 +269,9 @@ public class ConfigParser {
     /**
      * Write contents of Map map to the File file. Output is written
      * with one key, value pair on each line, in the format: key=value.
-     * 
+     * Write to a temp file in the same directory and then rename, to not corrupt
+     * simultaneous accesses by the router.
+     *
      * @param map
      *            A Map to write to file.
      * @param file
@@ -278,8 +280,17 @@ public class ConfigParser {
      *             if file cannot be written to.
      */
     public static void write(Map map, File file) throws IOException {
+        File tmp = File.createTempFile("hoststxt-", ".tmp", file.getAbsoluteFile().getParentFile());
         ConfigParser
+                .write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8")));
+        boolean success = tmp.renameTo(file);
+        if (!success) {
+            // hmm, that didn't work, try it the old way
+            System.out.println("Warning: addressbook rename fail from " + tmp + " to " + file);
+            tmp.delete();
+            ConfigParser
                 .write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
+        }
     }
 
     /**
-- 
GitLab