luci-mod-system: fix SimpleForm usage on file editing pages
authorJo-Philipp Wich <jo@mein.io>
Wed, 5 Jun 2019 14:01:16 +0000 (16:01 +0200)
committerJo-Philipp Wich <jo@mein.io>
Wed, 5 Jun 2019 14:15:40 +0000 (16:15 +0200)
When a value identical to the stored one is submitted, the CBI framework
will not emit an option write event and therfore not store the value in
the form data dictionary passed to SimpleForm.handle().

This usage pattern usally works be accident for file editor views such
as admin_system/crontab because \r\n windows style line endings are
substituted with unix \n ones before writing the data, defeating the
equality check in CBI.

When a single line without trailing newline is submitted however, the
CBI will not see a difference to the data stored in the file and clear
out the value on subsequent saves.

This commit alignes the logic used by various SimpleForm views to
behave identically and predictable:

 - File data is handled in the SimpleForm.handle() callback
 - The forcewrite property is used to disable equality checks
 - Submission of an empty string empties the backing file

Fixes: #2737
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-mod-system/luasrc/model/cbi/admin_system/backupfiles.lua
modules/luci-mod-system/luasrc/model/cbi/admin_system/crontab.lua
modules/luci-mod-system/luasrc/model/cbi/admin_system/startup.lua

index ee2401e93dd6eed990661b684575746027fb92ec..c81466c87455dc66f0ac965015b7f3df397c582b 100644 (file)
@@ -20,7 +20,8 @@ if luci.http.formvalue("display") ~= "list" then
        l.inputstyle = "apply"
 
        c = f:option(TextValue, "_custom")
-       c.rmempty = false
+       c.forcewrite = true
+       c.rmempty = true
        c.cols = 70
        c.rows = 30
 
@@ -28,9 +29,15 @@ if luci.http.formvalue("display") ~= "list" then
                return nixio.fs.readfile("/etc/sysupgrade.conf")
        end
 
-       c.write = function(self, section, value)
-               value = value:gsub("\r\n?", "\n")
-               return nixio.fs.writefile("/etc/sysupgrade.conf", value)
+       m.handle = function(self, state, data)
+               if state == FORM_VALID then
+                       if data._custom then
+                               nixio.fs.writefile("/etc/sysupgrade.conf", data._custom:gsub("\r\n", "\n"))
+                       else
+                               nixio.fs.writefile("/etc/sysupgrade.conf", "")
+                       end
+               end
+               return true
        end
 else
        m.submit = false
index 016a6199aab56c6b0a5e10d06e5963f148f44013..beb24e7caead12ddf231709c015024b207e09863 100644 (file)
@@ -11,6 +11,7 @@ f = SimpleForm("crontab", translate("Scheduled Tasks"),
                "crontab file was empty before editing."))
 
 t = f:field(TextValue, "crons")
+f.forcewrite = true
 t.rmempty = true
 t.rows = 10
 function t.cfgvalue()
index 9e19ac50a238719f87320d70abe4562fd4a55813..c3f14540e3589eac9c9578644f334df2c4763677 100644 (file)
@@ -78,6 +78,7 @@ f = SimpleForm("rc", translate("Local Startup"),
        translate("This is the content of /etc/rc.local. Insert your own commands here (in front of 'exit 0') to execute them at the end of the boot process."))
 
 t = f:field(TextValue, "rcs")
+t.forcewrite = true
 t.rmempty = true
 t.rows = 20
 
@@ -89,6 +90,8 @@ function f.handle(self, state, data)
        if state == FORM_VALID then
                if data.rcs then
                        fs.writefile("/etc/rc.local", data.rcs:gsub("\r\n", "\n"))
+               else
+                       fs.writefile("/etc/rc.local", "")
                end
        end
        return true