diff --git a/Lib/test/test_sqlite3/test_userfunctions.py b/Lib/test/test_sqlite3/test_userfunctions.py index e7cecb85213..506a4c69c67 100644 --- a/Lib/test/test_sqlite3/test_userfunctions.py +++ b/Lib/test/test_sqlite3/test_userfunctions.py @@ -803,13 +803,11 @@ def setUp(self): def tearDown(self): self.con.close() - @unittest.expectedFailure # TODO: RUSTPYTHON; error message differs def test_table_access(self): with self.assertRaises(sqlite.DatabaseError) as cm: self.con.execute("select * from t2") self.assertIn('prohibited', str(cm.exception)) - @unittest.expectedFailure # TODO: RUSTPYTHON; error message differs def test_column_access(self): with self.assertRaises(sqlite.DatabaseError) as cm: self.con.execute("select c2 from t1") diff --git a/crates/stdlib/src/_sqlite3.rs b/crates/stdlib/src/_sqlite3.rs index 5348cc1f5ec..fafdccfbc8a 100644 --- a/crates/stdlib/src/_sqlite3.rs +++ b/crates/stdlib/src/_sqlite3.rs @@ -587,10 +587,10 @@ mod _sqlite3 { ) -> c_int { let (callable, vm) = unsafe { (*data.cast::()).retrieve() }; let f = || -> PyResult { - let arg1 = ptr_to_str(arg1, vm)?; - let arg2 = ptr_to_str(arg2, vm)?; - let db_name = ptr_to_str(db_name, vm)?; - let access = ptr_to_str(access, vm)?; + let arg1 = ptr_to_str_or_none(arg1, vm)?; + let arg2 = ptr_to_str_or_none(arg2, vm)?; + let db_name = ptr_to_str_or_none(db_name, vm)?; + let access = ptr_to_str_or_none(access, vm)?; let val = callable.call((action, arg1, arg2, db_name, access), vm)?; let Some(val) = val.downcast_ref::() else { @@ -2798,12 +2798,14 @@ mod _sqlite3 { } let sql_cstr = sql.to_cstring(vm)?; - let db = connection.db_lock(vm)?; - - db.sql_limit(sql.byte_len(), vm)?; + let raw = { + let db = connection.db_lock(vm)?; + db.sql_limit(sql.byte_len(), vm)?; + **db + }; let mut tail = null(); - let st = db.prepare(sql_cstr.as_ptr(), &mut tail, vm)?; + let st = raw.prepare(sql_cstr.as_ptr(), &mut tail, vm)?; let Some(st) = st else { return Ok(None); @@ -3480,7 +3482,17 @@ mod _sqlite3 { return Err(vm.new_memory_error("string pointer is null")); } unsafe { CStr::from_ptr(p).to_str() } - .map_err(|_| vm.new_value_error("Invalid UIF-8 codepoint")) + .map_err(|_| vm.new_value_error("Invalid UTF-8 codepoint")) + } + + fn ptr_to_str_or_none(p: *const libc::c_char, vm: &VirtualMachine) -> PyResult { + if p.is_null() { + return Ok(vm.ctx.none()); + } + let s = unsafe { CStr::from_ptr(p) } + .to_str() + .map_err(|_| vm.new_value_error("Invalid UTF-8 codepoint".to_owned()))?; + Ok(vm.ctx.new_str(s).into()) } fn ptr_to_string(