mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	gh-129928: Raise more accurate exception for incorrect sqlite3 UDF creation (#129941)
Consistently raise ProgrammingError if the user tries to create an UDF with an invalid number of parameters.
This commit is contained in:
		
							parent
							
								
									0dbe543d70
								
							
						
					
					
						commit
						3a2e7aacf6
					
				
					 3 changed files with 29 additions and 6 deletions
				
			
		|  | @ -171,7 +171,7 @@ def tearDown(self): | ||||||
|         self.con.close() |         self.con.close() | ||||||
| 
 | 
 | ||||||
|     def test_func_error_on_create(self): |     def test_func_error_on_create(self): | ||||||
|         with self.assertRaises(sqlite.OperationalError): |         with self.assertRaisesRegex(sqlite.ProgrammingError, "not -100"): | ||||||
|             self.con.create_function("bla", -100, lambda x: 2*x) |             self.con.create_function("bla", -100, lambda x: 2*x) | ||||||
| 
 | 
 | ||||||
|     def test_func_too_many_args(self): |     def test_func_too_many_args(self): | ||||||
|  | @ -507,9 +507,8 @@ def test_win_sum_int(self): | ||||||
|         self.assertEqual(self.cur.fetchall(), self.expected) |         self.assertEqual(self.cur.fetchall(), self.expected) | ||||||
| 
 | 
 | ||||||
|     def test_win_error_on_create(self): |     def test_win_error_on_create(self): | ||||||
|         self.assertRaises(sqlite.ProgrammingError, |         with self.assertRaisesRegex(sqlite.ProgrammingError, "not -100"): | ||||||
|                           self.con.create_window_function, |             self.con.create_window_function("shouldfail", -100, WindowSumInt) | ||||||
|                           "shouldfail", -100, WindowSumInt) |  | ||||||
| 
 | 
 | ||||||
|     @with_tracebacks(BadWindow) |     @with_tracebacks(BadWindow) | ||||||
|     def test_win_exception_in_method(self): |     def test_win_exception_in_method(self): | ||||||
|  | @ -638,7 +637,7 @@ def tearDown(self): | ||||||
|         self.con.close() |         self.con.close() | ||||||
| 
 | 
 | ||||||
|     def test_aggr_error_on_create(self): |     def test_aggr_error_on_create(self): | ||||||
|         with self.assertRaises(sqlite.OperationalError): |         with self.assertRaisesRegex(sqlite.ProgrammingError, "not -100"): | ||||||
|             self.con.create_function("bla", -100, AggrSum) |             self.con.create_function("bla", -100, AggrSum) | ||||||
| 
 | 
 | ||||||
|     @with_tracebacks(AttributeError, msg_regex="AggrNoStep") |     @with_tracebacks(AttributeError, msg_regex="AggrNoStep") | ||||||
|  |  | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | Raise :exc:`sqlite3.ProgrammingError` if a user-defined SQL function with | ||||||
|  | invalid number of parameters is created. Patch by Erlend Aasland. | ||||||
|  | @ -1139,6 +1139,20 @@ destructor_callback(void *ctx) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int | ||||||
|  | check_num_params(pysqlite_Connection *self, const int n, const char *name) | ||||||
|  | { | ||||||
|  |     int limit = sqlite3_limit(self->db, SQLITE_LIMIT_FUNCTION_ARG, -1); | ||||||
|  |     assert(limit >= 0); | ||||||
|  |     if (n < -1 || n > limit) { | ||||||
|  |         PyErr_Format(self->ProgrammingError, | ||||||
|  |                      "'%s' must be between -1 and %d, not %d", | ||||||
|  |                      name, limit, n); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*[clinic input]
 | /*[clinic input]
 | ||||||
| _sqlite3.Connection.create_function as pysqlite_connection_create_function | _sqlite3.Connection.create_function as pysqlite_connection_create_function | ||||||
| 
 | 
 | ||||||
|  | @ -1167,6 +1181,9 @@ pysqlite_connection_create_function_impl(pysqlite_Connection *self, | ||||||
|     if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { |     if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|  |     if (check_num_params(self, narg, "narg") < 0) { | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (deterministic) { |     if (deterministic) { | ||||||
|         flags |= SQLITE_DETERMINISTIC; |         flags |= SQLITE_DETERMINISTIC; | ||||||
|  | @ -1307,10 +1324,12 @@ create_window_function_impl(pysqlite_Connection *self, PyTypeObject *cls, | ||||||
|                         "SQLite 3.25.0 or higher"); |                         "SQLite 3.25.0 or higher"); | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { |     if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|  |     if (check_num_params(self, num_params, "num_params") < 0) { | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     int flags = SQLITE_UTF8; |     int flags = SQLITE_UTF8; | ||||||
|     int rc; |     int rc; | ||||||
|  | @ -1367,6 +1386,9 @@ pysqlite_connection_create_aggregate_impl(pysqlite_Connection *self, | ||||||
|     if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { |     if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|  |     if (check_num_params(self, n_arg, "n_arg") < 0) { | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     callback_context *ctx = create_callback_context(cls, aggregate_class); |     callback_context *ctx = create_callback_context(cls, aggregate_class); | ||||||
|     if (ctx == NULL) { |     if (ctx == NULL) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Erlend E. Aasland
						Erlend E. Aasland