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