You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
1.9 KiB

import csv
import re
import shlex
import sys
csv.field_size_limit(2 ** 31 - 1)
dict_params = re.compile(r":([^\ \,\.\\\(\)\=]+)")
list_params = re.compile(r"\?")
class AndroidSQLConn:
def __init__(self, device, filepath, use_root=True):
self.device = device
self.filepath = filepath
self.root = use_root
def _quote_param_(param):
if isinstance(param, str):
return "'{}'".format(param.replace("'", "''"))
elif isinstance(param, bool):
return "1" if param else "0"
elif param is None:
return "NULL"
else:
return str(param)
def _sub_params_(SQL, params):
params = iter(params)
try:
return list_params.sub(
lambda match: AndroidSQLConn._quote_param_(next(params)), SQL
)
except StopIteration:
raise TypeError("Not enough parameters")
def _sub_params_dict_(SQL, params):
try:
return dict_params.sub(
lambda match: AndroidSQLConn._quote_param_(params[match.group(1)]), SQL
)
except KeyError:
raise TypeError("Parameter specified but not in mapping")
def execute(self, SQL, params=None):
if params:
if isinstance(params, dict):
SQL = AndroidSQLConn._sub_params_dict_(SQL, params)
else:
SQL = AndroidSQLConn._sub_params_(SQL, params)
SQL = shlex.quote(SQL)
if self.root:
shell = self.device.sudo
else:
shell = self.device.shell
out = shell(
"sqlite3", "-header", "-csv", shlex.quote(self.filepath), SQL, output="out"
)
if out:
return csv.DictReader(out.splitlines())
if __name__ == "__main__":
print(
AndroidSQLConn._sub_params_(
"SELECT * FROM table WHERE name=?,age=?;", ["boby;DROP TABLE table", 1]
)
)