diff options
Diffstat (limited to 'srcs/phpmyadmin/import.php')
| -rw-r--r-- | srcs/phpmyadmin/import.php | 809 |
1 files changed, 0 insertions, 809 deletions
diff --git a/srcs/phpmyadmin/import.php b/srcs/phpmyadmin/import.php deleted file mode 100644 index 9ed969d..0000000 --- a/srcs/phpmyadmin/import.php +++ /dev/null @@ -1,809 +0,0 @@ -<?php -/* vim: set expandtab sw=4 ts=4 sts=4: */ -/** - * Core script for import, this is just the glue around all other stuff - * - * @package PhpMyAdmin - */ -declare(strict_types=1); - -use PhpMyAdmin\Bookmark; -use PhpMyAdmin\Core; -use PhpMyAdmin\DatabaseInterface; -use PhpMyAdmin\Encoding; -use PhpMyAdmin\File; -use PhpMyAdmin\Import; -use PhpMyAdmin\ParseAnalyze; -use PhpMyAdmin\Plugins; -use PhpMyAdmin\Plugins\ImportPlugin; -use PhpMyAdmin\Response; -use PhpMyAdmin\Sql; -use PhpMyAdmin\Url; -use PhpMyAdmin\Util; - -if (! defined('ROOT_PATH')) { - define('ROOT_PATH', __DIR__ . DIRECTORY_SEPARATOR); -} - -/* Enable LOAD DATA LOCAL INFILE for LDI plugin */ -if (isset($_POST['format']) && $_POST['format'] == 'ldi') { - define('PMA_ENABLE_LDI', 1); -} - -global $db, $pmaThemeImage, $table; - -require_once ROOT_PATH . 'libraries/common.inc.php'; - -/** @var Response $response */ -$response = $containerBuilder->get(Response::class); - -/** @var DatabaseInterface $dbi */ -$dbi = $containerBuilder->get(DatabaseInterface::class); - -/** @var import $import */ -$import = $containerBuilder->get('import'); - -if (isset($_POST['show_as_php'])) { - $GLOBALS['show_as_php'] = $_POST['show_as_php']; -} - -// If there is a request to 'Simulate DML'. -if (isset($_POST['simulate_dml'])) { - $import->handleSimulateDmlRequest(); - exit; -} - -$sql = new Sql(); - -// If it's a refresh console bookmarks request -if (isset($_GET['console_bookmark_refresh'])) { - $response->addJSON( - 'console_message_bookmark', - PhpMyAdmin\Console::getBookmarkContent() - ); - exit; -} -// If it's a console bookmark add request -if (isset($_POST['console_bookmark_add'])) { - if (isset($_POST['label']) && isset($_POST['db']) - && isset($_POST['bookmark_query']) && isset($_POST['shared']) - ) { - $cfgBookmark = Bookmark::getParams($GLOBALS['cfg']['Server']['user']); - $bookmarkFields = [ - 'bkm_database' => $_POST['db'], - 'bkm_user' => $cfgBookmark['user'], - 'bkm_sql_query' => $_POST['bookmark_query'], - 'bkm_label' => $_POST['label'], - ]; - $isShared = ($_POST['shared'] == 'true' ? true : false); - $bookmark = Bookmark::createBookmark( - $dbi, - $GLOBALS['cfg']['Server']['user'], - $bookmarkFields, - $isShared - ); - if ($bookmark !== false && $bookmark->save()) { - $response->addJSON('message', __('Succeeded')); - $response->addJSON('data', $bookmarkFields); - $response->addJSON('isShared', $isShared); - } else { - $response->addJSON('message', __('Failed')); - } - die(); - } else { - $response->addJSON('message', __('Incomplete params')); - die(); - } -} - -$format = ''; - -/** - * Sets globals from $_POST - */ -$post_params = [ - 'charset_of_file', - 'format', - 'import_type', - 'is_js_confirmed', - 'MAX_FILE_SIZE', - 'message_to_show', - 'noplugin', - 'skip_queries', - 'local_import_file', -]; - -foreach ($post_params as $one_post_param) { - if (isset($_POST[$one_post_param])) { - $GLOBALS[$one_post_param] = $_POST[$one_post_param]; - } -} - -// reset import messages for ajax request -$_SESSION['Import_message']['message'] = null; -$_SESSION['Import_message']['go_back_url'] = null; -// default values -$GLOBALS['reload'] = false; - -// Use to identify current cycle is executing -// a multiquery statement or stored routine -if (! isset($_SESSION['is_multi_query'])) { - $_SESSION['is_multi_query'] = false; -} - -$ajax_reload = []; -$import_text = ''; -// Are we just executing plain query or sql file? -// (eg. non import, but query box/window run) -if (! empty($sql_query)) { - // apply values for parameters - if (! empty($_POST['parameterized']) - && ! empty($_POST['parameters']) - && is_array($_POST['parameters']) - ) { - $parameters = $_POST['parameters']; - foreach ($parameters as $parameter => $replacement) { - $quoted = preg_quote($parameter, '/'); - // making sure that :param does not apply values to :param1 - $sql_query = preg_replace( - '/' . $quoted . '([^a-zA-Z0-9_])/', - $dbi->escapeString($replacement) . '${1}', - $sql_query - ); - // for parameters the appear at the end of the string - $sql_query = preg_replace( - '/' . $quoted . '$/', - $dbi->escapeString($replacement), - $sql_query - ); - } - } - - // run SQL query - $import_text = $sql_query; - $import_type = 'query'; - $format = 'sql'; - $_SESSION['sql_from_query_box'] = true; - - // If there is a request to ROLLBACK when finished. - if (isset($_POST['rollback_query'])) { - $import->handleRollbackRequest($import_text); - } - - // refresh navigation and main panels - if (preg_match('/^(DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', $sql_query)) { - $GLOBALS['reload'] = true; - $ajax_reload['reload'] = true; - } - - // refresh navigation panel only - if (preg_match( - '/^(CREATE|ALTER)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', - $sql_query - )) { - $ajax_reload['reload'] = true; - } - - // do a dynamic reload if table is RENAMED - // (by sending the instruction to the AJAX response handler) - if (preg_match( - '/^RENAME\s+TABLE\s+(.*?)\s+TO\s+(.*?)($|;|\s)/i', - $sql_query, - $rename_table_names - )) { - $ajax_reload['reload'] = true; - $ajax_reload['table_name'] = PhpMyAdmin\Util::unQuote( - $rename_table_names[2] - ); - } - - $sql_query = ''; -} elseif (! empty($sql_file)) { - // run uploaded SQL file - $import_file = $sql_file; - $import_type = 'queryfile'; - $format = 'sql'; - unset($sql_file); -} elseif (! empty($_POST['id_bookmark'])) { - // run bookmark - $import_type = 'query'; - $format = 'sql'; -} - -// If we didn't get any parameters, either user called this directly, or -// upload limit has been reached, let's assume the second possibility. -if ($_POST == [] && $_GET == []) { - $message = PhpMyAdmin\Message::error( - __( - 'You probably tried to upload a file that is too large. Please refer ' . - 'to %sdocumentation%s for a workaround for this limit.' - ) - ); - $message->addParam('[doc@faq1-16]'); - $message->addParam('[/doc]'); - - // so we can obtain the message - $_SESSION['Import_message']['message'] = $message->getDisplay(); - $_SESSION['Import_message']['go_back_url'] = $GLOBALS['goto']; - - $response->setRequestStatus(false); - $response->addJSON('message', $message); - - exit; // the footer is displayed automatically -} - -// Add console message id to response output -if (isset($_POST['console_message_id'])) { - $response->addJSON('console_message_id', $_POST['console_message_id']); -} - -/** - * Sets globals from $_POST patterns, for import plugins - * We only need to load the selected plugin - */ - -if (! in_array( - $format, - [ - 'csv', - 'ldi', - 'mediawiki', - 'ods', - 'shp', - 'sql', - 'xml', - ] -) -) { - // this should not happen for a normal user - // but only during an attack - Core::fatalError('Incorrect format parameter'); -} - -$post_patterns = [ - '/^force_file_/', - '/^' . $format . '_/', -]; - -Core::setPostAsGlobal($post_patterns); - -// Check needed parameters -PhpMyAdmin\Util::checkParameters(['import_type', 'format']); - -// We don't want anything special in format -$format = Core::securePath($format); - -if (strlen($table) > 0 && strlen($db) > 0) { - $urlparams = [ - 'db' => $db, - 'table' => $table, - ]; -} elseif (strlen($db) > 0) { - $urlparams = ['db' => $db]; -} else { - $urlparams = []; -} - -// Create error and goto url -if ($import_type == 'table') { - $goto = 'tbl_import.php'; -} elseif ($import_type == 'database') { - $goto = 'db_import.php'; -} elseif ($import_type == 'server') { - $goto = 'server_import.php'; -} elseif (empty($goto) || ! preg_match('@^(server|db|tbl)(_[a-z]*)*\.php$@i', $goto)) { - if (strlen($table) > 0 && strlen($db) > 0) { - $goto = 'tbl_structure.php'; - } elseif (strlen($db) > 0) { - $goto = 'db_structure.php'; - } else { - $goto = 'server_sql.php'; - } -} -$err_url = $goto . Url::getCommon($urlparams); -$_SESSION['Import_message']['go_back_url'] = $err_url; -// Avoid setting selflink to 'import.php' -// problem similar to bug 4276 -if (basename($_SERVER['SCRIPT_NAME']) === 'import.php') { - $_SERVER['SCRIPT_NAME'] = $goto; -} - - -if (strlen($db) > 0) { - $dbi->selectDb($db); -} - -Util::setTimeLimit(); -if (! empty($cfg['MemoryLimit'])) { - ini_set('memory_limit', $cfg['MemoryLimit']); -} - -$timestamp = time(); -if (isset($_POST['allow_interrupt'])) { - $maximum_time = ini_get('max_execution_time'); -} else { - $maximum_time = 0; -} - -// set default values -$timeout_passed = false; -$error = false; -$read_multiply = 1; -$finished = false; -$offset = 0; -$max_sql_len = 0; -$file_to_unlink = ''; -$sql_query = ''; -$sql_query_disabled = false; -$go_sql = false; -$executed_queries = 0; -$run_query = true; -$charset_conversion = false; -$reset_charset = false; -$bookmark_created = false; -$result = false; -$msg = 'Sorry an unexpected error happened!'; - -// Bookmark Support: get a query back from bookmark if required -if (! empty($_POST['id_bookmark'])) { - $id_bookmark = (int) $_POST['id_bookmark']; - switch ($_POST['action_bookmark']) { - case 0: // bookmarked query that have to be run - $bookmark = Bookmark::get( - $dbi, - $GLOBALS['cfg']['Server']['user'], - $db, - $id_bookmark, - 'id', - isset($_POST['action_bookmark_all']) - ); - - if (! empty($_POST['bookmark_variable'])) { - $import_text = $bookmark->applyVariables( - $_POST['bookmark_variable'] - ); - } else { - $import_text = $bookmark->getQuery(); - } - - // refresh navigation and main panels - if (preg_match( - '/^(DROP)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', - $import_text - )) { - $GLOBALS['reload'] = true; - $ajax_reload['reload'] = true; - } - - // refresh navigation panel only - if (preg_match( - '/^(CREATE|ALTER)\s+(VIEW|TABLE|DATABASE|SCHEMA)\s+/i', - $import_text - ) - ) { - $ajax_reload['reload'] = true; - } - break; - case 1: // bookmarked query that have to be displayed - $bookmark = Bookmark::get( - $dbi, - $GLOBALS['cfg']['Server']['user'], - $db, - $id_bookmark - ); - $import_text = $bookmark->getQuery(); - if ($response->isAjax()) { - $message = PhpMyAdmin\Message::success(__('Showing bookmark')); - $response->setRequestStatus($message->isSuccess()); - $response->addJSON('message', $message); - $response->addJSON('sql_query', $import_text); - $response->addJSON('action_bookmark', $_POST['action_bookmark']); - exit; - } else { - $run_query = false; - } - break; - case 2: // bookmarked query that have to be deleted - $bookmark = Bookmark::get( - $dbi, - $GLOBALS['cfg']['Server']['user'], - $db, - $id_bookmark - ); - if (! empty($bookmark)) { - $bookmark->delete(); - if ($response->isAjax()) { - $message = PhpMyAdmin\Message::success( - __('The bookmark has been deleted.') - ); - $response->setRequestStatus($message->isSuccess()); - $response->addJSON('message', $message); - $response->addJSON('action_bookmark', $_POST['action_bookmark']); - $response->addJSON('id_bookmark', $id_bookmark); - exit; - } else { - $run_query = false; - $error = true; // this is kind of hack to skip processing the query - } - } - - break; - } -} // end bookmarks reading - -// Do no run query if we show PHP code -if (isset($GLOBALS['show_as_php'])) { - $run_query = false; - $go_sql = true; -} - -// We can not read all at once, otherwise we can run out of memory -$memory_limit = trim(ini_get('memory_limit')); -// 2 MB as default -if (empty($memory_limit)) { - $memory_limit = 2 * 1024 * 1024; -} -// In case no memory limit we work on 10MB chunks -if ($memory_limit == -1) { - $memory_limit = 10 * 1024 * 1024; -} - -// Calculate value of the limit -$memoryUnit = mb_strtolower(substr((string) $memory_limit, -1)); -if ('m' == $memoryUnit) { - $memory_limit = (int) substr((string) $memory_limit, 0, -1) * 1024 * 1024; -} elseif ('k' == $memoryUnit) { - $memory_limit = (int) substr((string) $memory_limit, 0, -1) * 1024; -} elseif ('g' == $memoryUnit) { - $memory_limit = (int) substr((string) $memory_limit, 0, -1) * 1024 * 1024 * 1024; -} else { - $memory_limit = (int) $memory_limit; -} - -// Just to be sure, there might be lot of memory needed for uncompression -$read_limit = $memory_limit / 8; - -// handle filenames -if (isset($_FILES['import_file'])) { - $import_file = $_FILES['import_file']['tmp_name']; - $import_file_name = $_FILES['import_file']['name']; -} -if (! empty($local_import_file) && ! empty($cfg['UploadDir'])) { - // sanitize $local_import_file as it comes from a POST - $local_import_file = Core::securePath($local_import_file); - - $import_file = PhpMyAdmin\Util::userDir($cfg['UploadDir']) - . $local_import_file; - - /* - * Do not allow symlinks to avoid security issues - * (user can create symlink to file he can not access, - * but phpMyAdmin can). - */ - if (@is_link($import_file)) { - $import_file = 'none'; - } -} elseif (empty($import_file) || ! is_uploaded_file($import_file)) { - $import_file = 'none'; -} - -// Do we have file to import? - -if ($import_file != 'none' && ! $error) { - /** - * Handle file compression - */ - $import_handle = new File($import_file); - $import_handle->checkUploadedFile(); - if ($import_handle->isError()) { - $import->stop($import_handle->getError()); - } - $import_handle->setDecompressContent(true); - $import_handle->open(); - if ($import_handle->isError()) { - $import->stop($import_handle->getError()); - } -} elseif (! $error) { - if (! isset($import_text) || empty($import_text)) { - $message = PhpMyAdmin\Message::error( - __( - 'No data was received to import. Either no file name was ' . - 'submitted, or the file size exceeded the maximum size permitted ' . - 'by your PHP configuration. See [doc@faq1-16]FAQ 1.16[/doc].' - ) - ); - $import->stop($message); - } -} - -// so we can obtain the message -//$_SESSION['Import_message'] = $message->getDisplay(); - -// Convert the file's charset if necessary -if (Encoding::isSupported() && isset($charset_of_file)) { - if ($charset_of_file != 'utf-8') { - $charset_conversion = true; - } -} elseif (isset($charset_of_file) && $charset_of_file != 'utf-8') { - $dbi->query('SET NAMES \'' . $charset_of_file . '\''); - // We can not show query in this case, it is in different charset - $sql_query_disabled = true; - $reset_charset = true; -} - -// Something to skip? (because timeout has passed) -if (! $error && isset($_POST['skip'])) { - $original_skip = $skip = intval($_POST['skip']); - while ($skip > 0 && ! $finished) { - $import->getNextChunk($skip < $read_limit ? $skip : $read_limit); - // Disable read progressivity, otherwise we eat all memory! - $read_multiply = 1; - $skip -= $read_limit; - } - unset($skip); -} - -// This array contain the data like numberof valid sql queries in the statement -// and complete valid sql statement (which affected for rows) -$sql_data = [ - 'valid_sql' => [], - 'valid_queries' => 0, -]; - -if (! $error) { - /** - * @var ImportPlugin $import_plugin - */ - $import_plugin = Plugins::getPlugin( - "import", - $format, - 'libraries/classes/Plugins/Import/', - $import_type - ); - if ($import_plugin == null) { - $message = PhpMyAdmin\Message::error( - __('Could not load import plugins, please check your installation!') - ); - $import->stop($message); - } else { - // Do the real import - $default_fk_check = PhpMyAdmin\Util::handleDisableFKCheckInit(); - try { - $import_plugin->doImport($sql_data); - PhpMyAdmin\Util::handleDisableFKCheckCleanup($default_fk_check); - } catch (Exception $e) { - PhpMyAdmin\Util::handleDisableFKCheckCleanup($default_fk_check); - throw $e; - } - } -} - -if (isset($import_handle)) { - $import_handle->close(); -} - -// Cleanup temporary file -if ($file_to_unlink != '') { - unlink($file_to_unlink); -} - -// Reset charset back, if we did some changes -if ($reset_charset) { - $dbi->query('SET CHARACTER SET ' . $GLOBALS['charset_connection']); - $dbi->setCollation($collation_connection); -} - -// Show correct message -if (! empty($id_bookmark) && $_POST['action_bookmark'] == 2) { - $message = PhpMyAdmin\Message::success(__('The bookmark has been deleted.')); - $display_query = $import_text; - $error = false; // unset error marker, it was used just to skip processing -} elseif (! empty($id_bookmark) && $_POST['action_bookmark'] == 1) { - $message = PhpMyAdmin\Message::notice(__('Showing bookmark')); -} elseif ($bookmark_created) { - $special_message = '[br]' . sprintf( - __('Bookmark %s has been created.'), - htmlspecialchars($_POST['bkm_label']) - ); -} elseif ($finished && ! $error) { - // Do not display the query with message, we do it separately - $display_query = ';'; - if ($import_type != 'query') { - $message = PhpMyAdmin\Message::success( - '<em>' - . _ngettext( - 'Import has been successfully finished, %d query executed.', - 'Import has been successfully finished, %d queries executed.', - $executed_queries - ) - . '</em>' - ); - $message->addParam($executed_queries); - - if (! empty($import_notice)) { - $message->addHtml($import_notice); - } - if (! empty($local_import_file)) { - $message->addText('(' . $local_import_file . ')'); - } else { - $message->addText('(' . $_FILES['import_file']['name'] . ')'); - } - } -} - -// Did we hit timeout? Tell it user. -if ($timeout_passed) { - $urlparams['timeout_passed'] = '1'; - $urlparams['offset'] = $GLOBALS['offset']; - if (isset($local_import_file)) { - $urlparams['local_import_file'] = $local_import_file; - } - - $importUrl = $err_url = $goto . Url::getCommon($urlparams); - - $message = PhpMyAdmin\Message::error( - __( - 'Script timeout passed, if you want to finish import,' - . ' please %sresubmit the same file%s and import will resume.' - ) - ); - $message->addParamHtml('<a href="' . $importUrl . '">'); - $message->addParamHtml('</a>'); - - if ($offset == 0 || (isset($original_skip) && $original_skip == $offset)) { - $message->addText( - __( - 'However on last run no data has been parsed,' - . ' this usually means phpMyAdmin won\'t be able to' - . ' finish this import unless you increase php time limits.' - ) - ); - } -} - -// if there is any message, copy it into $_SESSION as well, -// so we can obtain it by AJAX call -if (isset($message)) { - $_SESSION['Import_message']['message'] = $message->getDisplay(); -} -// Parse and analyze the query, for correct db and table name -// in case of a query typed in the query window -// (but if the query is too large, in case of an imported file, the parser -// can choke on it so avoid parsing) -$sqlLength = mb_strlen($sql_query); -if ($sqlLength <= $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) { - list( - $analyzed_sql_results, - $db, - $table_from_sql - ) = ParseAnalyze::sqlQuery($sql_query, $db); - // @todo: possibly refactor - extract($analyzed_sql_results); - - if ($table != $table_from_sql && ! empty($table_from_sql)) { - $table = $table_from_sql; - } -} - -// There was an error? -if (isset($my_die)) { - foreach ($my_die as $key => $die) { - PhpMyAdmin\Util::mysqlDie( - $die['error'], - $die['sql'], - false, - $err_url, - $error - ); - } -} - -if ($go_sql) { - if (! empty($sql_data) && ($sql_data['valid_queries'] > 1)) { - $_SESSION['is_multi_query'] = true; - $sql_queries = $sql_data['valid_sql']; - } else { - $sql_queries = [$sql_query]; - } - - $html_output = ''; - - foreach ($sql_queries as $sql_query) { - // parse sql query - list( - $analyzed_sql_results, - $db, - $table_from_sql - ) = ParseAnalyze::sqlQuery($sql_query, $db); - // @todo: possibly refactor - extract($analyzed_sql_results); - - // Check if User is allowed to issue a 'DROP DATABASE' Statement - if ($sql->hasNoRightsToDropDatabase( - $analyzed_sql_results, - $cfg['AllowUserDropDatabase'], - $dbi->isSuperuser() - )) { - PhpMyAdmin\Util::mysqlDie( - __('"DROP DATABASE" statements are disabled.'), - '', - false, - $_SESSION['Import_message']['go_back_url'] - ); - return; - } // end if - - if ($table != $table_from_sql && ! empty($table_from_sql)) { - $table = $table_from_sql; - } - - $html_output .= $sql->executeQueryAndGetQueryResponse( - $analyzed_sql_results, // analyzed_sql_results - false, // is_gotofile - $db, // db - $table, // table - null, // find_real_end - null, // sql_query_for_bookmark - see below - null, // extra_data - null, // message_to_show - null, // message - null, // sql_data - $goto, // goto - $pmaThemeImage, // pmaThemeImage - null, // disp_query - null, // disp_message - null, // query_type - $sql_query, // sql_query - null, // selectedTables - null // complete_query - ); - } - - // sql_query_for_bookmark is not included in Sql::executeQueryAndGetQueryResponse - // since only one bookmark has to be added for all the queries submitted through - // the SQL tab - if (! empty($_POST['bkm_label']) && ! empty($import_text)) { - $cfgBookmark = Bookmark::getParams($GLOBALS['cfg']['Server']['user']); - $sql->storeTheQueryAsBookmark( - $db, - $cfgBookmark['user'], - $_POST['sql_query'], - $_POST['bkm_label'], - isset($_POST['bkm_replace']) ? $_POST['bkm_replace'] : null - ); - } - - $response->addJSON('ajax_reload', $ajax_reload); - $response->addHTML($html_output); - exit; -} elseif ($result) { - // Save a Bookmark with more than one queries (if Bookmark label given). - if (! empty($_POST['bkm_label']) && ! empty($import_text)) { - $cfgBookmark = Bookmark::getParams($GLOBALS['cfg']['Server']['user']); - $sql->storeTheQueryAsBookmark( - $db, - $cfgBookmark['user'], - $_POST['sql_query'], - $_POST['bkm_label'], - isset($_POST['bkm_replace']) ? $_POST['bkm_replace'] : null - ); - } - - $response->setRequestStatus(true); - $response->addJSON('message', PhpMyAdmin\Message::success($msg)); - $response->addJSON( - 'sql_query', - PhpMyAdmin\Util::getMessage($msg, $sql_query, 'success') - ); -} elseif ($result === false) { - $response->setRequestStatus(false); - $response->addJSON('message', PhpMyAdmin\Message::error($msg)); -} else { - $active_page = $goto; - include ROOT_PATH . $goto; -} - -// If there is request for ROLLBACK in the end. -if (isset($_POST['rollback_query'])) { - $dbi->query('ROLLBACK'); -} |
