bug #2890443 [mysqli] "No index used in query" exception is reported
[phpmyadmin/crack.git] / libraries / import.lib.php
blob345e02c44451b9a0fe00d3f6c71772ea61bbf9fa
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Library that provides common import functions that are used by import plugins
6 * @version $Id$
7 * @package phpMyAdmin
8 */
9 if (! defined('PHPMYADMIN')) {
10 exit;
13 /**
14 * We need to know something about user
16 require_once './libraries/check_user_privileges.lib.php';
18 /**
19 * We do this check, DROP DATABASE does not need to be confirmed elsewhere
21 define('PMA_CHK_DROP', 1);
23 /**
24 * Check whether timeout is getting close
26 * @return boolean true if timeout is close
27 * @access public
29 function PMA_checkTimeout()
31 global $timestamp, $maximum_time, $timeout_passed;
32 if ($maximum_time == 0) {
33 return FALSE;
34 } elseif ($timeout_passed) {
35 return TRUE;
36 /* 5 in next row might be too much */
37 } elseif ((time() - $timestamp) > ($maximum_time - 5)) {
38 $timeout_passed = TRUE;
39 return TRUE;
40 } else {
41 return FALSE;
45 /**
46 * Detects what compression filse uses
48 * @param string filename to check
49 * @return string MIME type of compression, none for none
50 * @access public
52 function PMA_detectCompression($filepath)
54 $file = @fopen($filepath, 'rb');
55 if (!$file) {
56 return FALSE;
58 $test = fread($file, 4);
59 $len = strlen($test);
60 fclose($file);
61 if ($len >= 2 && $test[0] == chr(31) && $test[1] == chr(139)) {
62 return 'application/gzip';
64 if ($len >= 3 && substr($test, 0, 3) == 'BZh') {
65 return 'application/bzip2';
67 if ($len >= 4 && $test == "PK\003\004") {
68 return 'application/zip';
70 return 'none';
73 /**
74 * Runs query inside import buffer. This is needed to allow displaying
75 * of last SELECT, SHOW or HANDLER results and similar nice stuff.
77 * @uses $GLOBALS['finished'] read and write
78 * @param string query to run
79 * @param string query to display, this might be commented
80 * @param bool whether to use control user for queries
81 * @access public
83 function PMA_importRunQuery($sql = '', $full = '', $controluser = false)
85 global $import_run_buffer, $go_sql, $complete_query, $display_query,
86 $sql_query, $my_die, $error, $reload,
87 $skip_queries, $executed_queries, $max_sql_len, $read_multiply,
88 $cfg, $sql_query_disabled, $db, $run_query, $is_superuser;
89 $read_multiply = 1;
90 if (isset($import_run_buffer)) {
91 // Should we skip something?
92 if ($skip_queries > 0) {
93 $skip_queries--;
94 } else {
95 if (!empty($import_run_buffer['sql']) && trim($import_run_buffer['sql']) != '') {
96 $max_sql_len = max($max_sql_len, strlen($import_run_buffer['sql']));
97 if (!$sql_query_disabled) {
98 $sql_query .= $import_run_buffer['full'];
100 if (!$cfg['AllowUserDropDatabase']
101 && !$is_superuser
102 && preg_match('@^[[:space:]]*DROP[[:space:]]+(IF EXISTS[[:space:]]+)?DATABASE @i', $import_run_buffer['sql'])) {
103 $GLOBALS['message'] = PMA_Message::error('strNoDropDatabases');
104 $error = TRUE;
105 } else {
106 $executed_queries++;
107 if ($run_query && $GLOBALS['finished'] && empty($sql) && !$error && (
108 (!empty($import_run_buffer['sql']) && preg_match('/^[\s]*(SELECT|SHOW|HANDLER)/i', $import_run_buffer['sql'])) ||
109 ($executed_queries == 1)
110 )) {
111 $go_sql = TRUE;
112 if (!$sql_query_disabled) {
113 $complete_query = $sql_query;
114 $display_query = $sql_query;
115 } else {
116 $complete_query = '';
117 $display_query = '';
119 $sql_query = $import_run_buffer['sql'];
120 } elseif ($run_query) {
121 if ($controluser) {
122 $result = PMA_query_as_cu($import_run_buffer['sql']);
123 } else {
124 $result = PMA_DBI_try_query($import_run_buffer['sql']);
126 $msg = '# ';
127 if ($result === FALSE) { // execution failed
128 if (!isset($my_die)) {
129 $my_die = array();
131 $my_die[] = array('sql' => $import_run_buffer['full'], 'error' => PMA_DBI_getError());
133 if ($cfg['VerboseMultiSubmit']) {
134 $msg .= $GLOBALS['strError'];
137 if (!$cfg['IgnoreMultiSubmitErrors']) {
138 $error = TRUE;
139 return;
141 } elseif ($cfg['VerboseMultiSubmit']) {
142 $a_num_rows = (int)@PMA_DBI_num_rows($result);
143 $a_aff_rows = (int)@PMA_DBI_affected_rows();
144 if ($a_num_rows > 0) {
145 $msg .= $GLOBALS['strRows'] . ': ' . $a_num_rows;
146 } elseif ($a_aff_rows > 0) {
147 $msg .= sprintf($GLOBALS['strRowsAffected'], $a_aff_rows);
148 } else {
149 $msg .= $GLOBALS['strEmptyResultSet'];
152 if (!$sql_query_disabled) {
153 $sql_query .= $msg . "\n";
156 // If a 'USE <db>' SQL-clause was found and the query succeeded, set our current $db to the new one
157 if ($result != FALSE && preg_match('@^[\s]*USE[[:space:]]*([\S]+)@i', $import_run_buffer['sql'], $match)) {
158 $db = trim($match[1]);
159 $db = trim($db,';'); // for example, USE abc;
160 $reload = TRUE;
163 if ($result != FALSE && preg_match('@^[\s]*(DROP|CREATE)[\s]+(IF EXISTS[[:space:]]+)?(TABLE|DATABASE)[[:space:]]+(.+)@im', $import_run_buffer['sql'])) {
164 $reload = TRUE;
166 } // end run query
167 } // end if not DROP DATABASE
168 } // end non empty query
169 elseif (!empty($import_run_buffer['full'])) {
170 if ($go_sql) {
171 $complete_query .= $import_run_buffer['full'];
172 $display_query .= $import_run_buffer['full'];
173 } else {
174 if (!$sql_query_disabled) {
175 $sql_query .= $import_run_buffer['full'];
179 // check length of query unless we decided to pass it to sql.php
180 // (if $run_query is false, we are just displaying so show
181 // the complete query in the textarea)
182 if (! $go_sql && $run_query) {
183 if ($cfg['VerboseMultiSubmit'] && ! empty($sql_query)) {
184 if (strlen($sql_query) > 50000 || $executed_queries > 50 || $max_sql_len > 1000) {
185 $sql_query = '';
186 $sql_query_disabled = TRUE;
188 } else {
189 if (strlen($sql_query) > 10000 || $executed_queries > 10 || $max_sql_len > 500) {
190 $sql_query = '';
191 $sql_query_disabled = TRUE;
195 } // end do query (no skip)
196 } // end buffer exists
198 // Do we have something to push into buffer?
199 if (!empty($sql) || !empty($full)) {
200 $import_run_buffer = array('sql' => $sql, 'full' => $full);
201 } else {
202 unset($GLOBALS['import_run_buffer']);
208 * Returns next part of imported file/buffer
210 * @uses $GLOBALS['offset'] read and write
211 * @uses $GLOBALS['import_file'] read only
212 * @uses $GLOBALS['import_text'] read and write
213 * @uses $GLOBALS['finished'] read and write
214 * @uses $GLOBALS['read_limit'] read only
215 * @param integer size of buffer to read (this is maximal size
216 * function will return)
217 * @return string part of file/buffer
218 * @access public
220 function PMA_importGetNextChunk($size = 32768)
222 global $compression, $import_handle, $charset_conversion, $charset_of_file,
223 $charset, $read_multiply;
225 // Add some progression while reading large amount of data
226 if ($read_multiply <= 8) {
227 $size *= $read_multiply;
228 } else {
229 $size *= 8;
231 $read_multiply++;
233 // We can not read too much
234 if ($size > $GLOBALS['read_limit']) {
235 $size = $GLOBALS['read_limit'];
238 if (PMA_checkTimeout()) {
239 return FALSE;
241 if ($GLOBALS['finished']) {
242 return TRUE;
245 if ($GLOBALS['import_file'] == 'none') {
246 // Well this is not yet supported and tested, but should return content of textarea
247 if (strlen($GLOBALS['import_text']) < $size) {
248 $GLOBALS['finished'] = TRUE;
249 return $GLOBALS['import_text'];
250 } else {
251 $r = substr($GLOBALS['import_text'], 0, $size);
252 $GLOBALS['offset'] += $size;
253 $GLOBALS['import_text'] = substr($GLOBALS['import_text'], $size);
254 return $r;
258 switch ($compression) {
259 case 'application/bzip2':
260 $result = bzread($import_handle, $size);
261 $GLOBALS['finished'] = feof($import_handle);
262 break;
263 case 'application/gzip':
264 $result = gzread($import_handle, $size);
265 $GLOBALS['finished'] = feof($import_handle);
266 break;
267 case 'application/zip':
268 $result = substr($GLOBALS['import_text'], 0, $size);
269 $GLOBALS['import_text'] = substr($GLOBALS['import_text'], $size);
270 $GLOBALS['finished'] = empty($GLOBALS['import_text']);
271 break;
272 case 'none':
273 $result = fread($import_handle, $size);
274 $GLOBALS['finished'] = feof($import_handle);
275 break;
277 $GLOBALS['offset'] += $size;
279 if ($charset_conversion) {
280 return PMA_convert_string($charset_of_file, $charset, $result);
281 } else {
283 * Skip possible byte order marks (I do not think we need more
284 * charsets, but feel free to add more, you can use wikipedia for
285 * reference: <http://en.wikipedia.org/wiki/Byte_Order_Mark>)
287 * @todo BOM could be used for charset autodetection
289 if ($GLOBALS['offset'] == $size) {
290 // UTF-8
291 if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) {
292 $result = substr($result, 3);
293 // UTF-16 BE, LE
294 } elseif (strncmp($result, "\xFE\xFF", 2) == 0 || strncmp($result, "\xFF\xFE", 2) == 0) {
295 $result = substr($result, 2);
298 return $result;