| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent fc3ba6b commit 023fe33
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -225,6 +225,13 @@ def CheckExecuteArgFloat(self): | |||
| 225 | 225 | def CheckExecuteArgString(self): | |
| 226 | 226 | self.cu.execute("insert into test(name) values (?)", ("Hugo",)) | |
| 227 | 227 | ||
| 228 | + def CheckExecuteArgStringWithZeroByte(self): | ||
| 229 | + self.cu.execute("insert into test(name) values (?)", ("Hu\x00go",)) | ||
| 230 | + | ||
| 231 | + self.cu.execute("select name from test where id=?", (self.cu.lastrowid,)) | ||
| 232 | + row = self.cu.fetchone() | ||
| 233 | + self.assertEqual(row[0], "Hu\x00go") | ||
| 234 | + | ||
| 228 | 235 | def CheckExecuteWrongNoOfArgs1(self): | |
| 229 | 236 | # too many parameters | |
| 230 | 237 | try: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -189,13 +189,48 @@ def CheckOptimizedUnicode(self): | |||
| 189 | 189 | def tearDown(self): | |
| 190 | 190 | self.con.close() | |
| 191 | 191 | ||
| 192 | + class TextFactoryTestsWithEmbeddedZeroBytes(unittest.TestCase): | ||
| 193 | + def setUp(self): | ||
| 194 | + self.con = sqlite.connect(":memory:") | ||
| 195 | + self.con.execute("create table test (value text)") | ||
| 196 | + self.con.execute("insert into test (value) values (?)", ("a\x00b",)) | ||
| 197 | + | ||
| 198 | + def CheckString(self): | ||
| 199 | + # text_factory defaults to str | ||
| 200 | + row = self.con.execute("select value from test").fetchone() | ||
| 201 | + self.assertIs(type(row[0]), str) | ||
| 202 | + self.assertEqual(row[0], "a\x00b") | ||
| 203 | + | ||
| 204 | + def CheckBytes(self): | ||
| 205 | + self.con.text_factory = bytes | ||
| 206 | + row = self.con.execute("select value from test").fetchone() | ||
| 207 | + self.assertIs(type(row[0]), bytes) | ||
| 208 | + self.assertEqual(row[0], b"a\x00b") | ||
| 209 | + | ||
| 210 | + def CheckBytearray(self): | ||
| 211 | + self.con.text_factory = bytearray | ||
| 212 | + row = self.con.execute("select value from test").fetchone() | ||
| 213 | + self.assertIs(type(row[0]), bytearray) | ||
| 214 | + self.assertEqual(row[0], b"a\x00b") | ||
| 215 | + | ||
| 216 | + def CheckCustom(self): | ||
| 217 | + # A custom factory should receive a bytes argument | ||
| 218 | + self.con.text_factory = lambda x: x | ||
| 219 | + row = self.con.execute("select value from test").fetchone() | ||
| 220 | + self.assertIs(type(row[0]), bytes) | ||
| 221 | + self.assertEqual(row[0], b"a\x00b") | ||
| 222 | + | ||
| 223 | + def tearDown(self): | ||
| 224 | + self.con.close() | ||
| 225 | + | ||
| 192 | 226 | def suite(): | |
| 193 | 227 | connection_suite = unittest.makeSuite(ConnectionFactoryTests, "Check") | |
| 194 | 228 | cursor_suite = unittest.makeSuite(CursorFactoryTests, "Check") | |
| 195 | 229 | row_suite_compat = unittest.makeSuite(RowFactoryTestsBackwardsCompat, "Check") | |
| 196 | 230 | row_suite = unittest.makeSuite(RowFactoryTests, "Check") | |
| 197 | 231 | text_suite = unittest.makeSuite(TextFactoryTests, "Check") | |
| 198 | - return unittest.TestSuite((connection_suite, cursor_suite, row_suite_compat, row_suite, text_suite)) | ||
| 232 | + text_zero_bytes_suite = unittest.makeSuite(TextFactoryTestsWithEmbeddedZeroBytes, "Check") | ||
| 233 | + return unittest.TestSuite((connection_suite, cursor_suite, row_suite_compat, row_suite, text_suite, text_zero_bytes_suite)) | ||
| 199 | 234 | ||
| 200 | 235 | def test(): | |
| 201 | 236 | runner = unittest.TextTestRunner() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -113,6 +113,8 @@ Core and Builtins | |||
| 113 | 113 | Library | |
| 114 | 114 | ------- | |
| 115 | 115 | ||
| 116 | + - Issue #13676: Handle strings with embedded zeros correctly in sqlite3. | ||
| 117 | + | ||
| 116 | 118 | - Issue #13506: Add '' to path for IDLE Shell when started and restarted with Restart Shell. | |
| 117 | 119 | Original patches by Marco Scataglini and Roger Serwy. | |
| 118 | 120 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -268,9 +268,9 @@ PyObject* _pysqlite_build_column_name(const char* colname) | |||
| 268 | 268 | } | |
| 269 | 269 | } | |
| 270 | 270 | ||
| 271 | - PyObject* pysqlite_unicode_from_string(const char* val_str, int optimize) | ||
| 271 | + PyObject* pysqlite_unicode_from_string(const char* val_str, Py_ssize_t size, int optimize) | ||
| 272 | 272 | { | |
| 273 | - return PyUnicode_FromString(val_str); | ||
| 273 | + return PyUnicode_FromStringAndSize(val_str, size); | ||
| 274 | 274 | } | |
| 275 | 275 | ||
| 276 | 276 | /* | |
@@ -355,10 +355,11 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) | |||
| 355 | 355 | converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i)); | |
| 356 | 356 | } else if (coltype == SQLITE_TEXT) { | |
| 357 | 357 | val_str = (const char*)sqlite3_column_text(self->statement->st, i); | |
| 358 | + nbytes = sqlite3_column_bytes(self->statement->st, i); | ||
| 358 | 359 | if ((self->connection->text_factory == (PyObject*)&PyUnicode_Type) | |
| 359 | 360 | || (self->connection->text_factory == pysqlite_OptimizedUnicode)) { | |
| 360 | 361 | ||
| 361 | - converted = pysqlite_unicode_from_string(val_str, | ||
| 362 | + converted = pysqlite_unicode_from_string(val_str, nbytes, | ||
| 362 | 363 | self->connection->text_factory == pysqlite_OptimizedUnicode ? 1 : 0); | |
| 363 | 364 | ||
| 364 | 365 | if (!converted) { | |
@@ -383,11 +384,11 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) | |||
| 383 | 384 | } | |
| 384 | 385 | } | |
| 385 | 386 | } else if (self->connection->text_factory == (PyObject*)&PyBytes_Type) { | |
| 386 | - converted = PyBytes_FromString(val_str); | ||
| 387 | + converted = PyBytes_FromStringAndSize(val_str, nbytes); | ||
| 387 | 388 | } else if (self->connection->text_factory == (PyObject*)&PyByteArray_Type) { | |
| 388 | - converted = PyByteArray_FromStringAndSize(val_str, strlen(val_str)); | ||
| 389 | + converted = PyByteArray_FromStringAndSize(val_str, nbytes); | ||
| 389 | 390 | } else { | |
| 390 | - converted = PyObject_CallFunction(self->connection->text_factory, "y", val_str); | ||
| 391 | + converted = PyObject_CallFunction(self->connection->text_factory, "y#", val_str, nbytes); | ||
| 391 | 392 | } | |
| 392 | 393 | } else { | |
| 393 | 394 | /* coltype == SQLITE_BLOB */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -129,9 +129,9 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec | |||
| 129 | 129 | rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter)); | |
| 130 | 130 | break; | |
| 131 | 131 | case TYPE_UNICODE: | |
| 132 | - string = _PyUnicode_AsString(parameter); | ||
| 132 | + string = _PyUnicode_AsStringAndSize(parameter, &buflen); | ||
| 133 | 133 | if (string != NULL) | |
| 134 | - rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT); | ||
| 134 | + rc = sqlite3_bind_text(self->st, pos, string, buflen, SQLITE_TRANSIENT); | ||
| 135 | 135 | else | |
| 136 | 136 | rc = -1; | |
| 137 | 137 | break; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments