1--TEST-- 2MySQL PDO->__construct() - Generic + DSN 3--EXTENSIONS-- 4pdo_mysql 5--SKIPIF-- 6<?php 7require_once __DIR__ . '/inc/mysql_pdo_test.inc'; 8MySQLPDOTest::skip(); 9if (getenv('CIRCLECI')) die('xfail Broken on CicleCI'); 10?> 11--FILE-- 12<?php 13 require_once __DIR__ . '/inc/mysql_pdo_test.inc'; 14 15 function tryandcatch($offset, $code) { 16 try { 17 eval($code); 18 assert(sprintf("[%03d] Should have failed\n", $offset) != ''); 19 } catch (PDOException $e) { 20 return sprintf("[%03d] %s, [%s] %s\n", 21 $offset, 22 $e->getMessage(), 23 (isset($db) && is_object($db)) ? $db->errorCode() : 'n/a', 24 (isset($db) && is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a'); 25 } 26 27 return ''; 28 } 29 30 try { 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 // what about long values for a valid option ... 108 // hostnames > 1024 chars break on some NIS-enabled FreeBSD... 109 $dsn = MySQLPDOTest::getDSN(array('host' => str_repeat('0123456789', 100))); 110 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 111 $tmp = $e->getMessage(); 112 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 113 printf("[018] Cannot find proper error codes: %s\n", $tmp); 114 } 115 116 if (PDO_MYSQL_TEST_PORT && (PDO_MYSQL_TEST_SOCKET == '')) { 117 // Playing with the port makes only sense if no socket gets used 118 119 $port = PDO_MYSQL_TEST_PORT; 120 // let's hope we don't hit a MySQL running on that port... 121 $invalid_port = $port * 2; 122 123 $dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port); 124 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 125 $tmp = $e->getMessage(); 126 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005')) 127 printf("[019] Cannot find proper error codes: %s\n", $tmp); 128 } 129 130 $dsn = MySQLPDOTest::getDSN(array('port' => $invalid_port), 'port=' . $port); 131 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 132 printf("[020] DSN=%s, %s\n", $dsn, $e->getMessage()); 133 } 134 135 $invalid_port = 'abc'; 136 $dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port); 137 try { 138 $db = @new PDO($dsn, $user, $pass); 139 // atoi('abc') = 0, 0 -> fallback to default 3306 -> may or may not fail! 140 } catch (PDOException $e) { 141 } 142 } 143 144 if (PDO_MYSQL_TEST_DB) { 145 $db = PDO_MYSQL_TEST_DB; 146 $invalid_db = 'letshopeitdoesnotexist'; 147 148 $dsn = MySQLPDOTest::getDSN(array('dbname' => $db), 'dbname=' . $invalid_db); 149 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 150 $tmp = $e->getMessage(); 151 // 1044 may occur here if running tests using a custom user that does not have access to all databases 152 if (!stristr($tmp, '42000') && !stristr($tmp, '1049') && !stristr($tmp, '1044')) 153 printf("[022] Cannot find proper error codes: %s\n", $tmp); 154 } 155 156 $dsn = MySQLPDOTest::getDSN(array('dbname' => $invalid_db), 'dbname=' . $db); 157 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 158 printf("[023] DSN=%s, %s\n", $dsn, $e->getMessage()); 159 } 160 } 161 162 if (PDO_MYSQL_TEST_SOCKET && (stristr(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_SOCKET) !== false)) { 163 $socket = PDO_MYSQL_TEST_SOCKET; 164 $invalid_socket = '/lets/hope/it/does/not/exist'; 165 166 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $socket), 'unix_socket=' . $invalid_socket); 167 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 168 $tmp = $e->getMessage(); 169 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2002')) 170 printf("[024] Cannot find proper error codes: %s\n", $tmp); 171 } 172 173 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $invalid_socket), 'unix_socket=' . $socket); 174 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 175 printf("[025] DSN=%s, %s\n", $dsn, $e->getMessage()); 176 } 177 } 178 179 $have_charset_support = false; 180 $dsn = MySQLPDOTest::getDSN(); 181 try { 182 $db = new PDO($dsn, $user, $pass); 183 $stmt = $db->query('SELECT VERSION() as _version'); 184 $version = $stmt->fetch(PDO::FETCH_ASSOC); 185 186 $tmp = explode('.', $version['_version']); 187 if ((count($tmp) == 3) && 188 (($tmp[0] >= 4 && $tmp[1] >= 1) || ($tmp[0] >= 5))) { 189 // MySQL Server 4.1 - charset support available 190 $have_charset_support = true; 191 } 192 193 } catch (PDOException $e) { 194 printf("[026] DSN=%s, %s\n", $dsn, $e->getMessage()); 195 } 196 197 if (PDO_MYSQL_TEST_CHARSET) { 198 $charset = PDO_MYSQL_TEST_CHARSET; 199 $invalid_charset = 'invalid'; 200 201 if ($have_charset_support) { 202 $dsn = MySQLPDOTest::getDSN(); 203 $db = new PDO($dsn, $user, $pass); 204 $stmt = $db->query(sprintf('SHOW CHARACTER SET LIKE "%s"', $charset)); 205 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 206 $have_charset = (empty($tmp)) ? false : true; 207 208 if ($have_charset) { 209 $dsn = MySQLPDOTest::getDSN(array('charset' => $charset), 'charset=' . $invalid_charset); 210 try { 211 $db = @new PDO($dsn, $user, $pass); 212 /* NOTE: MySQL does a fallback to the charset suggested during the handshake - no error - no bug! */ 213 } catch (PDOException $e) { 214 $tmp = $e->getMessage(); 215 /* TODO: add proper codes */ 216 if (!stristr($tmp, 'sqlstatecode') || !stristr($tmp, 'mysqlinternalerrcode')) 217 printf("[027] TODO - Cannot find proper error codes: %s\n", $tmp); 218 } 219 220 $dsn = MySQLPDOTest::getDSN(array('charset' => $invalid_charset), 'charset=' . $charset); 221 try { 222 $db = @new PDO($dsn, $user, $pass); 223 /* Strictly speaking we should test more: character_set_client, character_set_results, and character_set_connection */ 224 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 225 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 226 if ($tmp['_charset'] != $charset) 227 printf("[028] Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 228 $tmp['_charset'], $charset); 229 } catch (PDOException $e) { 230 printf("[029] DSN=%s, %s\n", $dsn, $e->getMessage()); 231 } 232 } else { 233 printf("[030] You're trying to run the tests with charset '%s' which seems not supported by the server!", $charset); 234 } 235 } 236 } 237 238 if ($have_charset_support) { 239 // In case the PDO_MYSQL_TEST_CHARSET interferes with any defaults 240 // we do another test to verify that the charset has been set. 241 $dsn = MySQLPDOTest::getDSN(); 242 $db = new PDO($dsn, $user, $pass); 243 $stmt = $db->query('SHOW CHARACTER SET LIKE "latin1"'); 244 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 245 $have_latin1 =(empty($tmp)) ? false : true; 246 $stmt = $db->query('SHOW CHARACTER SET LIKE "latin2"'); 247 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 248 $have_latin2 =(empty($tmp)) ? false : true; 249 250 if ($have_latin1 && $have_latin2) { 251 // very likely we do have both of them... 252 try { 253 $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin1')); 254 $db = new PDO($dsn, $user, $pass); 255 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 256 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 257 if ($tmp['_charset'] != 'latin1') 258 printf("[031] DSN = %s, Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 259 $dsn, $tmp['_charset'], 'latin1'); 260 261 } catch (PDOException $e) { 262 printf("[032] %s\n", $e->getMessage()); 263 } 264 265 try { 266 $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin2')); 267 $db = new PDO($dsn, $user, $pass); 268 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 269 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 270 if ($tmp['_charset'] != 'latin2') 271 printf("[033] DSN = %s, character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 272 $dsn, $tmp['_charset'], 'latin2'); 273 274 } catch (PDOException $e) { 275 printf("[034] %s\n", $e->getMessage()); 276 } 277 } 278 } 279 } catch (PDOException $e) { 280 printf("[001] %s, [%s] %s\n", 281 $e->getMessage(), 282 (is_object($db)) ? $db->errorCode() : 'n/a', 283 (is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a'); 284 } 285 286 print "done!"; 287?> 288--EXPECTF-- 289[002] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 290[003] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 291[004] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 292[005] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 293[006] PDO::__construct(): Argument #1 ($dsn) must be a valid data source name, [n/a] n/a 294[007] could not find driver, [n/a] n/a 295[009] SQLSTATE[%s] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a 296[017] DSN=%s, SQLSTATE[%s] [%d] %s 297done! 298