Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fixes Bug #63916 PDO::PARAM_INT casts to 32bit int internally even on 64... #253

Closed
wants to merge 1 commit into from

3 participants

@srgoogleguy

...bit builds in pdo_sqlite.

@lstrojny

Patch + tests looks good. Does the same bug happen for ext/sqlite3?

@srgoogleguy

hmmm, yes it does. If I run the same reproduce test case through sqlite3 we get the same issue.

<?php
$num = 100004313234244; // notice this exceeds 32 bits
$conn = new sqlite3(':memory:');
$conn->query('CREATE TABLE users (id INTEGER NOT NULL, num INTEGER NOT NULL, PRIMARY KEY(id))');

$stmt = $conn->prepare('insert into users (id, num) values (:id, :num)');
$stmt->bindValue(':id', 1, SQLITE3_INTEGER);
$stmt->bindValue(':num', $num, SQLITE3_INTEGER);
$stmt->execute();

$stmt = $conn->query('SELECT num FROM users');
$result = $stmt->fetchArray();

printf("Expected: %d Received: %d\n", $num, $result[0]);
?>

Output is: "Expected: 100004313234244 Received: 294714180"

I'll have to dig into sqlite3 to see why it's not using the sqlite3_bind_int64 API functions where they're needed. I would have thought this would be the reason they are there, no?

@lstrojny

@srgoogleguy I'm not sure as I don’t know that much about sqlite3. Would be cool if you could dig into that a little further.

@srgoogleguy

@lstrojny Just wanted to update this that I managed to locate the issue in ext/sqlite3 as well and I fixed it in #253

@lstrojny

Looks good.

@php-pulls
Collaborator

Comment on behalf of lstrojny at php.net:

Merged into 5.4, 5.5 and master

@php-pulls php-pulls closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 6, 2013
  1. @srgoogleguy
This page is out of date. Refresh to see the latest.
View
6 ext/pdo_sqlite/sqlite_statement.c
@@ -112,9 +112,15 @@ static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_d
}
} else {
convert_to_long(param->parameter);
+#if LONG_MAX > 2147483647
+ if (SQLITE_OK == sqlite3_bind_int64(S->stmt, param->paramno + 1, Z_LVAL_P(param->parameter))) {
+ return 1;
+ }
+#else
if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(param->parameter))) {
return 1;
}
+#endif
}
pdo_sqlite_error_stmt(stmt);
return 0;
View
27 ext/pdo_sqlite/tests/bug_63916-2.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #63916 PDO::PARAM_INT casts to 32bit int internally even on 64bit builds in pdo_sqlite
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_sqlite')) die('skip');
+if (PHP_INT_SIZE > 4) die('skip');
+?>
+--FILE--
+<?php
+$num = PHP_INT_MAX; // 32 bits
+$conn = new PDO('sqlite::memory:');
+$conn->query('CREATE TABLE users (id INTEGER NOT NULL, num INTEGER NOT NULL, PRIMARY KEY(id))');
+
+$stmt = $conn->prepare('insert into users (id, num) values (:id, :num)');
+$stmt->bindValue(':id', 1, PDO::PARAM_INT);
+$stmt->bindValue(':num', $num, PDO::PARAM_INT);
+$stmt->execute();
+
+$stmt = $conn->query('SELECT num FROM users');
+$result = $stmt->fetchAll(PDO::FETCH_COLUMN);
+
+var_dump($num,$result[0]);
+
+?>
+--EXPECT--
+int(2147483647)
+string(10) "2147483647"
View
27 ext/pdo_sqlite/tests/bug_63916.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #63916 PDO::PARAM_INT casts to 32bit int internally even on 64bit builds in pdo_sqlite
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_sqlite')) die('skip');
+if (PHP_INT_SIZE < 8) die('skip');
+?>
+--FILE--
+<?php
+$num = 100004313234244; // exceeds 32 bits
+$conn = new PDO('sqlite::memory:');
+$conn->query('CREATE TABLE users (id INTEGER NOT NULL, num INTEGER NOT NULL, PRIMARY KEY(id))');
+
+$stmt = $conn->prepare('insert into users (id, num) values (:id, :num)');
+$stmt->bindValue(':id', 1, PDO::PARAM_INT);
+$stmt->bindValue(':num', $num, PDO::PARAM_INT);
+$stmt->execute();
+
+$stmt = $conn->query('SELECT num FROM users');
+$result = $stmt->fetchAll(PDO::FETCH_COLUMN);
+
+var_dump($num,$result[0]);
+
+?>
+--EXPECT--
+int(100004313234244)
+string(15) "100004313234244"
Something went wrong with that request. Please try again.