-
Notifications
You must be signed in to change notification settings - Fork 375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new pdo_sqlsrv tests for utf8 encoding errors #966
Merged
Merged
Changes from 4 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
36610c6
Add new pdo_sqlsrv tests for utf8 encoding errors
yitam 1d1363f
A new test for connection errors with invalid values
yitam 47a48ee
Modified an error message
yitam f4665ab
Allowed more possible errors in diff platforms
yitam cb000c7
Added another empty result error checking
yitam e05d061
Added one last test about fetching errors
yitam b1ebe5a
Removed the typo
yitam File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
138 changes: 138 additions & 0 deletions
138
test/functional/pdo_sqlsrv/pdo_construct_attr_errors.phpt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
--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. | ||
.phpt | ||
--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 | ||
|
86 changes: 86 additions & 0 deletions
86
test/functional/pdo_sqlsrv/pdo_insert_fetch_invalid_utf16.phpt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 changes: 106 additions & 0 deletions
106
test/functional/pdo_sqlsrv/pdo_insert_fetch_utf8stream.phpt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed something here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it was a typo... unless you have any suggestion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, just wondering if this was a typo or something else.