aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2018-12-10 15:53:26 -0200
committerHisham Muhammad <hisham@gobolinux.org>2018-12-10 15:53:26 -0200
commit9bb5c285f007d4d2f83ff5593db5afa7fa2a0310 (patch)
tree63caa335d2bb74e7c039284b861fdc1d6c151405
parent914a2b7503b15c40894ac9efb8f33352f1a75cd1 (diff)
downloadluarocks-9bb5c285f007d4d2f83ff5593db5afa7fa2a0310.tar.gz
luarocks-9bb5c285f007d4d2f83ff5593db5afa7fa2a0310.tar.bz2
luarocks-9bb5c285f007d4d2f83ff5593db5afa7fa2a0310.zip
persist: handle keys that are keywords correctly.
Closes #947.
-rw-r--r--spec/persist_spec.lua8
-rw-r--r--src/luarocks/persist.lua75
2 files changed, 70 insertions, 13 deletions
diff --git a/spec/persist_spec.lua b/spec/persist_spec.lua
index dccb0ec4..734b2a4e 100644
--- a/spec/persist_spec.lua
+++ b/spec/persist_spec.lua
@@ -36,6 +36,14 @@ foo = {
36]], persist.save_from_table_to_string({foo = {1, 2, 3, 4}, bar = {baz = "string"}})) 36]], persist.save_from_table_to_string({foo = {1, 2, 3, 4}, bar = {baz = "string"}}))
37 end) 37 end)
38 38
39 it("table with a keyword key (#947)", function()
40 assert.are.same([[
41bar = {
42 ["function"] = "foo"
43}
44]], persist.save_from_table_to_string({bar = {["function"] = "foo"}}))
45 end)
46
39 it("strings with quotes", function() 47 it("strings with quotes", function()
40 assert.are.same([[ 48 assert.are.same([[
41bar = "a \\backslash?" 49bar = "a \\backslash?"
diff --git a/src/luarocks/persist.lua b/src/luarocks/persist.lua
index 6dc8b9ab..73f92bea 100644
--- a/src/luarocks/persist.lua
+++ b/src/luarocks/persist.lua
@@ -42,6 +42,51 @@ local function write_value(out, v, level, sub_order)
42 end 42 end
43end 43end
44 44
45local is_valid_plain_key
46do
47 local keywords = {
48 ["and"] = true,
49 ["break"] = true,
50 ["do"] = true,
51 ["else"] = true,
52 ["elseif"] = true,
53 ["end"] = true,
54 ["false"] = true,
55 ["for"] = true,
56 ["function"] = true,
57 ["goto"] = true,
58 ["if"] = true,
59 ["in"] = true,
60 ["local"] = true,
61 ["nil"] = true,
62 ["not"] = true,
63 ["or"] = true,
64 ["repeat"] = true,
65 ["return"] = true,
66 ["then"] = true,
67 ["true"] = true,
68 ["until"] = true,
69 ["while"] = true,
70 }
71 function is_valid_plain_key(k)
72 return type(k) == "string"
73 and k:match("^[a-zA-Z_][a-zA-Z0-9_]*$")
74 and not keywords[k]
75 end
76end
77
78local function write_table_key_assignment(out, k, level)
79 if is_valid_plain_key(k) then
80 out:write(k)
81 else
82 out:write("[")
83 write_value(out, k, level)
84 out:write("]")
85 end
86
87 out:write(" = ")
88end
89
45--- Write a table as Lua code in curly brackets notation to a writer object. 90--- Write a table as Lua code in curly brackets notation to a writer object.
46-- Only numbers, strings and tables (containing numbers, strings 91-- Only numbers, strings and tables (containing numbers, strings
47-- or other recursively processed tables) are supported. 92-- or other recursively processed tables) are supported.
@@ -64,15 +109,7 @@ write_table = function(out, tbl, level, field_order)
64 if k == i then 109 if k == i then
65 i = i + 1 110 i = i + 1
66 else 111 else
67 if type(k) == "string" and k:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then 112 write_table_key_assignment(out, k, level)
68 out:write(k)
69 else
70 out:write("[")
71 write_value(out, k, level)
72 out:write("]")
73 end
74
75 out:write(" = ")
76 end 113 end
77 114
78 write_value(out, v, level, sub_order) 115 write_value(out, v, level, sub_order)
@@ -95,12 +132,17 @@ end
95-- @param out table or userdata: a writer object supporting :write() method. 132-- @param out table or userdata: a writer object supporting :write() method.
96-- @param tbl table: the table to be written. 133-- @param tbl table: the table to be written.
97-- @param field_order table: optional prioritization table 134-- @param field_order table: optional prioritization table
135-- @return true if successful; nil and error message if failed.
98local function write_table_as_assignments(out, tbl, field_order) 136local function write_table_as_assignments(out, tbl, field_order)
99 for k, v, sub_order in util.sortedpairs(tbl, field_order) do 137 for k, v, sub_order in util.sortedpairs(tbl, field_order) do
138 if not is_valid_plain_key(k) then
139 return nil, "cannot store '"..tostring(k).."' as a plain key."
140 end
100 out:write(k.." = ") 141 out:write(k.." = ")
101 write_value(out, v, 0, sub_order) 142 write_value(out, v, 0, sub_order)
102 out:write("\n") 143 out:write("\n")
103 end 144 end
145 return true
104end 146end
105 147
106--- Write a table as series of assignments to a writer object. 148--- Write a table as series of assignments to a writer object.
@@ -109,7 +151,8 @@ end
109local function write_table_as_table(out, tbl) 151local function write_table_as_table(out, tbl)
110 out:write("return {\n") 152 out:write("return {\n")
111 for k, v, sub_order in util.sortedpairs(tbl) do 153 for k, v, sub_order in util.sortedpairs(tbl) do
112 out:write(" " .. k .. " = ") 154 out:write(" ")
155 write_table_key_assignment(out, k, 1)
113 write_value(out, v, 1, sub_order) 156 write_value(out, v, 1, sub_order)
114 out:write(",\n") 157 out:write(",\n")
115 end 158 end
@@ -122,11 +165,14 @@ end
122-- or other recursively processed tables) are supported. 165-- or other recursively processed tables) are supported.
123-- @param tbl table: the table containing the data to be written 166-- @param tbl table: the table containing the data to be written
124-- @param field_order table: an optional array indicating the order of top-level fields. 167-- @param field_order table: an optional array indicating the order of top-level fields.
125-- @return string 168-- @return persisted data as string; or nil and an error message
126function persist.save_from_table_to_string(tbl, field_order) 169function persist.save_from_table_to_string(tbl, field_order)
127 local out = {buffer = {}} 170 local out = {buffer = {}}
128 function out:write(data) table.insert(self.buffer, data) end 171 function out:write(data) table.insert(self.buffer, data) end
129 write_table_as_assignments(out, tbl, field_order) 172 local ok, err = write_table_as_assignments(out, tbl, field_order)
173 if not ok then
174 return nil, err
175 end
130 return table.concat(out.buffer) 176 return table.concat(out.buffer)
131end 177end
132 178
@@ -144,8 +190,11 @@ function persist.save_from_table(filename, tbl, field_order)
144 if not out then 190 if not out then
145 return nil, "Cannot create file at "..filename 191 return nil, "Cannot create file at "..filename
146 end 192 end
147 write_table_as_assignments(out, tbl, field_order) 193 local ok, err = write_table_as_assignments(out, tbl, field_order)
148 out:close() 194 out:close()
195 if not ok then
196 return nil, err
197 end
149 return true 198 return true
150end 199end
151 200