Console: Safer processing of changes on /configadvanced

This commit is contained in:
zzz
2017-11-26 20:54:44 +00:00
parent 6a48910935
commit 03588e7648
2 changed files with 30 additions and 6 deletions

View File

@ -3,6 +3,8 @@ package net.i2p.router.web;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
@ -17,7 +19,7 @@ import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
public class ConfigAdvancedHandler extends FormHandler { public class ConfigAdvancedHandler extends FormHandler {
//private boolean _forceRestart; //private boolean _forceRestart;
private boolean _shouldSave; private boolean _shouldSave;
private String _config; private String _oldConfig, _config;
private String _ff; private String _ff;
@Override @Override
@ -45,16 +47,24 @@ public class ConfigAdvancedHandler extends FormHandler {
_config = val; _config = val;
} }
/** @since 0.9.33 */
public void setNofilter_oldConfig(String val) {
_oldConfig = val;
}
/** /**
* The user made changes to the config and wants to save them, so * The user made changes to the config and wants to save them, so
* lets go ahead and do so. * lets go ahead and do so.
* *
* We saved the previous config in the form, so we do a diff between the two.
* This will reduce the chance of undoing some change that happened in-between.
*/ */
private void saveChanges() { private void saveChanges() {
Set<String> unsetKeys = new HashSet<String>(_context.router().getConfigSettings()); if (_oldConfig != null && _config != null) {
if (_config != null) { Properties oldProps = new Properties();
Properties props = new Properties(); Properties props = new Properties();
try { try {
DataHelper.loadProps(oldProps, new ByteArrayInputStream(DataHelper.getUTF8(_oldConfig)));
DataHelper.loadProps(props, new ByteArrayInputStream(DataHelper.getUTF8(_config))); DataHelper.loadProps(props, new ByteArrayInputStream(DataHelper.getUTF8(_config)));
} catch (IOException ioe) { } catch (IOException ioe) {
_log.error("Config error", ioe); _log.error("Config error", ioe);
@ -63,9 +73,19 @@ public class ConfigAdvancedHandler extends FormHandler {
return; return;
} }
for (String key : props.stringPropertyNames()) { Set<String> unsetKeys = new HashSet<String>(oldProps.stringPropertyNames());
for (Iterator<Map.Entry<Object, Object>> iter = props.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry<Object, Object> e = iter.next();
String key = (String) e.getKey();
String nnew = (String) e.getValue();
String old = oldProps.getProperty(key);
unsetKeys.remove(key); unsetKeys.remove(key);
if (nnew.equals(old)) {
// no change
iter.remove();
}
} }
// what's remaining in unsetKeys will be deleted
boolean saved = _context.router().saveConfig(props, unsetKeys); boolean saved = _context.router().saveConfig(props, unsetKeys);
if (saved) if (saved)

View File

@ -56,10 +56,14 @@
</form> </form>
<h3 id="advancedconfig" class="tabletitle"><%=intl._t("Advanced I2P Configuration")%>&nbsp;<a title="Help with additional configuration settings" href="/help#advancedsettings">[Additional Options]</a></h3> <h3 id="advancedconfig" class="tabletitle"><%=intl._t("Advanced I2P Configuration")%>&nbsp;<a title="Help with additional configuration settings" href="/help#advancedsettings">[Additional Options]</a></h3>
<% if (advancedhelper.isAdvanced()) { %> <%
String advConfig = advancedhelper.getSettings();
if (advancedhelper.isAdvanced()) {
%>
<form action="" method="POST"> <form action="" method="POST">
<input type="hidden" name="nonce" value="<%=pageNonce%>" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<input type="hidden" name="action" value="blah" > <input type="hidden" name="action" value="blah" >
<input type="hidden" name="nofilter_oldConfig" value="<%=advConfig%>" >
<% } // isAdvanced %> <% } // isAdvanced %>
<table class="configtable" id="advconf"> <table class="configtable" id="advconf">
<% if (advancedhelper.isAdvanced()) { %> <% if (advancedhelper.isAdvanced()) { %>
@ -72,7 +76,7 @@
</td></tr> </td></tr>
<% } // isAdvanced %> <% } // isAdvanced %>
<tr><td class="tabletextarea"> <tr><td class="tabletextarea">
<textarea id="advancedsettings" rows="32" cols="60" name="nofilter_config" wrap="off" spellcheck="false" <% if (!advancedhelper.isAdvanced()) { %>readonly="readonly"<% } %>><jsp:getProperty name="advancedhelper" property="settings" /></textarea> <textarea id="advancedsettings" rows="32" cols="60" name="nofilter_config" wrap="off" spellcheck="false" <% if (!advancedhelper.isAdvanced()) { %>readonly="readonly"<% } %>><%=advConfig%></textarea>
</td></tr> </td></tr>
<% if (advancedhelper.isAdvanced()) { %> <% if (advancedhelper.isAdvanced()) { %>
<tr><td class="optionsave" align="right"> <tr><td class="optionsave" align="right">