Discussion:
[DBD-SQLite] [patch][1/2] Fix integer overflow in passing argument to perl function
Yuriy Kaminskiy
2012-03-24 18:23:04 UTC
Permalink
... with test (should fail before patch on all machines with
sizeof(int)<sizeof(int64_t), and pass after patch).
Yuriy M. Kaminskiy
2012-03-24 18:09:04 UTC
Permalink
---
dbdimp.c | 15 ++++++++++++++-
t/09_create_function.t | 6 +++++-
2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/dbdimp.c b/dbdimp.c
index 3a4e308..346138c 100644
--- a/dbdimp.c
+++ b/dbdimp.c
@@ -1304,11 +1304,24 @@ sqlite_db_func_dispatcher(int is_unicode, sqlite3_context *context, int argc, sq
SV *arg;
STRLEN len;
int type = sqlite3_value_type(value[i]);
+ sqlite_int64 iv;

/* warn("func dispatch type: %d, value: %s\n", type, sqlite3_value_text(value[i])); */
switch(type) {
case SQLITE_INTEGER:
- arg = sv_2mortal(newSViv(sqlite3_value_int(value[i])));
+ iv = sqlite3_value_int64(value[i]);
+ if ( iv >= IV_MIN && iv <= IV_MAX ) {
+ /* ^^^ compile-time constant (= true) when IV == int64 */
+ arg = sv_2mortal(newSViv((IV)iv));
+ }
+ else if ( iv >= 0 && iv <= UV_MAX ) {
+ /* warn("integer overflow, cast to UV"); */
+ arg = sv_2mortal(newSVuv((UV)iv));
+ }
+ else {
+ /* warn("integer overflow, cast to NV"); */
+ arg = sv_2mortal(newSVnv((NV)iv));
+ }
break;
case SQLITE_FLOAT:
arg = sv_2mortal(newSVnv(sqlite3_value_double(value[i])));
diff --git a/t/09_create_function.t b/t/09_create_function.t
index d00e6e6..090fb73 100644
--- a/t/09_create_function.t
+++ b/t/09_create_function.t
@@ -11,7 +11,7 @@ use t::lib::Test qw/connect_ok @CALL_FUNCS/;
use Test::More;
use Test::NoWarnings;

-plan tests => 27 * @CALL_FUNCS + 1;
+plan tests => 28 * @CALL_FUNCS + 1;

sub now {
return time();
@@ -119,5 +119,9 @@ foreach my $call_func (@CALL_FUNCS) {
$result = $dbh->selectrow_arrayref( "SELECT noop(1.0625)" );
is_deeply( $result, [ 1.0625 ], "SELECT noop(1.0625)" );

+ # 2147483648 == 1<<31
+ $result = $dbh->selectrow_arrayref( "SELECT noop(2147483648)" );
+ is_deeply( $result, [ 2147483648 ], "SELECT noop(2147483648)" );
+
$dbh->disconnect;
}
--
1.7.6.3


--------------040005010804050006030405--
Yuriy Kaminskiy
2012-03-24 18:41:22 UTC
Permalink
We can avoid converting UV to text when it fits in int64.
Test fails before patch only on machines with 32-bit IV/UV.
kenichi ishigaki
2012-03-25 02:41:29 UTC
Permalink
Applied the last three (two in this thread and one in the previous
thread) to the trunk, either.

Thanks,

Kenichi
Post by Yuriy Kaminskiy
We can avoid converting UV to text when it fits in int64.
Test fails before patch only on machines with 32-bit IV/UV.
_______________________________________________
DBD-SQLite mailing list
http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbd-sqlite
Loading...