From f34a8dc6f2be3462740118af05e4c68f6905b86e Mon Sep 17 00:00:00 2001 From: Roger Binns Date: Sat, 8 Jun 2024 09:41:12 -0700 Subject: [PATCH] Address xRandomness error Fixes #526 --- apsw/tests.py | 19 +++++++++++++++++++ doc/changes.rst | 7 +++++++ src/connection.c | 5 +++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/apsw/tests.py b/apsw/tests.py index 2418e412..1533490f 100644 --- a/apsw/tests.py +++ b/apsw/tests.py @@ -5053,6 +5053,25 @@ def __init__(self, filename, flags): self.assertTrue(vfs_saw_none) self.assertTrue(vfsfile_saw_none) + def testIssue526(self): + "Error in VFS xRandomness" + class RandomVFS(apsw.VFS): + def __init__(self): + apsw.VFS.__init__(self, "issue526", "", 1) + + vfs = RandomVFS() + + self.db.pragma("journal_mode", "WAL") + try: + with self.db: + RandomVFS.xRandomness = lambda *args: 1/0 + # this resets SQLite randomness so xRandonness of default VFS will be called again + apsw.randomness(0) + self.db.pragma("user_version", 1) + raise Exception("Should not reach here") + except ZeroDivisionError: + pass + def testCursorGet(self): "Cursor.get" for query, expected in (("select 3,4", (3, 4)), ("select 3; select 4", [3, 4]), ("select 3,4; select 4,5", [ diff --git a/doc/changes.rst b/doc/changes.rst index 608618b5..f4492b4b 100644 --- a/doc/changes.rst +++ b/doc/changes.rst @@ -10,6 +10,13 @@ history `__. APSW changes by version ----------------------- +next +==== + +Address how errors are handled in VFS xRandomness routine, that is +only called once by SQLite to seed its random number generator. +(:issue:`526`) + 3.46.0.0 ======== diff --git a/src/connection.c b/src/connection.c index 72755c2d..1a3321a9 100644 --- a/src/connection.c +++ b/src/connection.c @@ -4040,8 +4040,9 @@ static int connection_trace_and_exec(Connection *self, int release, int sp, int PYSQLITE_CON_CALL(res = sqlite3_exec(self->db, sql, 0, 0, 0)); SET_EXC(res, self->db); sqlite3_free(sql); - assert(res == SQLITE_OK || PyErr_Occurred()); - return res == SQLITE_OK; + + /* See issue 526 for why we can't trust SQLite success code */ + return PyErr_Occurred() ? 0 : (res == SQLITE_OK); } static PyObject *