1--TEST-- 2MySQL PDO->__construct() - Generic + DSN 3--SKIPIF-- 4<?php 5require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc'); 6require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); 7MySQLPDOTest::skip(); 8?> 9--FILE-- 10<?php 11 require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); 12 13 function tryandcatch($offset, $code) { 14 15 try { 16 eval($code); 17 assert(sprintf("[%03d] Should have failed\n", $offset) != ''); 18 } catch (PDOException $e) { 19 return sprintf("[%03d] %s, [%s] %s\n", 20 $offset, 21 $e->getMessage(), 22 (isset($db) && is_object($db)) ? $db->errorCode() : 'n/a', 23 (isset($db) && is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a'); 24 } 25 26 return ''; 27 } 28 29 try { 30 31 try { 32 if (NULL !== ($db = @new PDO())) 33 printf("[001] Too few parameters\n"); 34 } catch (TypeError $ex) { 35 } 36 37 print tryandcatch(2, '$db = new PDO(chr(0));'); 38 print tryandcatch(3, '$db = new PDO("a" . chr(0) . "b");'); 39 print tryandcatch(4, '$db = new PDO("MYSQL");'); 40 print tryandcatch(5, '$db = new PDO("mysql");'); 41 print tryandcatch(6, '$db = new PDO("mysql ");'); 42 print tryandcatch(7, '$db = new PDO("fantasyandfriends :");'); 43 44 $dsn = PDO_MYSQL_TEST_DSN; 45 // MySQL Server might accept anonymous connections, don't 46 // print anything 47 tryandcatch(8, '$db = new PDO("' . $dsn . '");'); 48 49 $user = 'dontcreatesuchauser'; 50 $pass = 'withthispassword'; 51 print tryandcatch(9, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 52 53 // should fail 54 $dsn = 'mysql:'; 55 // don't print the message since it can be different 56 tryandcatch(10, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 57 58 $dsn = PDO_MYSQL_TEST_DSN; 59 $user = PDO_MYSQL_TEST_USER; 60 $pass = PDO_MYSQL_TEST_PASS; 61 // should work... 62 $db = new PDO($dsn, $user, $pass); 63 64 // Reaction on host not specified differs for different configs, so no printing 65 $dsn = 'mysql:invalid=foo'; 66 tryandcatch(11, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 67 68 $dsn = 'mysql:' . str_repeat('howmuch=canpdoeat;', 1000); 69 tryandcatch(12, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 70 71 $dsn = 'mysql:' . str_repeat('abcdefghij', 1024 * 10) . '=somevalue'; 72 tryandcatch(13, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 73 74 if (PDO_MYSQL_TEST_HOST) { 75 $host = PDO_MYSQL_TEST_HOST; 76 $invalid_host = $host . 'invalid'; 77 78 // last host specification should be the one used 79 $dsn = MySQLPDOTest::getDSN(array('host' => $host), 'host=' . $invalid_host); 80 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 81 $tmp = $e->getMessage(); 82 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 83 printf("[014] Cannot find proper error codes: %s\n", $tmp); 84 } 85 86 $dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host), 'host=' . $host); 87 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 88 printf("[015] DSN=%s, %s\n", $dsn, $e->getMessage()); 89 } 90 91 $invalid_host = '-' . chr(0); 92 93 $dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host)); 94 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 95 $tmp = $e->getMessage(); 96 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 97 printf("[016] Cannot find proper error codes: %s\n", $tmp); 98 } 99 100 // parsing should not get confused by chr(0) 101 $dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host), 'host=' . $host); 102 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 103 printf("[017] DSN=%s, %s\n", $dsn, $e->getMessage()); 104 } 105 106 } 107 108 // what about long values for a valid option ... 109 // hostnames > 1024 chars break on some NIS-enabled FreeBSD... 110 $dsn = MySQLPDOTest::getDSN(array('host' => str_repeat('0123456789', 100))); 111 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 112 $tmp = $e->getMessage(); 113 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 114 printf("[018] Cannot find proper error codes: %s\n", $tmp); 115 } 116 117 if (PDO_MYSQL_TEST_PORT && (PDO_MYSQL_TEST_SOCKET == '')) { 118 // Playing with the port makes only sense if no socket gets used 119 120 $port = PDO_MYSQL_TEST_PORT; 121 // let's hope we don't hit a MySQL running on that port... 122 $invalid_port = $port * 2; 123 124 $dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port); 125 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 126 $tmp = $e->getMessage(); 127 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005')) 128 printf("[019] Cannot find proper error codes: %s\n", $tmp); 129 } 130 131 $dsn = MySQLPDOTest::getDSN(array('port' => $invalid_port), 'port=' . $port); 132 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 133 printf("[020] DSN=%s, %s\n", $dsn, $e->getMessage()); 134 } 135 136 $invalid_port = 'abc'; 137 $dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port); 138 try { 139 $db = @new PDO($dsn, $user, $pass); 140 // atoi('abc') = 0, 0 -> fallback to default 3306 -> may or may not fail! 141 } catch (PDOException $e) { 142 } 143 144 } 145 146 if (PDO_MYSQL_TEST_DB) { 147 $db = PDO_MYSQL_TEST_DB; 148 $invalid_db = 'letshopeitdoesnotexist'; 149 150 $dsn = MySQLPDOTest::getDSN(array('dbname' => $db), 'dbname=' . $invalid_db); 151 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 152 $tmp = $e->getMessage(); 153 // 1044 may occur here if running tests using a custom user that does not have access to all databases 154 if (!stristr($tmp, '42000') && !stristr($tmp, '1049') && !stristr($tmp, '1044')) 155 printf("[022] Cannot find proper error codes: %s\n", $tmp); 156 } 157 158 $dsn = MySQLPDOTest::getDSN(array('dbname' => $invalid_db), 'dbname=' . $db); 159 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 160 printf("[023] DSN=%s, %s\n", $dsn, $e->getMessage()); 161 } 162 163 } 164 165 if (PDO_MYSQL_TEST_SOCKET && (stristr(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_SOCKET) !== false)) { 166 $socket = PDO_MYSQL_TEST_SOCKET; 167 $invalid_socket = '/lets/hope/it/does/not/exist'; 168 169 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $socket), 'unix_socket=' . $invalid_socket); 170 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 171 $tmp = $e->getMessage(); 172 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2002')) 173 printf("[024] Cannot find proper error codes: %s\n", $tmp); 174 } 175 176 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $invalid_socket), 'unix_socket=' . $socket); 177 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 178 printf("[025] DSN=%s, %s\n", $dsn, $e->getMessage()); 179 } 180 181 } 182 183 $have_charset_support = false; 184 $dsn = MySQLPDOTest::getDSN(); 185 try { 186 $db = new PDO($dsn, $user, $pass); 187 $stmt = $db->query('SELECT VERSION() as _version'); 188 $version = $stmt->fetch(PDO::FETCH_ASSOC); 189 190 $tmp = explode('.', $version['_version']); 191 if ((count($tmp) == 3) && 192 (($tmp[0] >= 4 && $tmp[1] >= 1) || ($tmp[0] >= 5))) { 193 // MySQL Server 4.1 - charset support available 194 $have_charset_support = true; 195 } 196 197 } catch (PDOException $e) { 198 printf("[026] DSN=%s, %s\n", $dsn, $e->getMessage()); 199 } 200 201 if (PDO_MYSQL_TEST_CHARSET) { 202 $charset = PDO_MYSQL_TEST_CHARSET; 203 $invalid_charset = 'invalid'; 204 205 if ($have_charset_support) { 206 $dsn = MySQLPDOTest::getDSN(); 207 $db = new PDO($dsn, $user, $pass); 208 $stmt = $db->query(sprintf('SHOW CHARACTER SET LIKE "%s"', $charset)); 209 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 210 $have_charset = (empty($tmp)) ? false : true; 211 212 if ($have_charset) { 213 $dsn = MySQLPDOTest::getDSN(array('charset' => $charset), 'charset=' . $invalid_charset); 214 try { 215 $db = @new PDO($dsn, $user, $pass); 216 /* NOTE: MySQL does a fallback to the charset suggested during the handshake - no error - no bug! */ 217 } catch (PDOException $e) { 218 $tmp = $e->getMessage(); 219 /* TODO: add proper codes */ 220 if (!stristr($tmp, 'sqlstatecode') || !stristr($tmp, 'mysqlinternalerrcode')) 221 printf("[027] TODO - Cannot find proper error codes: %s\n", $tmp); 222 } 223 224 $dsn = MySQLPDOTest::getDSN(array('charset' => $invalid_charset), 'charset=' . $charset); 225 try { 226 $db = @new PDO($dsn, $user, $pass); 227 /* Strictly speaking we should test more: character_set_client, character_set_results, and character_set_connection */ 228 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 229 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 230 if ($tmp['_charset'] != $charset) 231 printf("[028] Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 232 $tmp['_charset'], $charset); 233 } catch (PDOException $e) { 234 printf("[029] DSN=%s, %s\n", $dsn, $e->getMessage()); 235 } 236 } else { 237 printf("[030] You're trying to run the tests with charset '%s' which seems not supported by the server!", $charset); 238 } 239 240 } 241 242 } 243 244 if ($have_charset_support) { 245 // In case the PDO_MYSQL_TEST_CHARSET interferes with any defaults 246 // we do another test to verify that the charset has been set. 247 $dsn = MySQLPDOTest::getDSN(); 248 $db = new PDO($dsn, $user, $pass); 249 $stmt = $db->query('SHOW CHARACTER SET LIKE "latin1"'); 250 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 251 $have_latin1 =(empty($tmp)) ? false : true; 252 $stmt = $db->query('SHOW CHARACTER SET LIKE "latin2"'); 253 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 254 $have_latin2 =(empty($tmp)) ? false : true; 255 256 if ($have_latin1 && $have_latin2) { 257 // very likely we do have both of them... 258 try { 259 $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin1')); 260 $db = new PDO($dsn, $user, $pass); 261 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 262 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 263 if ($tmp['_charset'] != 'latin1') 264 printf("[031] DSN = %s, Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 265 $dsn, $tmp['_charset'], 'latin1'); 266 267 } catch (PDOException $e) { 268 printf("[032] %s\n", $e->getMessage()); 269 } 270 271 try { 272 $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin2')); 273 $db = new PDO($dsn, $user, $pass); 274 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 275 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 276 if ($tmp['_charset'] != 'latin2') 277 printf("[033] DSN = %s, character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 278 $dsn, $tmp['_charset'], 'latin2'); 279 280 } catch (PDOException $e) { 281 printf("[034] %s\n", $e->getMessage()); 282 } 283 284 } 285 } 286 287 } catch (PDOException $e) { 288 printf("[001] %s, [%s] %s\n", 289 $e->getMessage(), 290 (is_object($db)) ? $db->errorCode() : 'n/a', 291 (is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a'); 292 } 293 294 print "done!"; 295?> 296--EXPECTF-- 297[002] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 298[003] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 299[004] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 300[005] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 301[006] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 302[007] could not find driver, [n/a] n/a 303[009] SQLSTATE[%s] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a 304[017] DSN=%s, SQLSTATE[%s] [%d] %s 305done! 306