1--TEST-- 2MySQL PDO->__construct() - Generic + DSN 3--SKIPIF-- 4<?php 5require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc'); 6require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); 7MySQLPDOTest::skip(); 8?> 9--FILE-- 10<?php 11 require_once(dirname(__FILE__) . 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 if (!stristr($tmp, '42000') && !stristr($tmp, '1049')) 154 printf("[022] Cannot find proper error codes: %s\n", $tmp); 155 } 156 157 $dsn = MySQLPDOTest::getDSN(array('dbname' => $invalid_db), 'dbname=' . $db); 158 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 159 printf("[023] DSN=%s, %s\n", $dsn, $e->getMessage()); 160 } 161 162 } 163 164 if (PDO_MYSQL_TEST_SOCKET && (stristr(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_SOCKET) !== false)) { 165 $socket = PDO_MYSQL_TEST_SOCKET; 166 $invalid_socket = '/lets/hope/it/does/not/exist'; 167 168 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $socket), 'unix_socket=' . $invalid_socket); 169 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 170 $tmp = $e->getMessage(); 171 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2002')) 172 printf("[024] Cannot find proper error codes: %s\n", $tmp); 173 } 174 175 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $invalid_socket), 'unix_socket=' . $socket); 176 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 177 printf("[025] DSN=%s, %s\n", $dsn, $e->getMessage()); 178 } 179 180 } 181 182 $have_charset_support = false; 183 $dsn = MySQLPDOTest::getDSN(); 184 try { 185 $db = new PDO($dsn, $user, $pass); 186 $stmt = $db->query('SELECT VERSION() as _version'); 187 $version = $stmt->fetch(PDO::FETCH_ASSOC); 188 189 $tmp = explode('.', $version['_version']); 190 if ((count($tmp) == 3) && 191 (($tmp[0] >= 4 && $tmp[1] >= 1) || ($tmp[0] >= 5))) { 192 // MySQL Server 4.1 - charset support available 193 $have_charset_support = true; 194 } 195 196 } catch (PDOException $e) { 197 printf("[026] DSN=%s, %s\n", $dsn, $e->getMessage()); 198 } 199 200 if (PDO_MYSQL_TEST_CHARSET) { 201 $charset = PDO_MYSQL_TEST_CHARSET; 202 $invalid_charset = 'invalid'; 203 204 if ($have_charset_support) { 205 $dsn = MySQLPDOTest::getDSN(); 206 $db = new PDO($dsn, $user, $pass); 207 $stmt = $db->query(sprintf('SHOW CHARACTER SET LIKE "%s"', $charset)); 208 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 209 $have_charset = (empty($tmp)) ? false : true; 210 211 if ($have_charset) { 212 $dsn = MySQLPDOTest::getDSN(array('charset' => $charset), 'charset=' . $invalid_charset); 213 try { 214 $db = @new PDO($dsn, $user, $pass); 215 /* NOTE: MySQL does a fallback to the charset suggested during the handshake - no error - no bug! */ 216 } catch (PDOException $e) { 217 $tmp = $e->getMessage(); 218 /* TODO: add proper codes */ 219 if (!stristr($tmp, 'sqlstatecode') || !stristr($tmp, 'mysqlinternalerrcode')) 220 printf("[027] TODO - Cannot find proper error codes: %s\n", $tmp); 221 } 222 223 $dsn = MySQLPDOTest::getDSN(array('charset' => $invalid_charset), 'charset=' . $charset); 224 try { 225 $db = @new PDO($dsn, $user, $pass); 226 /* Strictly speaking we should test more: character_set_client, character_set_results, and character_set_connection */ 227 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 228 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 229 if ($tmp['_charset'] != $charset) 230 printf("[028] Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 231 $tmp['_charset'], $charset); 232 } catch (PDOException $e) { 233 printf("[029] DSN=%s, %s\n", $dsn, $e->getMessage()); 234 } 235 } else { 236 printf("[030] You're trying to run the tests with charset '%s' which seems not supported by the server!", $charset); 237 } 238 239 } 240 241 } 242 243 if ($have_charset_support) { 244 // In case the PDO_MYSQL_TEST_CHARSET interferes with any defaults 245 // we do another test to verify that the charset has been set. 246 $dsn = MySQLPDOTest::getDSN(); 247 $db = new PDO($dsn, $user, $pass); 248 $stmt = $db->query('SHOW CHARACTER SET LIKE "latin1"'); 249 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 250 $have_latin1 =(empty($tmp)) ? false : true; 251 $stmt = $db->query('SHOW CHARACTER SET LIKE "latin2"'); 252 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 253 $have_latin2 =(empty($tmp)) ? false : true; 254 255 if ($have_latin1 && $have_latin2) { 256 // very likely we do have both of them... 257 try { 258 $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin1')); 259 $db = new PDO($dsn, $user, $pass); 260 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 261 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 262 if ($tmp['_charset'] != 'latin1') 263 printf("[031] DSN = %s, Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 264 $dsn, $tmp['_charset'], 'latin1'); 265 266 } catch (PDOException $e) { 267 printf("[032] %s\n", $e->getMessage()); 268 } 269 270 try { 271 $dsn = MySQLPDOTest::getDSN(array('charset' => 'latin2')); 272 $db = new PDO($dsn, $user, $pass); 273 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 274 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 275 if ($tmp['_charset'] != 'latin2') 276 printf("[033] DSN = %s, character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 277 $dsn, $tmp['_charset'], 'latin2'); 278 279 } catch (PDOException $e) { 280 printf("[034] %s\n", $e->getMessage()); 281 } 282 283 } 284 } 285 286 } catch (PDOException $e) { 287 printf("[001] %s, [%s] %s\n", 288 $e->getMessage(), 289 (is_object($db)) ? $db->errorCode() : 'n/a', 290 (is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a'); 291 } 292 293 print "done!"; 294?> 295--EXPECTF-- 296[002] invalid data source name, [n/a] n/a 297[003] invalid data source name, [n/a] n/a 298[004] invalid data source name, [n/a] n/a 299[005] invalid data source name, [n/a] n/a 300[006] invalid data source name, [n/a] n/a 301[007] could not find driver, [n/a] n/a 302[009] SQLSTATE[%s] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a 303[017] DSN=%s, SQLSTATE[%s] [%d] %s 304done! 305