1--TEST-- 2Bug #42378 (bind_result memory exhaustion, SELECT column, FORMAT(...) AS _format) 3--SKIPIF-- 4<?php 5require_once('skipif.inc'); 6require_once('skipifconnectfailure.inc'); 7?> 8--INI-- 9memory_limit=83886080 10--FILE-- 11<?php 12 require_once("connect.inc"); 13 14 function create_table($link, $column, $min, $max, $engine, $offset) { 15 16 if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { 17 printf("[%03d] Cannot drop table test, [%d] %s\n", 18 $offset, 19 mysqli_errno($link), mysqli_error($link)); 20 return array(); 21 } 22 print "$column\n"; 23 24 $sql = sprintf("CREATE TABLE test(id INT AUTO_INCREMENT PRIMARY KEY, col1 %s) ENGINE=%s", 25 $column, $engine); 26 if (!mysqli_query($link, $sql)) { 27 printf("[%03d] Cannot create table test, [%d] %s\n", 28 $offset + 1, 29 mysqli_errno($link), mysqli_error($link)); 30 return array(); 31 } 32 33 $values = array(); 34 for ($i = 1; $i <= 100; $i++) { 35 $col1 = mt_rand($min, $max); 36 $values[$i] = $col1; 37 $sql = sprintf("INSERT INTO test(id, col1) VALUES (%d, %f)", 38 $i, $col1); 39 if (!mysqli_query($link, $sql)) { 40 printf("[%03d] Cannot insert data, [%d] %s\n", 41 $offset + 2, 42 mysqli_errno($link), mysqli_error($link)); 43 return array(); 44 } 45 } 46 47 return $values; 48 } 49 50 function test_format($link, $format, $from, $order_by, $expected, $offset) { 51 52 if (!$stmt = mysqli_stmt_init($link)) { 53 printf("[%03d] Cannot create PS, [%d] %s\n", 54 $offset, 55 mysqli_errno($link), mysqli_error($link)); 56 return false; 57 } 58 print "$format\n"; 59 60 if ($order_by) 61 $sql = sprintf('SELECT %s AS _format FROM %s ORDER BY %s', $format, $from, $order_by); 62 else 63 $sql = sprintf('SELECT %s AS _format FROM %s', $format, $from); 64 65 if (!mysqli_stmt_prepare($stmt, $sql)) { 66 printf("[%03d] Cannot prepare PS, [%d] %s\n", 67 $offset + 1, 68 mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 69 return false; 70 } 71 72 if (!mysqli_stmt_execute($stmt)) { 73 printf("[%03d] Cannot execute PS, [%d] %s\n", 74 $offset + 2, 75 mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 76 return false; 77 } 78 79 if (!mysqli_stmt_store_result($stmt)) { 80 printf("[%03d] Cannot store result set, [%d] %s\n", 81 $offset + 3, 82 mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 83 return false; 84 } 85 86 if (!is_array($expected)) { 87 88 $result = null; 89 if (!mysqli_stmt_bind_result($stmt, $result)) { 90 printf("[%03d] Cannot bind result, [%d] %s\n", 91 $offset + 4, 92 mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 93 return false; 94 } 95 96 if (!mysqli_stmt_fetch($stmt)) { 97 printf("[%03d] Cannot fetch result,, [%d] %s\n", 98 $offset + 5, 99 mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 100 return false; 101 } 102 103 if ($result !== $expected) { 104 printf("[%03d] Expecting %s/%s got %s/%s with %s - %s.\n", 105 $offset + 6, 106 gettype($expected), $expected, 107 gettype($result), $result, 108 $format, $sql); 109 } 110 111 } else { 112 113 $order_by_col = $result = null; 114 if (!is_null($order_by)) { 115 if (!mysqli_stmt_bind_result($stmt, $order_by_col, $result)) { 116 printf("[%03d] Cannot bind result, [%d] %s\n", 117 $offset + 7, 118 mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 119 return false; 120 } 121 } else { 122 if (!mysqli_stmt_bind_result($stmt, $result)) { 123 printf("[%03d] Cannot bind result, [%d] %s\n", 124 $offset + 7, 125 mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); 126 return false; 127 } 128 } 129 130 foreach ($expected as $k => $v) { 131 if (!mysqli_stmt_fetch($stmt)) { 132 break; 133 } 134 if ($result !== $v) { 135 printf("[%03d] Row %d - expecting %s/%s got %s/%s [%s] with %s - %s.\n", 136 $offset + 8, 137 $k, 138 gettype($v), $v, 139 gettype($result), $result, 140 $order_by_col, 141 $format, $sql); 142 } 143 } 144 145 } 146 147 mysqli_stmt_free_result($stmt); 148 mysqli_stmt_close($stmt); 149 150 return true; 151 } 152 153 if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 154 printf("[001] Cannot connect - [%d] %s\n", 155 mysqli_connect_errno(), 156 mysqli_connect_error()); 157 158 /* create new table and select from it */ 159 $expected = create_table($link, 'FLOAT', -10000, 10000, $engine, 90); 160 foreach ($expected as $k => $v) 161 $expected[$k] = number_format(round($v), 0, '.', ','); 162 test_format($link, 'FORMAT(col1, 0)', 'test', NULL, array(), 100); 163 164 $expected = create_table($link, 'FLOAT', -10000, 10000, $engine, 110); 165 foreach ($expected as $k => $v) 166 $expected[$k] = number_format(round($v), 0, '.', ','); 167 test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 120); 168 169 $expected = create_table($link, 'FLOAT UNSIGNED', 0, 10000, $engine, 130); 170 foreach ($expected as $k => $v) 171 $expected[$k] = number_format(round($v), 0, '.', ','); 172 test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 140); 173 174 $expected = create_table($link, 'DECIMAL(5,0)', -1000, 1000, $engine, 150); 175 foreach ($expected as $k => $v) 176 $expected[$k] = number_format(round($v), 0, '.', ','); 177 test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 160); 178 179 mysqli_close($link); 180 print "done!"; 181?> 182--CLEAN-- 183<?php 184 require_once("clean_table.inc"); 185?> 186--EXPECT-- 187FLOAT 188FORMAT(col1, 0) 189FLOAT 190id AS order_by_col, FORMAT(col1, 0) 191FLOAT UNSIGNED 192id AS order_by_col, FORMAT(col1, 0) 193DECIMAL(5,0) 194id AS order_by_col, FORMAT(col1, 0) 195done! 196