unix-ffi/sqlite3: Fix bytes to accommodate for different pointer sizes.

Currently, the bytes object used to store the sqlite3 database pointer
is always 4 bytes, which causes segfaults on 64 bit platforms with 8
byte pointers. To address this, the size is now dynamically determined
using the uctypes modules pointer size.

Signed-off-by: Robert Klink <rhermanklink@ripe.net>
pull/905/head
Robert Klink 2024-07-31 13:58:54 +02:00 zatwierdzone przez Damien George
rodzic 910af1889c
commit 8d6ebf57a2
1 zmienionych plików z 14 dodań i 10 usunięć

Wyświetl plik

@ -1,5 +1,6 @@
import sys import sys
import ffilib import ffilib
import uctypes
sq3 = ffilib.open("libsqlite3") sq3 = ffilib.open("libsqlite3")
@ -61,6 +62,10 @@ def check_error(db, s):
raise Error(s, sqlite3_errmsg(db)) raise Error(s, sqlite3_errmsg(db))
def get_ptr_size():
return uctypes.sizeof({"ptr": (0 | uctypes.PTR, uctypes.PTR)})
class Connections: class Connections:
def __init__(self, h): def __init__(self, h):
self.h = h self.h = h
@ -83,13 +88,13 @@ class Cursor:
params = [quote(v) for v in params] params = [quote(v) for v in params]
sql = sql % tuple(params) sql = sql % tuple(params)
print(sql) print(sql)
b = bytearray(4)
s = sqlite3_prepare(self.h, sql, -1, b, None) stmnt_ptr = bytes(get_ptr_size())
check_error(self.h, s) res = sqlite3_prepare(self.h, sql, -1, stmnt_ptr, None)
self.stmnt = int.from_bytes(b, sys.byteorder) check_error(self.h, res)
# print("stmnt", self.stmnt) self.stmnt = int.from_bytes(stmnt_ptr, sys.byteorder)
self.num_cols = sqlite3_column_count(self.stmnt) self.num_cols = sqlite3_column_count(self.stmnt)
# print("num_cols", self.num_cols)
# If it's not select, actually execute it here # If it's not select, actually execute it here
# num_cols == 0 for statements which don't return data (=> modify it) # num_cols == 0 for statements which don't return data (=> modify it)
if not self.num_cols: if not self.num_cols:
@ -127,10 +132,9 @@ class Cursor:
def connect(fname): def connect(fname):
b = bytearray(4) sqlite_ptr = bytes(get_ptr_size())
sqlite3_open(fname, b) sqlite3_open(fname, sqlite_ptr)
h = int.from_bytes(b, sys.byteorder) return Connections(int.from_bytes(sqlite_ptr, sys.byteorder))
return Connections(h)
def quote(val): def quote(val):