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