Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
2efdc90b
Commit
2efdc90b
authored
Feb 07, 2013
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Plain Diff
Issue #17073: Fix some integer overflows in sqlite3 module.
parents
03ee12ed
3cf96ac2
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
196 additions
and
61 deletions
+196
-61
Lib/sqlite3/test/hooks.py
Lib/sqlite3/test/hooks.py
+19
-0
Lib/sqlite3/test/userfunctions.py
Lib/sqlite3/test/userfunctions.py
+48
-12
Misc/NEWS
Misc/NEWS
+2
-0
Modules/_sqlite/connection.c
Modules/_sqlite/connection.c
+46
-27
Modules/_sqlite/cursor.c
Modules/_sqlite/cursor.c
+3
-17
Modules/_sqlite/statement.c
Modules/_sqlite/statement.c
+8
-5
Modules/_sqlite/util.c
Modules/_sqlite/util.c
+66
-0
Modules/_sqlite/util.h
Modules/_sqlite/util.h
+4
-0
No files found.
Lib/sqlite3/test/hooks.py
View file @
2efdc90b
...
@@ -76,6 +76,25 @@ class CollationTests(unittest.TestCase):
...
@@ -76,6 +76,25 @@ class CollationTests(unittest.TestCase):
except
sqlite
.
OperationalError
as
e
:
except
sqlite
.
OperationalError
as
e
:
self
.
assertEqual
(
e
.
args
[
0
].
lower
(),
"no such collation sequence: mycoll"
)
self
.
assertEqual
(
e
.
args
[
0
].
lower
(),
"no such collation sequence: mycoll"
)
def
CheckCollationReturnsLargeInteger
(
self
):
def
mycoll
(
x
,
y
):
# reverse order
return
-
((
x
>
y
)
-
(
x
<
y
))
*
2
**
32
con
=
sqlite
.
connect
(
":memory:"
)
con
.
create_collation
(
"mycoll"
,
mycoll
)
sql
=
"""
select x from (
select 'a' as x
union
select 'b' as x
union
select 'c' as x
) order by x collate mycoll
"""
result
=
con
.
execute
(
sql
).
fetchall
()
self
.
assertEqual
(
result
,
[(
'c'
,),
(
'b'
,),
(
'a'
,)],
msg
=
"the expected order was not returned"
)
def
CheckCollationRegisterTwice
(
self
):
def
CheckCollationRegisterTwice
(
self
):
"""
"""
Register two different collation functions under the same name.
Register two different collation functions under the same name.
...
...
Lib/sqlite3/test/userfunctions.py
View file @
2efdc90b
...
@@ -375,14 +375,15 @@ class AggregateTests(unittest.TestCase):
...
@@ -375,14 +375,15 @@ class AggregateTests(unittest.TestCase):
val
=
cur
.
fetchone
()[
0
]
val
=
cur
.
fetchone
()[
0
]
self
.
assertEqual
(
val
,
60
)
self
.
assertEqual
(
val
,
60
)
def
authorizer_cb
(
action
,
arg1
,
arg2
,
dbname
,
source
):
class
AuthorizerTests
(
unittest
.
TestCase
):
@
staticmethod
def
authorizer_cb
(
action
,
arg1
,
arg2
,
dbname
,
source
):
if
action
!=
sqlite
.
SQLITE_SELECT
:
if
action
!=
sqlite
.
SQLITE_SELECT
:
return
sqlite
.
SQLITE_DENY
return
sqlite
.
SQLITE_DENY
if
arg2
==
'c2'
or
arg1
==
't2'
:
if
arg2
==
'c2'
or
arg1
==
't2'
:
return
sqlite
.
SQLITE_DENY
return
sqlite
.
SQLITE_DENY
return
sqlite
.
SQLITE_OK
return
sqlite
.
SQLITE_OK
class
AuthorizerTests
(
unittest
.
TestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
self
.
con
=
sqlite
.
connect
(
":memory:"
)
self
.
con
=
sqlite
.
connect
(
":memory:"
)
self
.
con
.
executescript
(
"""
self
.
con
.
executescript
(
"""
...
@@ -395,12 +396,12 @@ class AuthorizerTests(unittest.TestCase):
...
@@ -395,12 +396,12 @@ class AuthorizerTests(unittest.TestCase):
# For our security test:
# For our security test:
self
.
con
.
execute
(
"select c2 from t2"
)
self
.
con
.
execute
(
"select c2 from t2"
)
self
.
con
.
set_authorizer
(
authorizer_cb
)
self
.
con
.
set_authorizer
(
self
.
authorizer_cb
)
def
tearDown
(
self
):
def
tearDown
(
self
):
pass
pass
def
CheckTableA
ccess
(
self
):
def
test_table_a
ccess
(
self
):
try
:
try
:
self
.
con
.
execute
(
"select * from t2"
)
self
.
con
.
execute
(
"select * from t2"
)
except
sqlite
.
DatabaseError
as
e
:
except
sqlite
.
DatabaseError
as
e
:
...
@@ -409,7 +410,7 @@ class AuthorizerTests(unittest.TestCase):
...
@@ -409,7 +410,7 @@ class AuthorizerTests(unittest.TestCase):
return
return
self
.
fail
(
"should have raised an exception due to missing privileges"
)
self
.
fail
(
"should have raised an exception due to missing privileges"
)
def
CheckColumnA
ccess
(
self
):
def
test_column_a
ccess
(
self
):
try
:
try
:
self
.
con
.
execute
(
"select c2 from t1"
)
self
.
con
.
execute
(
"select c2 from t1"
)
except
sqlite
.
DatabaseError
as
e
:
except
sqlite
.
DatabaseError
as
e
:
...
@@ -418,11 +419,46 @@ class AuthorizerTests(unittest.TestCase):
...
@@ -418,11 +419,46 @@ class AuthorizerTests(unittest.TestCase):
return
return
self
.
fail
(
"should have raised an exception due to missing privileges"
)
self
.
fail
(
"should have raised an exception due to missing privileges"
)
class
AuthorizerRaiseExceptionTests
(
AuthorizerTests
):
@
staticmethod
def
authorizer_cb
(
action
,
arg1
,
arg2
,
dbname
,
source
):
if
action
!=
sqlite
.
SQLITE_SELECT
:
raise
ValueError
if
arg2
==
'c2'
or
arg1
==
't2'
:
raise
ValueError
return
sqlite
.
SQLITE_OK
class
AuthorizerIllegalTypeTests
(
AuthorizerTests
):
@
staticmethod
def
authorizer_cb
(
action
,
arg1
,
arg2
,
dbname
,
source
):
if
action
!=
sqlite
.
SQLITE_SELECT
:
return
0.0
if
arg2
==
'c2'
or
arg1
==
't2'
:
return
0.0
return
sqlite
.
SQLITE_OK
class
AuthorizerLargeIntegerTests
(
AuthorizerTests
):
@
staticmethod
def
authorizer_cb
(
action
,
arg1
,
arg2
,
dbname
,
source
):
if
action
!=
sqlite
.
SQLITE_SELECT
:
return
2
**
32
if
arg2
==
'c2'
or
arg1
==
't2'
:
return
2
**
32
return
sqlite
.
SQLITE_OK
def
suite
():
def
suite
():
function_suite
=
unittest
.
makeSuite
(
FunctionTests
,
"Check"
)
function_suite
=
unittest
.
makeSuite
(
FunctionTests
,
"Check"
)
aggregate_suite
=
unittest
.
makeSuite
(
AggregateTests
,
"Check"
)
aggregate_suite
=
unittest
.
makeSuite
(
AggregateTests
,
"Check"
)
authorizer_suite
=
unittest
.
makeSuite
(
AuthorizerTests
,
"Check"
)
authorizer_suite
=
unittest
.
makeSuite
(
AuthorizerTests
)
return
unittest
.
TestSuite
((
function_suite
,
aggregate_suite
,
authorizer_suite
))
return
unittest
.
TestSuite
((
function_suite
,
aggregate_suite
,
authorizer_suite
,
unittest
.
makeSuite
(
AuthorizerRaiseExceptionTests
),
unittest
.
makeSuite
(
AuthorizerIllegalTypeTests
),
unittest
.
makeSuite
(
AuthorizerLargeIntegerTests
),
))
def
test
():
def
test
():
runner
=
unittest
.
TextTestRunner
()
runner
=
unittest
.
TextTestRunner
()
...
...
Misc/NEWS
View file @
2efdc90b
...
@@ -166,6 +166,8 @@ Core and Builtins
...
@@ -166,6 +166,8 @@ Core and Builtins
Library
Library
-------
-------
- Issue #17073: Fix some integer overflows in sqlite3 module.
- Issue #17114: IDLE now uses non-strict config parser.
- Issue #17114: IDLE now uses non-strict config parser.
- Issue #16723: httplib.HTTPResponse no longer marked closed when the connection
- Issue #16723: httplib.HTTPResponse no longer marked closed when the connection
...
...
Modules/_sqlite/connection.c
View file @
2efdc90b
...
@@ -482,32 +482,35 @@ error:
...
@@ -482,32 +482,35 @@ error:
}
}
}
}
void
_pysqlite_set_result
(
sqlite3_context
*
context
,
PyObject
*
py_val
)
static
int
_pysqlite_set_result
(
sqlite3_context
*
context
,
PyObject
*
py_val
)
{
{
const
char
*
buffer
;
if
(
py_val
==
Py_None
)
{
Py_ssize_t
buflen
;
if
((
!
py_val
)
||
PyErr_Occurred
())
{
sqlite3_result_null
(
context
);
}
else
if
(
py_val
==
Py_None
)
{
sqlite3_result_null
(
context
);
sqlite3_result_null
(
context
);
}
else
if
(
PyLong_Check
(
py_val
))
{
}
else
if
(
PyLong_Check
(
py_val
))
{
sqlite3_result_int64
(
context
,
PyLong_AsLongLong
(
py_val
));
sqlite_int64
value
=
_pysqlite_long_as_int64
(
py_val
);
if
(
value
==
-
1
&&
PyErr_Occurred
())
return
-
1
;
sqlite3_result_int64
(
context
,
value
);
}
else
if
(
PyFloat_Check
(
py_val
))
{
}
else
if
(
PyFloat_Check
(
py_val
))
{
sqlite3_result_double
(
context
,
PyFloat_AsDouble
(
py_val
));
sqlite3_result_double
(
context
,
PyFloat_AsDouble
(
py_val
));
}
else
if
(
PyUnicode_Check
(
py_val
))
{
}
else
if
(
PyUnicode_Check
(
py_val
))
{
char
*
str
=
_PyUnicode_AsString
(
py_val
);
const
char
*
str
=
_PyUnicode_AsString
(
py_val
);
if
(
str
!=
NULL
)
if
(
str
==
NULL
)
return
-
1
;
sqlite3_result_text
(
context
,
str
,
-
1
,
SQLITE_TRANSIENT
);
sqlite3_result_text
(
context
,
str
,
-
1
,
SQLITE_TRANSIENT
);
}
else
if
(
PyObject_CheckBuffer
(
py_val
))
{
}
else
if
(
PyObject_CheckBuffer
(
py_val
))
{
const
char
*
buffer
;
Py_ssize_t
buflen
;
if
(
PyObject_AsCharBuffer
(
py_val
,
&
buffer
,
&
buflen
)
!=
0
)
{
if
(
PyObject_AsCharBuffer
(
py_val
,
&
buffer
,
&
buflen
)
!=
0
)
{
PyErr_SetString
(
PyExc_ValueError
,
"could not convert BLOB to buffer"
);
PyErr_SetString
(
PyExc_ValueError
,
"could not convert BLOB to buffer"
);
}
else
{
return
-
1
;
sqlite3_result_blob
(
context
,
buffer
,
buflen
,
SQLITE_TRANSIENT
);
}
}
sqlite3_result_blob
(
context
,
buffer
,
buflen
,
SQLITE_TRANSIENT
);
}
else
{
}
else
{
/* TODO: raise error */
return
-
1
;
}
}
return
0
;
}
}
PyObject
*
_pysqlite_build_py_params
(
sqlite3_context
*
context
,
int
argc
,
sqlite3_value
**
argv
)
PyObject
*
_pysqlite_build_py_params
(
sqlite3_context
*
context
,
int
argc
,
sqlite3_value
**
argv
)
...
@@ -528,7 +531,7 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
...
@@ -528,7 +531,7 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
cur_value
=
argv
[
i
];
cur_value
=
argv
[
i
];
switch
(
sqlite3_value_type
(
argv
[
i
]))
{
switch
(
sqlite3_value_type
(
argv
[
i
]))
{
case
SQLITE_INTEGER
:
case
SQLITE_INTEGER
:
cur_py_value
=
PyLong_FromLongLong
(
sqlite3_value_int64
(
cur_value
));
cur_py_value
=
_pysqlite_long_from_int64
(
sqlite3_value_int64
(
cur_value
));
break
;
break
;
case
SQLITE_FLOAT
:
case
SQLITE_FLOAT
:
cur_py_value
=
PyFloat_FromDouble
(
sqlite3_value_double
(
cur_value
));
cur_py_value
=
PyFloat_FromDouble
(
sqlite3_value_double
(
cur_value
));
...
@@ -571,6 +574,7 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
...
@@ -571,6 +574,7 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
PyObject
*
args
;
PyObject
*
args
;
PyObject
*
py_func
;
PyObject
*
py_func
;
PyObject
*
py_retval
=
NULL
;
PyObject
*
py_retval
=
NULL
;
int
ok
;
#ifdef WITH_THREAD
#ifdef WITH_THREAD
PyGILState_STATE
threadstate
;
PyGILState_STATE
threadstate
;
...
@@ -586,10 +590,12 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
...
@@ -586,10 +590,12 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
Py_DECREF
(
args
);
Py_DECREF
(
args
);
}
}
ok
=
0
;
if
(
py_retval
)
{
if
(
py_retval
)
{
_pysqlite_set_result
(
context
,
py_retval
)
;
ok
=
_pysqlite_set_result
(
context
,
py_retval
)
==
0
;
Py_DECREF
(
py_retval
);
Py_DECREF
(
py_retval
);
}
else
{
}
if
(
!
ok
)
{
if
(
_enable_callback_tracebacks
)
{
if
(
_enable_callback_tracebacks
)
{
PyErr_Print
();
PyErr_Print
();
}
else
{
}
else
{
...
@@ -669,9 +675,10 @@ error:
...
@@ -669,9 +675,10 @@ error:
void
_pysqlite_final_callback
(
sqlite3_context
*
context
)
void
_pysqlite_final_callback
(
sqlite3_context
*
context
)
{
{
PyObject
*
function_result
=
NULL
;
PyObject
*
function_result
;
PyObject
**
aggregate_instance
;
PyObject
**
aggregate_instance
;
_Py_IDENTIFIER
(
finalize
);
_Py_IDENTIFIER
(
finalize
);
int
ok
;
#ifdef WITH_THREAD
#ifdef WITH_THREAD
PyGILState_STATE
threadstate
;
PyGILState_STATE
threadstate
;
...
@@ -688,21 +695,23 @@ void _pysqlite_final_callback(sqlite3_context* context)
...
@@ -688,21 +695,23 @@ void _pysqlite_final_callback(sqlite3_context* context)
}
}
function_result
=
_PyObject_CallMethodId
(
*
aggregate_instance
,
&
PyId_finalize
,
""
);
function_result
=
_PyObject_CallMethodId
(
*
aggregate_instance
,
&
PyId_finalize
,
""
);
if
(
!
function_result
)
{
Py_DECREF
(
*
aggregate_instance
);
ok
=
0
;
if
(
function_result
)
{
ok
=
_pysqlite_set_result
(
context
,
function_result
)
==
0
;
Py_DECREF
(
function_result
);
}
if
(
!
ok
)
{
if
(
_enable_callback_tracebacks
)
{
if
(
_enable_callback_tracebacks
)
{
PyErr_Print
();
PyErr_Print
();
}
else
{
}
else
{
PyErr_Clear
();
PyErr_Clear
();
}
}
_sqlite3_result_error
(
context
,
"user-defined aggregate's 'finalize' method raised error"
,
-
1
);
_sqlite3_result_error
(
context
,
"user-defined aggregate's 'finalize' method raised error"
,
-
1
);
}
else
{
_pysqlite_set_result
(
context
,
function_result
);
}
}
error:
error:
Py_XDECREF
(
*
aggregate_instance
);
Py_XDECREF
(
function_result
);
#ifdef WITH_THREAD
#ifdef WITH_THREAD
PyGILState_Release
(
threadstate
);
PyGILState_Release
(
threadstate
);
#endif
#endif
...
@@ -859,7 +868,9 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co
...
@@ -859,7 +868,9 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co
rc
=
SQLITE_DENY
;
rc
=
SQLITE_DENY
;
}
else
{
}
else
{
if
(
PyLong_Check
(
ret
))
{
if
(
PyLong_Check
(
ret
))
{
rc
=
(
int
)
PyLong_AsLong
(
ret
);
rc
=
_PyLong_AsInt
(
ret
);
if
(
rc
==
-
1
&&
PyErr_Occurred
())
rc
=
SQLITE_DENY
;
}
else
{
}
else
{
rc
=
SQLITE_DENY
;
rc
=
SQLITE_DENY
;
}
}
...
@@ -1327,6 +1338,7 @@ pysqlite_collation_callback(
...
@@ -1327,6 +1338,7 @@ pysqlite_collation_callback(
PyGILState_STATE
gilstate
;
PyGILState_STATE
gilstate
;
#endif
#endif
PyObject
*
retval
=
NULL
;
PyObject
*
retval
=
NULL
;
long
longval
;
int
result
=
0
;
int
result
=
0
;
#ifdef WITH_THREAD
#ifdef WITH_THREAD
gilstate
=
PyGILState_Ensure
();
gilstate
=
PyGILState_Ensure
();
...
@@ -1350,10 +1362,17 @@ pysqlite_collation_callback(
...
@@ -1350,10 +1362,17 @@ pysqlite_collation_callback(
goto
finally
;
goto
finally
;
}
}
result
=
PyLong_AsLong
(
retval
);
longval
=
PyLong_AsLongAndOverflow
(
retval
,
&
result
);
if
(
PyErr_Occurred
())
{
if
(
longval
==
-
1
&&
PyErr_Occurred
())
{
PyErr_Clear
();
result
=
0
;
result
=
0
;
}
}
else
if
(
!
result
)
{
if
(
longval
>
0
)
result
=
1
;
else
if
(
longval
<
0
)
result
=
-
1
;
}
finally:
finally:
Py_XDECREF
(
string1
);
Py_XDECREF
(
string1
);
...
...
Modules/_sqlite/cursor.c
View file @
2efdc90b
...
@@ -26,14 +26,6 @@
...
@@ -26,14 +26,6 @@
#include "util.h"
#include "util.h"
#include "sqlitecompat.h"
#include "sqlitecompat.h"
/* used to decide wether to call PyLong_FromLong or PyLong_FromLongLong */
#ifndef INT32_MIN
#define INT32_MIN (-2147483647 - 1)
#endif
#ifndef INT32_MAX
#define INT32_MAX 2147483647
#endif
PyObject
*
pysqlite_cursor_iternext
(
pysqlite_Cursor
*
self
);
PyObject
*
pysqlite_cursor_iternext
(
pysqlite_Cursor
*
self
);
static
char
*
errmsg_fetch_across_rollback
=
"Cursor needed to be reset because of commit/rollback and can no longer be fetched from."
;
static
char
*
errmsg_fetch_across_rollback
=
"Cursor needed to be reset because of commit/rollback and can no longer be fetched from."
;
...
@@ -279,7 +271,6 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
...
@@ -279,7 +271,6 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
PyObject
*
row
;
PyObject
*
row
;
PyObject
*
item
=
NULL
;
PyObject
*
item
=
NULL
;
int
coltype
;
int
coltype
;
PY_LONG_LONG
intval
;
PyObject
*
converter
;
PyObject
*
converter
;
PyObject
*
converted
;
PyObject
*
converted
;
Py_ssize_t
nbytes
;
Py_ssize_t
nbytes
;
...
@@ -339,12 +330,7 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
...
@@ -339,12 +330,7 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
converted
=
Py_None
;
converted
=
Py_None
;
}
else
if
(
coltype
==
SQLITE_INTEGER
)
{
}
else
if
(
coltype
==
SQLITE_INTEGER
)
{
intval
=
sqlite3_column_int64
(
self
->
statement
->
st
,
i
);
converted
=
_pysqlite_long_from_int64
(
sqlite3_column_int64
(
self
->
statement
->
st
,
i
));
if
(
intval
<
INT32_MIN
||
intval
>
INT32_MAX
)
{
converted
=
PyLong_FromLongLong
(
intval
);
}
else
{
converted
=
PyLong_FromLong
((
long
)
intval
);
}
}
else
if
(
coltype
==
SQLITE_FLOAT
)
{
}
else
if
(
coltype
==
SQLITE_FLOAT
)
{
converted
=
PyFloat_FromDouble
(
sqlite3_column_double
(
self
->
statement
->
st
,
i
));
converted
=
PyFloat_FromDouble
(
sqlite3_column_double
(
self
->
statement
->
st
,
i
));
}
else
if
(
coltype
==
SQLITE_TEXT
)
{
}
else
if
(
coltype
==
SQLITE_TEXT
)
{
...
@@ -446,7 +432,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
...
@@ -446,7 +432,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
PyObject
*
func_args
;
PyObject
*
func_args
;
PyObject
*
result
;
PyObject
*
result
;
int
numcols
;
int
numcols
;
PY_LONG_LONG
lastrowid
;
int
statement_type
;
int
statement_type
;
PyObject
*
descriptor
;
PyObject
*
descriptor
;
PyObject
*
second_argument
=
NULL
;
PyObject
*
second_argument
=
NULL
;
...
@@ -716,10 +701,11 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
...
@@ -716,10 +701,11 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
Py_DECREF
(
self
->
lastrowid
);
Py_DECREF
(
self
->
lastrowid
);
if
(
!
multiple
&&
statement_type
==
STATEMENT_INSERT
)
{
if
(
!
multiple
&&
statement_type
==
STATEMENT_INSERT
)
{
sqlite3_int64
lastrowid
;
Py_BEGIN_ALLOW_THREADS
Py_BEGIN_ALLOW_THREADS
lastrowid
=
sqlite3_last_insert_rowid
(
self
->
connection
->
db
);
lastrowid
=
sqlite3_last_insert_rowid
(
self
->
connection
->
db
);
Py_END_ALLOW_THREADS
Py_END_ALLOW_THREADS
self
->
lastrowid
=
PyLong_FromLong
((
long
)
lastrowid
);
self
->
lastrowid
=
_pysqlite_long_from_int64
(
lastrowid
);
}
else
{
}
else
{
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
self
->
lastrowid
=
Py_None
;
self
->
lastrowid
=
Py_None
;
...
...
Modules/_sqlite/statement.c
View file @
2efdc90b
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
#include "connection.h"
#include "connection.h"
#include "microprotocols.h"
#include "microprotocols.h"
#include "prepare_protocol.h"
#include "prepare_protocol.h"
#include "util.h"
#include "sqlitecompat.h"
#include "sqlitecompat.h"
/* prototypes */
/* prototypes */
...
@@ -90,7 +91,6 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
...
@@ -90,7 +91,6 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
int
pysqlite_statement_bind_parameter
(
pysqlite_Statement
*
self
,
int
pos
,
PyObject
*
parameter
)
int
pysqlite_statement_bind_parameter
(
pysqlite_Statement
*
self
,
int
pos
,
PyObject
*
parameter
)
{
{
int
rc
=
SQLITE_OK
;
int
rc
=
SQLITE_OK
;
PY_LONG_LONG
longlongval
;
const
char
*
buffer
;
const
char
*
buffer
;
char
*
string
;
char
*
string
;
Py_ssize_t
buflen
;
Py_ssize_t
buflen
;
...
@@ -120,11 +120,14 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec
...
@@ -120,11 +120,14 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec
}
}
switch
(
paramtype
)
{
switch
(
paramtype
)
{
case
TYPE_LONG
:
case
TYPE_LONG
:
{
/* in the overflow error case, longval/longlongval is -1, and an exception is set */
sqlite_int64
value
=
_pysqlite_long_as_int64
(
parameter
);
longlongval
=
PyLong_AsLongLong
(
parameter
);
if
(
value
==
-
1
&&
PyErr_Occurred
())
rc
=
sqlite3_bind_int64
(
self
->
st
,
pos
,
(
sqlite_int64
)
longlongval
);
rc
=
-
1
;
else
rc
=
sqlite3_bind_int64
(
self
->
st
,
pos
,
value
);
break
;
break
;
}
case
TYPE_FLOAT
:
case
TYPE_FLOAT
:
rc
=
sqlite3_bind_double
(
self
->
st
,
pos
,
PyFloat_AsDouble
(
parameter
));
rc
=
sqlite3_bind_double
(
self
->
st
,
pos
,
PyFloat_AsDouble
(
parameter
));
break
;
break
;
...
...
Modules/_sqlite/util.c
View file @
2efdc90b
...
@@ -104,3 +104,69 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
...
@@ -104,3 +104,69 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
return
errorcode
;
return
errorcode
;
}
}
#ifdef WORDS_BIGENDIAN
# define IS_LITTLE_ENDIAN 0
#else
# define IS_LITTLE_ENDIAN 1
#endif
PyObject
*
_pysqlite_long_from_int64
(
sqlite3_int64
value
)
{
#ifdef HAVE_LONG_LONG
# if SIZEOF_LONG_LONG < 8
if
(
value
>
PY_LLONG_MAX
||
value
<
PY_LLONG_MIN
)
{
return
_PyLong_FromByteArray
(
&
value
,
sizeof
(
value
),
IS_LITTLE_ENDIAN
,
1
/* signed */
);
}
# endif
# if SIZEOF_LONG < SIZEOF_LONG_LONG
if
(
value
>
LONG_MAX
||
value
<
LONG_MIN
)
return
PyLong_FromLongLong
(
value
);
# endif
#else
# if SIZEOF_LONG < 8
if
(
value
>
LONG_MAX
||
value
<
LONG_MIN
)
{
return
_PyLong_FromByteArray
(
&
value
,
sizeof
(
value
),
IS_LITTLE_ENDIAN
,
1
/* signed */
);
}
# endif
#endif
return
PyLong_FromLong
(
value
);
}
sqlite3_int64
_pysqlite_long_as_int64
(
PyObject
*
py_val
)
{
int
overflow
;
#ifdef HAVE_LONG_LONG
PY_LONG_LONG
value
=
PyLong_AsLongLongAndOverflow
(
py_val
,
&
overflow
);
#else
long
value
=
PyLong_AsLongAndOverflow
(
py_val
,
&
overflow
);
#endif
if
(
value
==
-
1
&&
PyErr_Occurred
())
return
-
1
;
if
(
!
overflow
)
{
#ifdef HAVE_LONG_LONG
# if SIZEOF_LONG_LONG > 8
if
(
-
0x8000000000000000LL
<=
value
&&
value
<=
0x7FFFFFFFFFFFFFFFLL
)
# endif
#else
# if SIZEOF_LONG > 8
if
(
-
0x8000000000000000L
<=
value
&&
value
<=
0x7FFFFFFFFFFFFFFFL
)
# endif
#endif
return
value
;
}
else
if
(
sizeof
(
value
)
<
sizeof
(
sqlite3_int64
))
{
sqlite3_int64
int64val
;
if
(
_PyLong_AsByteArray
((
PyLongObject
*
)
py_val
,
(
unsigned
char
*
)
&
int64val
,
sizeof
(
int64val
),
IS_LITTLE_ENDIAN
,
1
/* signed */
)
>=
0
)
{
return
int64val
;
}
}
PyErr_SetString
(
PyExc_OverflowError
,
"Python int too large to convert to SQLite INTEGER"
);
return
-
1
;
}
Modules/_sqlite/util.h
View file @
2efdc90b
...
@@ -35,4 +35,8 @@ int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection);
...
@@ -35,4 +35,8 @@ int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection);
* Returns the error code (0 means no error occurred).
* Returns the error code (0 means no error occurred).
*/
*/
int
_pysqlite_seterror
(
sqlite3
*
db
,
sqlite3_stmt
*
st
);
int
_pysqlite_seterror
(
sqlite3
*
db
,
sqlite3_stmt
*
st
);
PyObject
*
_pysqlite_long_from_int64
(
sqlite3_int64
value
);
sqlite3_int64
_pysqlite_long_as_int64
(
PyObject
*
value
);
#endif
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment