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) |