From 03588e76486187f5018dc78723f71338e908b276 Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Sun, 26 Nov 2017 20:54:44 +0000 Subject: [PATCH] Console: Safer processing of changes on /configadvanced --- .../i2p/router/web/ConfigAdvancedHandler.java | 28 ++++++++++++++++--- apps/routerconsole/jsp/configadvanced.jsp | 8 ++++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigAdvancedHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigAdvancedHandler.java index f1d621674f..c664362165 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigAdvancedHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigAdvancedHandler.java @@ -3,6 +3,8 @@ package net.i2p.router.web; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; import java.util.Properties; import java.util.Set; @@ -17,7 +19,7 @@ import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade; public class ConfigAdvancedHandler extends FormHandler { //private boolean _forceRestart; private boolean _shouldSave; - private String _config; + private String _oldConfig, _config; private String _ff; @Override @@ -44,17 +46,25 @@ public class ConfigAdvancedHandler extends FormHandler { public void setNofilter_config(String 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 * 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() { - Set<String> unsetKeys = new HashSet<String>(_context.router().getConfigSettings()); - if (_config != null) { + if (_oldConfig != null && _config != null) { + Properties oldProps = new Properties(); Properties props = new Properties(); try { + DataHelper.loadProps(oldProps, new ByteArrayInputStream(DataHelper.getUTF8(_oldConfig))); DataHelper.loadProps(props, new ByteArrayInputStream(DataHelper.getUTF8(_config))); } catch (IOException ioe) { _log.error("Config error", ioe); @@ -63,9 +73,19 @@ public class ConfigAdvancedHandler extends FormHandler { 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); + if (nnew.equals(old)) { + // no change + iter.remove(); + } } + // what's remaining in unsetKeys will be deleted boolean saved = _context.router().saveConfig(props, unsetKeys); if (saved) diff --git a/apps/routerconsole/jsp/configadvanced.jsp b/apps/routerconsole/jsp/configadvanced.jsp index bc470e8599..00820a098e 100644 --- a/apps/routerconsole/jsp/configadvanced.jsp +++ b/apps/routerconsole/jsp/configadvanced.jsp @@ -56,10 +56,14 @@ </form> <h3 id="advancedconfig" class="tabletitle"><%=intl._t("Advanced I2P Configuration")%> <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"> <input type="hidden" name="nonce" value="<%=pageNonce%>" > <input type="hidden" name="action" value="blah" > + <input type="hidden" name="nofilter_oldConfig" value="<%=advConfig%>" > <% } // isAdvanced %> <table class="configtable" id="advconf"> <% if (advancedhelper.isAdvanced()) { %> @@ -72,7 +76,7 @@ </td></tr> <% } // isAdvanced %> <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> <% if (advancedhelper.isAdvanced()) { %> <tr><td class="optionsave" align="right"> -- GitLab