xref: /PHP-7.1/ext/mysqli/tests/bug42378.phpt (revision c01b505a)
1--TEST--
2Bug #42378 (bind_result memory exhaustion, SELECT column, FORMAT(...) AS _format)
3--SKIPIF--
4<?php
5require_once('skipif.inc');
6require_once('skipifemb.inc');
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			if (!empty($expected))
132				reset($expected);
133			while ((list($k, $v) = each($expected)) && mysqli_stmt_fetch($stmt)) {
134				if (!empty($expected)) {
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
149		mysqli_stmt_free_result($stmt);
150		mysqli_stmt_close($stmt);
151
152		return true;
153	}
154
155	if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
156		printf("[001] Cannot connect - [%d] %s\n",
157			mysqli_connect_errno(),
158			mysqli_connect_error());
159
160	/* create new table and select from it */
161	$expected = create_table($link, 'FLOAT', -10000, 10000, $engine, 90);
162	foreach ($expected as $k => $v)
163		$expected[$k] = number_format(round($v), 0, '.', ',');
164	test_format($link, 'FORMAT(col1, 0)', 'test', NULL, array(), 100);
165
166	$expected = create_table($link, 'FLOAT', -10000, 10000, $engine, 110);
167	foreach ($expected as $k => $v)
168		$expected[$k] = number_format(round($v), 0, '.', ',');
169	test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 120);
170
171	$expected = create_table($link, 'FLOAT UNSIGNED', 0, 10000, $engine, 130);
172	foreach ($expected as $k => $v)
173		$expected[$k] = number_format(round($v), 0, '.', ',');
174	test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 140);
175
176	$expected = create_table($link, 'DECIMAL(5,0)', -1000, 1000, $engine, 150);
177	foreach ($expected as $k => $v)
178		$expected[$k] = number_format(round($v), 0, '.', ',');
179	test_format($link, 'id AS order_by_col, FORMAT(col1, 0)', 'test', 'id', $expected, 160);
180
181	mysqli_close($link);
182	print "done!";
183?>
184--CLEAN--
185<?php
186	require_once("clean_table.inc");
187?>
188--EXPECTF--
189FLOAT
190FORMAT(col1, 0)
191FLOAT
192id AS order_by_col, FORMAT(col1, 0)
193FLOAT UNSIGNED
194id AS order_by_col, FORMAT(col1, 0)
195DECIMAL(5,0)
196id AS order_by_col, FORMAT(col1, 0)
197done!
198