Add new pdo_sqlsrv tests for utf8 encoding errors (#966)
This commit is contained in:
parent
486ab9fb08
commit
8ba932b1ca
137
test/functional/pdo_sqlsrv/pdo_construct_attr_errors.phpt
Normal file
137
test/functional/pdo_sqlsrv/pdo_construct_attr_errors.phpt
Normal file
|
@ -0,0 +1,137 @@
|
|||
--TEST--
|
||||
Test various connection errors with invalid attributes
|
||||
--DESCRIPTION--
|
||||
This is similar to sqlsrv sqlsrv_connStr.phpt such that invalid connection attributes or values used when connecting.
|
||||
--SKIPIF--
|
||||
<?php require('skipif_mid-refactor.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
function invalidEncoding($binary)
|
||||
{
|
||||
try {
|
||||
$options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
$conn = connect("", $options);
|
||||
$attr = ($binary) ? PDO::SQLSRV_ENCODING_BINARY : 'gibberish';
|
||||
|
||||
$conn->setAttribute(PDO::SQLSRV_ATTR_ENCODING, $attr);
|
||||
echo "Should have failed about an invalid encoding.\n";
|
||||
} catch (PDOException $e) {
|
||||
$error = '*An invalid encoding was specified for SQLSRV_ATTR_ENCODING.';
|
||||
if (!fnmatch($error, $e->getMessage())) {
|
||||
echo "invalidEncoding($binary)\n";
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function invalidServer()
|
||||
{
|
||||
global $uid, $pwd;
|
||||
|
||||
// Test an invalid server name in UTF-8
|
||||
try {
|
||||
$options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
$invalid = pack("H*", "ffc0");
|
||||
$conn = new PDO("sqlsrv:server = $invalid;", $uid, $pwd, $options);
|
||||
echo "Should have failed to connect to invalid server.\n";
|
||||
} catch (PDOException $e) {
|
||||
$error1 = '*Login timeout expired';
|
||||
$error2 = '*An error occurred translating the connection string to UTF-16: No mapping for the Unicode character exists in the target multi-byte code page*';
|
||||
if (fnmatch($error1, $e->getMessage()) || fnmatch($error2, $e->getMessage())) {
|
||||
; // matched at least one of the expected error messages
|
||||
} else {
|
||||
echo "invalidServer\n";
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function utf8APP()
|
||||
{
|
||||
global $server, $uid, $pwd;
|
||||
try {
|
||||
// Use a UTF-8 name
|
||||
$app = pack('H*', 'c59ec6a1d0bcc49720c59bc3a4e1839dd180c580e1bb8120ce86c59ac488c4a8c4b02dc5a5e284aec397c5a7');
|
||||
$dsn = "APP = $app;";
|
||||
$conn = connect($dsn);
|
||||
} catch (PDOException $e) {
|
||||
echo "With APP in UTF8 it should not have failed!\n";
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
function invalidCredentials()
|
||||
{
|
||||
global $server, $database;
|
||||
|
||||
// Use valid UTF-8
|
||||
$user = pack('H*', 'c59ec6a1d0bcc49720c59bc3a4e1839dd180c580e1bb8120ce86c59ac488c4a8c4b02dc5a5e284aec397c5a7');
|
||||
$passwd = pack('H*', 'c59ec6a1d0bcc49720c59bc3a4e1839dd180c580e1bb8120ce86c59ac488c4a8c4b02dc5a5e284aec397c5a7');
|
||||
|
||||
$options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
$error1 = "*Login failed for user \'*\'.";
|
||||
$error2 = "*Login timeout expired*";
|
||||
|
||||
try {
|
||||
$conn = new PDO("sqlsrv:server = $server; database = $database;", $user, $passwd, $options);
|
||||
echo "Should have failed to connect\n";
|
||||
} catch (PDOException $e) {
|
||||
if (fnmatch($error1, $e->getMessage()) || fnmatch($error2, $e->getMessage())) {
|
||||
; // matched at least one of the expected error messages
|
||||
} else {
|
||||
echo "invalidCredentials()\n";
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function invalidPassword()
|
||||
{
|
||||
global $server, $database;
|
||||
|
||||
// Use valid UTF-8
|
||||
$user = pack('H*', 'c59ec6a1d0bcc49720c59bc3a4e1839dd180c580e1bb8120ce86c59ac488c4a8c4b02dc5a5e284aec397c5a7');
|
||||
// Use invalid UTF-8
|
||||
$passwd = pack('H*', 'c59ec6c0d0bcc49720c59bc3a4e1839dd180c580e1bb8120ce86c59ac488c4a8c4b02dc5a5e284aec397c5a7');
|
||||
|
||||
$options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
// Possible errors
|
||||
$error = "*An error occurred translating the connection string to UTF-16: No mapping for the Unicode character exists in the target multi-byte code page.*";
|
||||
$error1 = "*Login failed for user \'*\'.";
|
||||
$error2 = "*Login timeout expired*";
|
||||
|
||||
try {
|
||||
$conn = new PDO("sqlsrv:server = $server; database = $database;", $user, $passwd, $options);
|
||||
echo "Should have failed to connect\n";
|
||||
} catch (PDOException $e) {
|
||||
if (!fnmatch($error, $e->getMessage())) {
|
||||
// Sometimes it might fail with two other possible error messages
|
||||
if (fnmatch($error1, $e->getMessage()) || fnmatch($error2, $e->getMessage())) {
|
||||
; // matched at least one of the expected error messages
|
||||
} else {
|
||||
echo "invalidPassword()\n";
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
invalidEncoding(false);
|
||||
invalidEncoding(true);
|
||||
invalidServer();
|
||||
utf8APP();
|
||||
invalidCredentials();
|
||||
invalidPassword();
|
||||
|
||||
echo "Done\n";
|
||||
} catch (PDOException $e) {
|
||||
var_dump($e);
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
||||
|
|
@ -12,6 +12,7 @@ require_once("MsCommon.inc");
|
|||
// These are the error messages we expect at various points below
|
||||
$errorNoMoreResults = "There are no more results returned by the query.";
|
||||
$errorNoFields = "The active result for the query contains no fields.";
|
||||
$errorNoMoreRows = "There are no more rows in the active result set. Since this result set is not scrollable, no more data may be retrieved.";
|
||||
|
||||
// This function compares the expected error message and the error returned by errorInfo().
|
||||
function CheckError($stmt, $expectedError=NULL)
|
||||
|
@ -94,6 +95,7 @@ echo "Empty result set, call fetch first: ##################################\n";
|
|||
|
||||
$stmt = $conn->query("TestEmptySetProc @a='a', @b='w'");
|
||||
Fetch($stmt);
|
||||
Fetch($stmt, $errorNoMoreRows);
|
||||
NextResult($stmt);
|
||||
Fetch($stmt);
|
||||
NextResult($stmt, $errorNoMoreResults);
|
||||
|
@ -158,6 +160,7 @@ Next result...
|
|||
Next result...
|
||||
Empty result set, call fetch first: ##################################
|
||||
Fetch...
|
||||
Fetch...
|
||||
Next result...
|
||||
Fetch...
|
||||
Next result...
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
--TEST--
|
||||
Test fetching invalid UTF-16 from the server
|
||||
--DESCRIPTION--
|
||||
This is similar to sqlsrv 0079.phpt with checking for error conditions concerning encoding issues.
|
||||
--SKIPIF--
|
||||
<?php require('skipif_mid-refactor.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
try {
|
||||
$conn = connect();
|
||||
|
||||
// The following is required or else the insertion would have failed because the input
|
||||
// was invalid
|
||||
$conn->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_SYSTEM);
|
||||
|
||||
// Create test table
|
||||
$tableName = 'pdoUTF16invalid';
|
||||
$columns = array(new ColumnMeta('int', 'id', 'identity'),
|
||||
new ColumnMeta('nvarchar(100)', 'c1'));
|
||||
$stmt = createTable($conn, $tableName, $columns);
|
||||
|
||||
// 0xdc00,0xdbff is an invalid surrogate pair
|
||||
$invalidUTF16 = pack("H*", '410042004300440000DCFFDB45004600');
|
||||
|
||||
$insertSql = "INSERT INTO $tableName (c1) VALUES (?)";
|
||||
$stmt = $conn->prepare($insertSql);
|
||||
$stmt->bindParam(1, $invalidUTF16, PDO::PARAM_STR, null, PDO::SQLSRV_ENCODING_BINARY);
|
||||
$stmt->execute();
|
||||
|
||||
try {
|
||||
// Now fetch data with UTF-8 encoding
|
||||
$tsql = "SELECT * FROM $tableName";
|
||||
$stmt = $conn->prepare($tsql);
|
||||
$stmt->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_UTF8);
|
||||
$stmt->execute();
|
||||
$utf8 = $stmt->fetchColumn(1); // Ignore the id column
|
||||
echo "fetchColumn should have failed with an error.\n";
|
||||
} catch (PDOException $e) {
|
||||
$error = '*An error occurred translating string for a field to UTF-8:*';
|
||||
if ($e->getCode() !== "IMSSP" || !fnmatch($error, $e->getMessage())) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
dropProc($conn, 'Utf16InvalidOut');
|
||||
$createProc = <<<PROC
|
||||
CREATE PROCEDURE Utf16InvalidOut
|
||||
@param nvarchar(25) OUTPUT
|
||||
AS
|
||||
BEGIN
|
||||
set @param = convert(nvarchar(25), 0x410042004300440000DCFFDB45004600);
|
||||
END;
|
||||
PROC;
|
||||
|
||||
$conn->query($createProc);
|
||||
|
||||
try {
|
||||
$invalidUTF16Out = '';
|
||||
$tsql = '{call Utf16InvalidOut(?)}';
|
||||
$stmt = $conn->prepare($tsql);
|
||||
$stmt->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_UTF8);
|
||||
$stmt->bindParam(1, $invalidUTF16Out, PDO::PARAM_STR, 25);
|
||||
$stmt->execute();
|
||||
} catch (PDOException $e) {
|
||||
$error = '*An error occurred translating string for an output param to UTF-8:*';
|
||||
if ($e->getCode() !== "IMSSP" || !fnmatch($error, $e->getMessage())) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
// Done testing with the stored procedure and test table
|
||||
dropProc($conn, 'Utf16InvalidOut');
|
||||
dropTable($conn, $tableName);
|
||||
|
||||
unset($stmt);
|
||||
unset($conn);
|
||||
} catch (PDOException $e) {
|
||||
var_dump($e->errorInfo);
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
106
test/functional/pdo_sqlsrv/pdo_insert_fetch_utf8stream.phpt
Normal file
106
test/functional/pdo_sqlsrv/pdo_insert_fetch_utf8stream.phpt
Normal file
|
@ -0,0 +1,106 @@
|
|||
--TEST--
|
||||
Test inserting UTF-8 stream via PHP including some checking of error conditions
|
||||
--DESCRIPTION--
|
||||
This is similar to sqlsrv 0067.phpt with checking for error conditions concerning encoding issues.
|
||||
--SKIPIF--
|
||||
<?php require('skipif_mid-refactor.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
try {
|
||||
$conn = connect();
|
||||
|
||||
// Create test table
|
||||
$tableName = 'pdoUTF8stream';
|
||||
$columns = array(new ColumnMeta('tinyint', 'c1'),
|
||||
new ColumnMeta('char(10)', 'c2'),
|
||||
new ColumnMeta('float', 'c3'),
|
||||
new ColumnMeta('varchar(max)', 'c4'));
|
||||
$stmt = createTable($conn, $tableName, $columns);
|
||||
|
||||
$f1 = 1;
|
||||
$f2 = "testtestte";
|
||||
$f3 = 12.0;
|
||||
$f4 = fopen("data://text/plain,This%20is%20some%20text%20meant%20to%20test%20binding%20parameters%20to%20streams", "r");
|
||||
|
||||
$insertSql = "INSERT INTO $tableName (c1, c2, c3, c4) VALUES (?, ?, ?, ?)";
|
||||
$stmt = $conn->prepare($insertSql);
|
||||
$stmt->bindParam(1, $f1);
|
||||
$stmt->bindParam(2, $f2);
|
||||
$stmt->bindParam(3, $f3);
|
||||
$stmt->bindParam(4, $f4, PDO::PARAM_LOB);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
// Next test UTF-8 cutoff in the middle of a valid 3 byte UTF-8 char
|
||||
$utf8 = str_repeat("41", 8188);
|
||||
$utf8 = $utf8 . "e38395";
|
||||
$utf8 = pack("H*", $utf8);
|
||||
$f4 = fopen("data://text/plain," . $utf8, "r");
|
||||
$stmt->bindParam(4, $f4, PDO::PARAM_LOB);
|
||||
$stmt->execute();
|
||||
|
||||
// Now test a 2 byte incomplete character
|
||||
$utf8 = str_repeat("41", 8188);
|
||||
$utf8 = $utf8 . "dfa0";
|
||||
$utf8 = pack("H*", $utf8);
|
||||
$f4 = fopen("data://text/plain," . $utf8, "r");
|
||||
$stmt->bindParam(4, $f4, PDO::PARAM_LOB);
|
||||
$stmt->execute();
|
||||
|
||||
// Then test a 4 byte incomplete character
|
||||
$utf8 = str_repeat("41", 8186);
|
||||
$utf8 = $utf8 . "f1a680bf";
|
||||
$utf8 = pack("H*", $utf8);
|
||||
$f4 = fopen("data://text/plain," . $utf8, "r");
|
||||
$stmt->bindParam(4, $f4, PDO::PARAM_LOB);
|
||||
$stmt->execute();
|
||||
|
||||
// Finally, verify error conditions with invalid inputs
|
||||
$error = '*An error occurred translating a PHP stream from UTF-8 to UTF-16:*';
|
||||
|
||||
// First test UTF-8 cutoff (really cutoff)
|
||||
$utf8 = str_repeat("41", 8188);
|
||||
$utf8 = $utf8 . "e383";
|
||||
$utf8 = pack("H*", $utf8);
|
||||
$f4 = fopen("data://text/plain," . $utf8, "r");
|
||||
try {
|
||||
$stmt->bindParam(4, $f4, PDO::PARAM_LOB);
|
||||
$stmt->execute();
|
||||
echo "Should have failed with a cutoff UTF-8 string\n";
|
||||
} catch (PDOException $e) {
|
||||
if ($e->getCode() !== "IMSSP" || !fnmatch($error, $e->getMessage())) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Then test UTF-8 invalid/corrupt stream
|
||||
$utf8 = str_repeat("41", 8188);
|
||||
$utf8 = $utf8 . "e38395e38395";
|
||||
$utf8 = substr_replace($utf8, "fe", 1000, 2);
|
||||
$utf8 = pack("H*", $utf8);
|
||||
$f4 = fopen("data://text/plain," . $utf8, "r");
|
||||
try {
|
||||
$stmt->bindParam(4, $f4, PDO::PARAM_LOB);
|
||||
$stmt->execute();
|
||||
echo "Should have failed with an invalid UTF-8 string\n";
|
||||
} catch (PDOException $e) {
|
||||
if ($e->getCode() !== "IMSSP" || !fnmatch($error, $e->getMessage())) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
// Done testing with stored procedures and table
|
||||
dropTable($conn, $tableName);
|
||||
|
||||
unset($stmt);
|
||||
unset($conn);
|
||||
} catch (PDOException $e) {
|
||||
var_dump($e->errorInfo);
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
233
test/functional/pdo_sqlsrv/pdo_insert_fetch_utf8text.phpt
Normal file
233
test/functional/pdo_sqlsrv/pdo_insert_fetch_utf8text.phpt
Normal file
|
@ -0,0 +1,233 @@
|
|||
--TEST--
|
||||
Test inserting and retrieving UTF-8 text
|
||||
--DESCRIPTION--
|
||||
This is similar to sqlsrv 0065.phpt with checking for error conditions concerning encoding issues.
|
||||
--SKIPIF--
|
||||
<?php require('skipif_mid-refactor.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
function verifyColumnData($columns, $results, $utf8)
|
||||
{
|
||||
for ($i = 0; $i < count($columns); $i++) {
|
||||
if ($i > 0) {
|
||||
if ($results[$i] !== $utf8) {
|
||||
echo $columns[$i]->colName . ' does not match the inserted UTF-8 text';
|
||||
var_dump($results[$i]);
|
||||
}
|
||||
} else {
|
||||
// The first column, a varchar(100) column, should have question marks,
|
||||
// like this one:
|
||||
$expected = "So?e sä???? ?SCII-te×t";
|
||||
// With AE, the fetched result may be different in Windows and other
|
||||
// platforms -- the point is to check if there are some '?'
|
||||
if (!isAEConnected() && $results[$i] !== $expected) {
|
||||
echo $columns[$i]->colName . " does not match $expected";
|
||||
var_dump($results[$i]);
|
||||
} else {
|
||||
$arr = explode('?', $results[$i]);
|
||||
if (count($arr) == 1) {
|
||||
// this means there is no question mark in $t
|
||||
echo $columns[$i]->colName . " value is unexpected";
|
||||
var_dump($results[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dropProcedures($conn)
|
||||
{
|
||||
// Drop all procedures
|
||||
dropProc($conn, "pdoIntDoubleProc");
|
||||
dropProc($conn, "pdoUTF8OutProc");
|
||||
dropProc($conn, "pdoUTF8OutWithResultsetProc");
|
||||
dropProc($conn, "pdoUTF8InOutProc");
|
||||
}
|
||||
|
||||
function createProcedures($conn, $tableName)
|
||||
{
|
||||
// Drop all procedures first
|
||||
dropProcedures($conn);
|
||||
|
||||
$createProc = <<<PROC
|
||||
CREATE PROCEDURE pdoUTF8OutProc
|
||||
@param nvarchar(25) OUTPUT
|
||||
AS
|
||||
BEGIN
|
||||
set @param = convert(nvarchar(25), 0x5E01A1013C04170120005B01E400DD1040044001C11E200086035A010801280130012D0065012E21D7006701);
|
||||
END;
|
||||
PROC;
|
||||
$stmt = $conn->query($createProc);
|
||||
|
||||
$createProc = "CREATE PROCEDURE pdoUTF8OutWithResultsetProc @param NVARCHAR(25) OUTPUT AS BEGIN SELECT c1, c2, c3 FROM $tableName SET @param = CONVERT(NVARCHAR(25), 0x5E01A1013C04170120005B01E400DD1040044001C11E200086035A010801280130012D0065012E21D7006701); END";
|
||||
$stmt = $conn->query($createProc);
|
||||
|
||||
$createProc = "CREATE PROCEDURE pdoUTF8InOutProc @param NVARCHAR(25) OUTPUT AS BEGIN SET @param = CONVERT(NVARCHAR(25), 0x6001E11EDD10130120006101E200DD1040043A01BB1E2000C5005A01C700CF0007042D006501BF1E45046301); END";
|
||||
$stmt = $conn->query($createProc);
|
||||
|
||||
$createProc = "CREATE PROCEDURE pdoIntDoubleProc @param INT OUTPUT AS BEGIN SET @param = @param + @param; END;";
|
||||
$stmt = $conn->query($createProc);
|
||||
}
|
||||
|
||||
function runBaselineProc($conn)
|
||||
{
|
||||
$sql = "{call pdoIntDoubleProc(?)}";
|
||||
$val = 1;
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bindParam(1, $val, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, 100);
|
||||
$stmt->execute();
|
||||
|
||||
if ($val !== 2) {
|
||||
echo "Incorrect value $val for pdoIntDoubleProc\n";
|
||||
}
|
||||
}
|
||||
|
||||
function runImmediateConversion($conn, $utf8)
|
||||
{
|
||||
$sql = "{call pdoUTF8OutProc(?)}";
|
||||
$val = '';
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bindParam(1, $val, PDO::PARAM_STR, 50);
|
||||
$stmt->execute();
|
||||
|
||||
if ($val !== $utf8) {
|
||||
echo "Incorrect value $val for pdoUTF8OutProc\n";
|
||||
}
|
||||
}
|
||||
|
||||
function runProcWithResultset($conn, $utf8)
|
||||
{
|
||||
$sql = "{call pdoUTF8OutWithResultsetProc(?)}";
|
||||
$val = '';
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bindParam(1, $val, PDO::PARAM_STR, 50);
|
||||
$stmt->execute();
|
||||
|
||||
// Moves the cursor to the next result set
|
||||
$stmt->nextRowset();
|
||||
|
||||
if ($val !== $utf8) {
|
||||
echo "Incorrect value $val for pdoUTF8OutWithResultsetProc\n";
|
||||
}
|
||||
}
|
||||
|
||||
function runInOutProcWithErrors($conn, $utf8_2)
|
||||
{
|
||||
// The input string is smaller than the output size for testing
|
||||
$val = 'This is a test.';
|
||||
|
||||
// The following should work
|
||||
$sql = "{call pdoUTF8InOutProc(?)}";
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bindParam(1, $val, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 25);
|
||||
$stmt->execute();
|
||||
|
||||
if ($val !== $utf8_2) {
|
||||
echo "Incorrect value $val for pdoUTF8InOutProc Part 1\n";
|
||||
}
|
||||
|
||||
// Use a much longer input string
|
||||
$val = 'This is a longer test that exceeds the returned values buffer size so that we can test an input buffer size larger than the output buffer size.';
|
||||
try {
|
||||
$stmt->bindParam(1, $val, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 25);
|
||||
$stmt->execute();
|
||||
echo "Should have failed since the string is too long!\n";
|
||||
} catch (PDOException $e) {
|
||||
$error = '*String data, right truncation';
|
||||
if ($e->getCode() !== "22001" || !fnmatch($error, $e->getMessage())) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runIntDoubleProcWithErrors($conn)
|
||||
{
|
||||
$sql = "{call pdoIntDoubleProc(?)}";
|
||||
$val = pack('H*', 'ffffffff');
|
||||
|
||||
try {
|
||||
$stmt = $conn->prepare($sql);
|
||||
$stmt->bindParam(1, $val, PDO::PARAM_STR);
|
||||
$stmt->execute();
|
||||
echo "Should have failed because of an invalid utf-8 string!\n";
|
||||
} catch (PDOException $e) {
|
||||
$error = '*An error occurred translating string for input param 1 to UCS-2:*';
|
||||
if ($e->getCode() !== "IMSSP" || !fnmatch($error, $e->getMessage())) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$conn = connect();
|
||||
|
||||
// Create test table
|
||||
$tableName = 'pdoUTF8test';
|
||||
$columns = array(new ColumnMeta('varchar(100)', 'c1'),
|
||||
new ColumnMeta('nvarchar(100)', 'c2'),
|
||||
new ColumnMeta('nvarchar(max)', 'c3'));
|
||||
$stmt = createTable($conn, $tableName, $columns);
|
||||
|
||||
$utf8 = "Şơмė śäოрŀề ΆŚĈĨİ-ť℮×ŧ";
|
||||
|
||||
$insertSql = "INSERT INTO $tableName (c1, c2, c3) VALUES (?, ?, ?)";
|
||||
$stmt1 = $conn->prepare($insertSql);
|
||||
$stmt1->bindParam(1, $utf8);
|
||||
$stmt1->bindParam(2, $utf8);
|
||||
$stmt1->bindParam(3, $utf8);
|
||||
|
||||
$stmt1->execute();
|
||||
|
||||
$stmt2 = $conn->prepare("SELECT c1, c2, c3 FROM $tableName");
|
||||
$stmt2->execute();
|
||||
$results = $stmt2->fetch(PDO::FETCH_NUM);
|
||||
verifyColumnData($columns, $results, $utf8);
|
||||
|
||||
// Start creating stored procedures for testing
|
||||
createProcedures($conn, $tableName);
|
||||
|
||||
runBaselineProc($conn);
|
||||
runImmediateConversion($conn, $utf8);
|
||||
runProcWithResultset($conn, $utf8);
|
||||
|
||||
// Use another set of UTF-8 text to test
|
||||
$utf8_2 = "Šỡოē šâოрĺẻ ÅŚÇÏЇ-ťếхţ";
|
||||
runInOutProcWithErrors($conn, $utf8_2);
|
||||
|
||||
// Now insert second row
|
||||
$utf8_3 = pack('H*', '7a61cc86c7bdceb2f18fb3bf');
|
||||
$stmt1->bindParam(1, $utf8_3);
|
||||
$stmt1->bindParam(2, $utf8_3);
|
||||
$stmt1->bindParam(3, $utf8_3);
|
||||
$stmt1->execute();
|
||||
|
||||
// Fetch data, ignoring first row
|
||||
$stmt2->execute();
|
||||
$stmt2->fetch(PDO::FETCH_NUM);
|
||||
|
||||
// Move to the second row and check second field
|
||||
$results2 = $stmt2->fetch(PDO::FETCH_NUM);
|
||||
if ($results2[1] !== $utf8_3) {
|
||||
echo "Unexpected $results2[1] from field 2 in second row.\n";
|
||||
}
|
||||
|
||||
// Last test with an invalid input
|
||||
runIntDoubleProcWithErrors($conn);
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
// Done testing with stored procedures and table
|
||||
dropProcedures($conn);
|
||||
dropTable($conn, $tableName);
|
||||
|
||||
unset($stmt1);
|
||||
unset($stmt2);
|
||||
unset($conn);
|
||||
} catch (PDOException $e) {
|
||||
var_dump($e->errorInfo);
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
Done
|
107
test/functional/pdo_sqlsrv/pdo_warning_errors.phpt
Normal file
107
test/functional/pdo_sqlsrv/pdo_warning_errors.phpt
Normal file
|
@ -0,0 +1,107 @@
|
|||
--TEST--
|
||||
Test various scenarios which all return the same error about statement not executed
|
||||
--DESCRIPTION--
|
||||
This is similar to sqlsrv test_warning_errors2.phpt with checking for error conditions concerning fetching and metadata.
|
||||
--SKIPIF--
|
||||
<?php require('skipif_mid-refactor.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
require_once("MsCommon_mid-refactor.inc");
|
||||
|
||||
$execError = '*The statement must be executed before results can be retrieved.';
|
||||
$noMoreResult = '*There are no more results returned by the query.';
|
||||
|
||||
function getNextResult($stmt, $error = null)
|
||||
{
|
||||
try {
|
||||
$result = $stmt->nextRowset();
|
||||
if (!is_null($error)) {
|
||||
echo "getNextResult: expect this to fail with an error from the driver\n";
|
||||
} elseif ($result !== false) {
|
||||
echo "getNextResult: expect this to simply return false\n";
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
if ($e->getCode() !== "IMSSP" || !fnmatch($error, $e->getMessage())) {
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$conn = connect();
|
||||
|
||||
$tsql = 'SELECT name FROM sys.objects';
|
||||
$stmt = $conn->prepare($tsql);
|
||||
|
||||
$colCount = $stmt->columnCount();
|
||||
if ($colCount != 0) {
|
||||
echo "Before execute(), result set should only have 0 columns\n";
|
||||
}
|
||||
$metadata = $stmt->getColumnMeta(0);
|
||||
if ($metadata !== false) {
|
||||
echo "Before execute(), result set is empty so getColumnMeta should have failed\n";
|
||||
}
|
||||
|
||||
// When fetching, PDO checks if statement is executed before passing the
|
||||
// control to the driver, so it simply fails without error message
|
||||
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($result !== false) {
|
||||
echo "Before execute(), fetch should have failed\n";
|
||||
}
|
||||
|
||||
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
var_dump($result);
|
||||
|
||||
$result = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
|
||||
var_dump($result);
|
||||
|
||||
getNextResult($stmt, $execError);
|
||||
|
||||
// Now, call execute()
|
||||
$stmt->execute();
|
||||
|
||||
$colCount = $stmt->columnCount();
|
||||
if ($colCount != 1) {
|
||||
echo "Expected only one column\n";
|
||||
}
|
||||
|
||||
$metadata = $stmt->getColumnMeta(0);
|
||||
if ($metadata['native_type'] !== 'string') {
|
||||
echo "The metadata returned is unexpected: \n";
|
||||
var_dump($metadata);
|
||||
}
|
||||
|
||||
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!is_array($result) && count($result) == 0) {
|
||||
echo "After execute(), fetch should have returned an array with results\n";
|
||||
}
|
||||
|
||||
$result = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);
|
||||
if (!is_array($result) && count($result) == 0) {
|
||||
echo "After execute(), fetchAll should have returned an array with results\n";
|
||||
}
|
||||
|
||||
getNextResult($stmt);
|
||||
|
||||
getNextResult($stmt, $noMoreResult);
|
||||
|
||||
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($result !== false) {
|
||||
// When nextRowset() fails, it resets the execute flag to false
|
||||
echo "After nextRowset failed, fetch should have failed\n";
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
|
||||
unset($stmt);
|
||||
unset($conn);
|
||||
} catch (PDOException $e) {
|
||||
var_dump($e->errorInfo);
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
array(0) {
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
Done
|
Loading…
Reference in a new issue