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 if (NULL !== ($db = @new PDO())) 32 printf("[001] Too few parameters\n"); 33 34 print tryandcatch(2, '$db = new PDO(chr(0));'); 35 print tryandcatch(3, '$db = new PDO("a" . chr(0) . "b");'); 36 print tryandcatch(4, '$db = new PDO("MYSQL");'); 37 print tryandcatch(5, '$db = new PDO("mysql");'); 38 print tryandcatch(6, '$db = new PDO("mysql ");'); 39 print tryandcatch(7, '$db = new PDO("fantasyandfriends :");'); 40 41 $dsn = PDO_MYSQL_TEST_DSN; 42 // MySQL Server might accept anonymous connections, don't 43 // print anything 44 tryandcatch(8, '$db = new PDO("' . $dsn . '");'); 45 46 $user = 'dontcreatesuchauser'; 47 $pass = 'withthispassword'; 48 print tryandcatch(9, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 49 50 // should fail 51 $dsn = 'mysql:'; 52 print tryandcatch(10, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 53 54 $dsn = PDO_MYSQL_TEST_DSN; 55 $user = PDO_MYSQL_TEST_USER; 56 $pass = PDO_MYSQL_TEST_PASS; 57 // should work... 58 $db = new PDO($dsn, $user, $pass); 59 60 $dsn = 'mysql:invalid=foo'; 61 print tryandcatch(11, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 62 63 $dsn = 'mysql:' . str_repeat('howmuch=canpdoeat;', 1000); 64 print tryandcatch(12, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 65 66 $dsn = 'mysql:' . str_repeat('abcdefghij', 1024 * 10) . '=somevalue'; 67 print tryandcatch(13, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");'); 68 69 if (PDO_MYSQL_TEST_HOST) { 70 $host = PDO_MYSQL_TEST_HOST; 71 $invalid_host = $host . 'invalid'; 72 73 // last host specification should be the one used 74 $dsn = MySQLPDOTest::getDSN(array('host' => $host), 'host=' . $invalid_host); 75 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 76 $tmp = $e->getMessage(); 77 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 78 printf("[014] Cannot find proper error codes: %s\n", $tmp); 79 } 80 81 $dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host), 'host=' . $host); 82 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 83 printf("[015] DSN=%s, %s\n", $dsn, $e->getMessage()); 84 } 85 86 $invalid_host = '-' . chr(0); 87 88 $dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host)); 89 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 90 $tmp = $e->getMessage(); 91 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 92 printf("[016] Cannot find proper error codes: %s\n", $tmp); 93 } 94 95 // parsing should not get confused by chr(0) 96 $dsn = MySQLPDOTest::getDSN(array('host' => $invalid_host), 'host=' . $host); 97 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 98 printf("[017] DSN=%s, %s\n", $dsn, $e->getMessage()); 99 } 100 101 } 102 103 // what about long values for a valid option ... 104 // hostnames > 1024 chars break on some NIS-enabled FreeBSD... 105 $dsn = MySQLPDOTest::getDSN(array('host' => str_repeat('0123456789', 100))); 106 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 107 $tmp = $e->getMessage(); 108 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005') && !stristr($tmp, '2002')) 109 printf("[018] Cannot find proper error codes: %s\n", $tmp); 110 } 111 112 if (PDO_MYSQL_TEST_PORT && (PDO_MYSQL_TEST_SOCKET == '')) { 113 // Playing with the port makes only sense if no socket gets used 114 115 $port = PDO_MYSQL_TEST_PORT; 116 // let's hope we don't hit a MySQL running on that port... 117 $invalid_port = $port * 2; 118 119 $dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port); 120 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 121 $tmp = $e->getMessage(); 122 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2005')) 123 printf("[019] Cannot find proper error codes: %s\n", $tmp); 124 } 125 126 $dsn = MySQLPDOTest::getDSN(array('port' => $invalid_port), 'port=' . $port); 127 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 128 printf("[020] DSN=%s, %s\n", $dsn, $e->getMessage()); 129 } 130 131 $invalid_port = 'abc'; 132 $dsn = MySQLPDOTest::getDSN(array('port' => $port), 'port=' . $invalid_port); 133 try { 134 $db = @new PDO($dsn, $user, $pass); 135 // atoi('abc') = 0, 0 -> fallback to default 3306 -> may or may not fail! 136 } catch (PDOException $e) { 137 } 138 139 } 140 141 if (PDO_MYSQL_TEST_DB) { 142 $db = PDO_MYSQL_TEST_DB; 143 $invalid_db = 'letshopeitdoesnotexist'; 144 145 $dsn = MySQLPDOTest::getDSN(array('dbname' => $db), 'dbname=' . $invalid_db); 146 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 147 $tmp = $e->getMessage(); 148 if (!stristr($tmp, '42000') && !stristr($tmp, '1049')) 149 printf("[022] Cannot find proper error codes: %s\n", $tmp); 150 } 151 152 $dsn = MySQLPDOTest::getDSN(array('dbname' => $invalid_db), 'dbname=' . $db); 153 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 154 printf("[023] DSN=%s, %s\n", $dsn, $e->getMessage()); 155 } 156 157 } 158 159 if (PDO_MYSQL_TEST_SOCKET && (stristr(PDO_MYSQL_TEST_DSN, PDO_MYSQL_TEST_SOCKET) !== false)) { 160 $socket = PDO_MYSQL_TEST_SOCKET; 161 $invalid_socket = '/lets/hope/it/does/not/exist'; 162 163 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $socket), 'unix_socket=' . $invalid_socket); 164 try { $db = @new PDO($dsn, $user, $pass); assert(false); printf("%s\n", $dsn); } catch (PDOException $e) { 165 $tmp = $e->getMessage(); 166 if (!stristr($tmp, 'HY000') && !stristr($tmp, '2002')) 167 printf("[024] Cannot find proper error codes: %s\n", $tmp); 168 } 169 170 $dsn = MySQLPDOTest::getDSN(array('unix_socket' => $invalid_socket), 'unix_socket=' . $socket); 171 try { $db = @new PDO($dsn, $user, $pass); } catch (PDOException $e) { 172 printf("[025] DSN=%s, %s\n", $dsn, $e->getMessage()); 173 } 174 175 } 176 177 $have_charset_support = false; 178 $dsn = MySQLPDOTest::getDSN(); 179 try { 180 $db = new PDO($dsn, $user, $pass); 181 $stmt = $db->query('SELECT VERSION() as _version'); 182 $version = $stmt->fetch(PDO::FETCH_ASSOC); 183 184 $tmp = explode('.', $version['_version']); 185 if ((count($tmp) == 3) && 186 (($tmp[0] >= 4 && $tmp[1] >= 1) || ($tmp[0] >= 5))) { 187 // MySQL Server 4.1 - charset support available 188 $have_charset_support = true; 189 } 190 191 } catch (PDOException $e) { 192 printf("[026] DSN=%s, %s\n", $dsn, $e->getMessage()); 193 } 194 195 if (PDO_MYSQL_TEST_CHARSET) { 196 $charset = PDO_MYSQL_TEST_CHARSET; 197 $invalid_charset = 'invalid'; 198 199 if ($have_charset_support) { 200 $dsn = MySQLPDOTest::getDSN(); 201 $db = new PDO($dsn, $user, $pass); 202 $stmt = $db->query(sprintf('SHOW CHARACTER SET LIKE "%s"', $charset)); 203 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 204 $have_charset = (empty($tmp)) ? false : true; 205 206 if ($have_charset) { 207 $dsn = MySQLPDOTest::getDSN(array('charset' => $charset), 'charset=' . $invalid_charset); 208 try { 209 $db = @new PDO($dsn, $user, $pass); 210 /* NOTE: MySQL does a fallback to the charset suggested during the handshake - no error - no bug! */ 211 } catch (PDOException $e) { 212 $tmp = $e->getMessage(); 213 /* TODO: add proper codes */ 214 if (!stristr($tmp, 'sqlstatecode') || !stristr($tmp, 'mysqlinternalerrcode')) 215 printf("[027] TODO - Cannot find proper error codes: %s\n", $tmp); 216 } 217 218 $dsn = MySQLPDOTest::getDSN(array('charset' => $invalid_charset), 'charset=' . $charset); 219 try { 220 $db = @new PDO($dsn, $user, $pass); 221 /* Strictly speaking we should test more: character_set_client, character_set_results, and character_set_connection */ 222 $stmt = $db->query('SELECT @@character_set_connection AS _charset'); 223 $tmp = $stmt->fetch(PDO::FETCH_ASSOC); 224 if ($tmp['_charset'] != $charset) 225 printf("[028] Character sets has not been set, @@character_set_connection reports '%s', expecting '%s'", 226 $tmp['_charset'], $charset); 227 } catch (PDOException $e) { 228 printf("[029] DSN=%s, %s\n", $dsn, $e->getMessage()); 229 } 230 } else { 231 printf("[030] You're trying to run the tests with charset '%s' which seems not supported by the server!", $charset); 232 } 233 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 } 280 281 } catch (PDOException $e) { 282 printf("[001] %s, [%s] %s\n", 283 $e->getMessage(), 284 (is_object($db)) ? $db->errorCode() : 'n/a', 285 (is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a'); 286 } 287 288 print "done!"; 289?> 290--EXPECTF-- 291[002] invalid data source name, [n/a] n/a 292[003] invalid data source name, [n/a] n/a 293[004] invalid data source name, [n/a] n/a 294[005] invalid data source name, [n/a] n/a 295[006] invalid data source name, [n/a] n/a 296[007] could not find driver, [n/a] n/a 297[009] SQLSTATE[%s] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a 298[010] SQLSTATE[%s] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a 299[017] DSN=%s, SQLSTATE[%s] [%d] %s 300[033] DSN = mysql:%s, character sets has not been set, @@character_set_connection reports 'latin1', expecting 'latin2'done! 301