libs/core: Add recursion detection to dumptable, serialize_data
authorSteven Barth <steven@midlink.org>
Thu, 28 Aug 2008 15:50:27 +0000 (15:50 +0000)
committerSteven Barth <steven@midlink.org>
Thu, 28 Aug 2008 15:50:27 +0000 (15:50 +0000)
Dumptable now writes to stderr

libs/cbi/luasrc/cbi.lua
libs/core/luasrc/util.lua

index 0a406c4..411aa23 100644 (file)
@@ -616,6 +616,13 @@ function NamedSection.parse(self)
                AbstractSection.parse_dynamic(self, s)
                if luci.http.formvalue("cbi.submit") then
                        Node.parse(self, s)
+                       
+                       if not self.override_scheme and self.map.scheme then
+                               local co = self.map:get()
+                               local stat, err = self.map.validator:validate_section(self.config, s, co)
+                               luci.http.prepare_content("text/html")
+                               luci.util.dumptable(err)
+                       end
                end
                AbstractSection.parse_optionals(self, s)
        end
@@ -705,10 +712,17 @@ function TypedSection.parse(self)
                end
        end
 
+       local co
        for i, k in ipairs(self:cfgsections()) do
                AbstractSection.parse_dynamic(self, k)
                if luci.http.formvalue("cbi.submit") then
                        Node.parse(self, k)
+                       
+                       if not self.override_scheme and self.map.scheme then
+                               co = co or self.map:get()
+                               local stat, err = self.map.uvl:validate_section(self.config, k, co)
+                               luci.util.perror(err)
+                       end
                end
                AbstractSection.parse_optionals(self, k)
        end
index cc15d3a..14bd1e7 100644 (file)
@@ -185,12 +185,19 @@ end
 -- @param t    Table value to dump
 -- @param i    Number of tabs to prepend to each line
 -- @return     Always nil
-function dumptable(t, i)
+function dumptable(t, i, seen)
        i = i or 0
+       seen = seen or setmetatable({}, {__mode="k"})
+       
        for k,v in pairs(t) do
-               print(string.rep("\t", i) .. tostring(k), tostring(v))
+               perror(string.rep("\t", i) .. tostring(k), tostring(v))
                if type(v) == "table" then
-                       dumptable(v, i+1)
+                       if not seen[v] then
+                               seen[v] = true
+                               dumptable(v, i+1, seen)
+                       else
+                               perror(string.rep("\t", i) .. "*** RECURSION ***")
+                       end
                end
        end
 end
@@ -425,11 +432,14 @@ end
 
 
 -- Serialize the contents of a table value.
-function _serialize_table(t)
+function _serialize_table(t, seen)
+       assert(not seen[t], "Recursion detected.")
+       seen[t] = true
+       
        local data = ""
        for k, v in pairs(t) do
-               k = serialize_data(k)
-               v = serialize_data(v)
+               k = serialize_data(k, seen)
+               v = serialize_data(v, seen)
                data = data .. ( #data > 0 and ", " or "" ) ..
                        '[' .. k .. '] = ' .. v
        end
@@ -442,7 +452,9 @@ end
 -- @return             String value containing the serialized code
 -- @see                        restore_data
 -- @see                        get_bytecode
-function serialize_data(val)
+function serialize_data(val, seen)
+       seen = seen or setmetatable({}, {__mode="k"})
+       
        if val == nil then
                return "nil"
        elseif type(val) == "number" then
@@ -454,7 +466,7 @@ function serialize_data(val)
        elseif type(val) == "function" then
                return string.format("loadstring(%q)", get_bytecode(val))
        elseif type(val) == "table" then
-               return "{ " .. _serialize_table(val) .. " }"
+               return "{ " .. _serialize_table(val, seen) .. " }"
        else
                return '"[unhandled data type:' .. type(val) .. ']"'
        end