From 090d59fcb7b25069f3a7f67f23bac0bbd0554f01 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Fri, 5 Oct 2012 13:00:52 +0000 Subject: [PATCH] * DataHelper: Sanity checks in storeProps(), use storeProps() for router config again --- core/java/src/net/i2p/data/DataHelper.java | 22 +++++++++++-- router/java/src/net/i2p/router/Router.java | 37 ++++++---------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 2a6aca2bfd..eb4ad76cf4 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -388,8 +388,6 @@ public class DataHelper { * - Leading whitespace is not trimmed * - '=' is the only key-termination character (not ':' or whitespace) * - * Note that the escaping of \r or \n was probably a mistake and should be taken out. - * */ public static void loadProps(Properties props, File file) throws IOException { loadProps(props, file, false); @@ -448,20 +446,40 @@ public class DataHelper { * Writes the props to the file, unsorted (unless props is an OrderedProperties) * Note that this does not escape the \r or \n that are unescaped in loadProps() above. * As of 0.8.1, file will be mode 600. + * + * Leading or trailing whitespace in values is not checked but + * will be trimmed by loadProps() + * + * @throws IllegalArgumentException if a key contains any of "#=\n" or starts with ';', + * or a value contains '#' or '\n' */ public static void storeProps(Properties props, File file) throws IOException { PrintWriter out = null; + IllegalArgumentException iae = null; try { out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8"))); out.println("# NOTE: This I2P config file must use UTF-8 encoding"); for (Map.Entry entry : props.entrySet()) { String name = (String) entry.getKey(); String val = (String) entry.getValue(); + if (name.contains("#") || + name.contains("=") || + name.contains("\n") || + name.startsWith(";") || + val.contains("#") || + val.contains("\n")) { + if (iae == null) + iae = new IllegalArgumentException("Invalid character (one of \"#;=\\n\") in key or value: \"" + + name + "\" = \"" + val + '\"'); + continue; + } out.println(name + "=" + val); } } finally { if (out != null) out.close(); } + if (iae != null) + throw iae; } /** diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java index c9bc66e9d1..8b2a414f1d 100644 --- a/router/java/src/net/i2p/router/Router.java +++ b/router/java/src/net/i2p/router/Router.java @@ -49,6 +49,7 @@ import net.i2p.util.FortunaRandomSource; import net.i2p.util.I2PAppThread; import net.i2p.util.I2PThread; import net.i2p.util.Log; +import net.i2p.util.OrderedProperties; import net.i2p.util.SecureFileOutputStream; import net.i2p.util.SimpleByteCache; import net.i2p.util.SimpleScheduler; @@ -976,44 +977,24 @@ public class Router implements RouterClock.ClockShiftListener { * Save the current config options (returning true if save was * successful, false otherwise) * - * Note that unlike DataHelper.storeProps(), - * this does escape the \r or \n that are unescaped in DataHelper.loadProps(). - * Note that the escaping of \r or \n was probably a mistake and should be taken out. - * * Synchronized with file read in getConfig() */ public boolean saveConfig() { - synchronized(_configFileLock) { - FileOutputStream fos = null; - try { - fos = new SecureFileOutputStream(_configFilename); - StringBuilder buf = new StringBuilder(8*1024); - buf.append("# NOTE: This I2P config file must use UTF-8 encoding\n"); - TreeSet ordered = new TreeSet(_config.keySet()); - for (Iterator iter = ordered.iterator() ; iter.hasNext(); ) { - String key = (String)iter.next(); - String val = _config.get(key); - // Escape line breaks before saving. - // Remember: "\" needs escaping both for regex and string. - // NOOO - see comments in DataHelper - //val = val.replaceAll("\\r","\\\\r"); - //val = val.replaceAll("\\n","\\\\n"); - buf.append(key).append('=').append(val).append('\n'); - } - fos.write(buf.toString().getBytes("UTF-8")); - } catch (IOException ioe) { + try { + Properties ordered = new OrderedProperties(); + synchronized(_configFileLock) { + ordered.putAll(_config); + DataHelper.storeProps(ordered, new File(_configFilename)); + } + } catch (Exception ioe) { // warning, _log will be null when called from constructor if (_log != null) _log.error("Error saving the config to " + _configFilename, ioe); else System.err.println("Error saving the config to " + _configFilename + ": " + ioe); return false; - } finally { - if (fos != null) try { fos.close(); } catch (IOException ioe) {} - } - - return true; } + return true; } /** -- GitLab