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)