Software /
code /
prosody
Comparison
plugins/mod_storage_sql.lua @ 8537:d7f31badd359
mod_storage_sql: Catch and report value deserialization errors
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 24 Feb 2018 11:50:08 +0100 |
parent | 8480:3d3706147174 |
child | 9459:6c279302fff4 |
comparison
equal
deleted
inserted
replaced
8536:c3f234e4ac23 | 8537:d7f31badd359 |
---|---|
41 local function deserialize(t, value) | 41 local function deserialize(t, value) |
42 if t == "string" then return value; | 42 if t == "string" then return value; |
43 elseif t == "boolean" then | 43 elseif t == "boolean" then |
44 if value == "true" then return true; | 44 if value == "true" then return true; |
45 elseif value == "false" then return false; end | 45 elseif value == "false" then return false; end |
46 elseif t == "number" then return tonumber(value); | 46 return nil, "invalid-boolean"; |
47 elseif t == "number" then | |
48 value = tonumber(value); | |
49 if value then return value; end | |
50 return nil, "invalid-number"; | |
47 elseif t == "json" then | 51 elseif t == "json" then |
48 return json.decode(value); | 52 return json.decode(value); |
49 elseif t == "xml" then | 53 elseif t == "xml" then |
50 return xml_parse(value); | 54 return xml_parse(value); |
51 end | 55 end |
56 return nil, "Unhandled value type: "..t; | |
52 end | 57 end |
53 | 58 |
54 local host = module.host; | 59 local host = module.host; |
55 local user, store; | 60 local user, store; |
56 | 61 |
63 WHERE "host"=? AND "user"=? AND "store"=?; | 68 WHERE "host"=? AND "user"=? AND "store"=?; |
64 ]] | 69 ]] |
65 for row in engine:select(select_sql, host, user or "", store) do | 70 for row in engine:select(select_sql, host, user or "", store) do |
66 haveany = true; | 71 haveany = true; |
67 local k = row[1]; | 72 local k = row[1]; |
68 local v = deserialize(row[2], row[3]); | 73 local v, e = deserialize(row[2], row[3]); |
74 assert(v ~= nil, e); | |
69 if k and v then | 75 if k and v then |
70 if k ~= "" then result[k] = v; elseif type(v) == "table" then | 76 if k ~= "" then result[k] = v; elseif type(v) == "table" then |
71 for a,b in pairs(v) do | 77 for a,b in pairs(v) do |
72 result[a] = b; | 78 result[a] = b; |
73 end | 79 end |
152 SELECT "type", "value" | 158 SELECT "type", "value" |
153 FROM "prosody" | 159 FROM "prosody" |
154 WHERE "host"=? AND "user"=? AND "store"=? AND "key"=? | 160 WHERE "host"=? AND "user"=? AND "store"=? AND "key"=? |
155 LIMIT 1 | 161 LIMIT 1 |
156 ]]; | 162 ]]; |
157 local data; | 163 local data, err; |
158 if type(key) == "string" and key ~= "" then | 164 if type(key) == "string" and key ~= "" then |
159 for row in engine:select(query, host, username or "", self.store, key) do | 165 for row in engine:select(query, host, username or "", self.store, key) do |
160 data = deserialize(row[1], row[2]); | 166 data, err = deserialize(row[1], row[2]); |
167 assert(data ~= nil, err); | |
161 end | 168 end |
162 return data; | 169 return data; |
163 else | 170 else |
164 for row in engine:select(query, host, username or "", self.store, "") do | 171 for row in engine:select(query, host, username or "", self.store, "") do |
165 data = deserialize(row[1], row[2]); | 172 data, err = deserialize(row[1], row[2]); |
173 assert(data ~= nil, err); | |
166 end | 174 end |
167 return data and data[key] or nil; | 175 return data and data[key] or nil; |
168 end | 176 end |
169 end); | 177 end); |
170 if not ok then return nil, result; end | 178 if not ok then return nil, result; end |
198 if data ~= self.remove then | 206 if data ~= self.remove then |
199 local t, value = assert(serialize(data)); | 207 local t, value = assert(serialize(data)); |
200 engine:insert(insert_sql, host, username or "", self.store, key, t, value); | 208 engine:insert(insert_sql, host, username or "", self.store, key, t, value); |
201 end | 209 end |
202 else | 210 else |
203 local extradata = {}; | 211 local extradata, err = {}; |
204 for row in engine:select(select_extradata_sql, host, username or "", self.store, "") do | 212 for row in engine:select(select_extradata_sql, host, username or "", self.store, "") do |
205 extradata = deserialize(row[1], row[2]); | 213 extradata, err = deserialize(row[1], row[2]); |
214 assert(extradata ~= nil, err); | |
206 end | 215 end |
207 engine:delete(delete_sql, host, username or "", self.store, ""); | 216 engine:delete(delete_sql, host, username or "", self.store, ""); |
208 extradata[key] = data; | 217 extradata[key] = data; |
209 local t, value = assert(serialize(extradata)); | 218 local t, value = assert(serialize(extradata)); |
210 engine:insert(insert_sql, host, username or "", self.store, "", t, value); | 219 engine:insert(insert_sql, host, username or "", self.store, "", t, value); |
354 end); | 363 end); |
355 if not ok then return ok, result end | 364 if not ok then return ok, result end |
356 return function() | 365 return function() |
357 local row = result(); | 366 local row = result(); |
358 if row ~= nil then | 367 if row ~= nil then |
359 return row[1], deserialize(row[2], row[3]), row[4], row[5]; | 368 local value, err = deserialize(row[2], row[3]); |
369 assert(value ~= nil, err); | |
370 return row[1], value, row[4], row[5]; | |
360 end | 371 end |
361 end, total; | 372 end, total; |
362 end | 373 end |
363 | 374 |
364 function archive_store:delete(username, query) | 375 function archive_store:delete(username, query) |