* DataHelper: Sanity checks in storeProps(), use

storeProps() for router config again
This commit is contained in:
zzz
2012-10-05 13:00:52 +00:00
parent 1d174d6797
commit 090d59fcb7
2 changed files with 29 additions and 30 deletions

View File

@@ -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;
}
/**

View File

@@ -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;
}
/**