= 43; // see bug #4942 if (@function_exists('gzencode') && ((! @ini_get('zlib.output_compression') && ! PMA_isGzHandlerEnabled()) || $GLOBALS['save_on_server'] || $chromeAndGreaterThan43) ) { return true; } else { return false; } } /** * Output handler for all exports, if needed buffering, it stores data into * $dump_buffer, otherwise it prints them out. * * @param string $line the insert statement * * @return bool Whether output succeeded */ function PMA_exportOutputHandler($line) { global $time_start, $dump_buffer, $dump_buffer_len, $save_filename; // Kanji encoding convert feature if ($GLOBALS['output_kanji_conversion']) { $line = PMA_Kanji_strConv( $line, $GLOBALS['knjenc'], isset($GLOBALS['xkana']) ? $GLOBALS['xkana'] : '' ); } // If we have to buffer data, we will perform everything at once at the end if ($GLOBALS['buffer_needed']) { $dump_buffer .= $line; if ($GLOBALS['onfly_compression']) { $dump_buffer_len += mb_strlen($line); if ($dump_buffer_len > $GLOBALS['memory_limit']) { if ($GLOBALS['output_charset_conversion']) { $dump_buffer = PMA_convertString( 'utf-8', $GLOBALS['charset'], $dump_buffer ); } if ($GLOBALS['compression'] == 'gzip' && PMA_gzencodeNeeded() ) { // as a gzipped file // without the optional parameter level because it bugs $dump_buffer = gzencode($dump_buffer); } if ($GLOBALS['save_on_server']) { $write_result = @fwrite($GLOBALS['file_handle'], $dump_buffer); // Here, use strlen rather than mb_strlen to get the length // in bytes to compare against the number of bytes written. if ($write_result != strlen($dump_buffer)) { $GLOBALS['message'] = Message::error( __('Insufficient space to save the file %s.') ); $GLOBALS['message']->addParam($save_filename); return false; } } else { echo $dump_buffer; } $dump_buffer = ''; $dump_buffer_len = 0; } } else { $time_now = time(); if ($time_start >= $time_now + 30) { $time_start = $time_now; header('X-pmaPing: Pong'); } // end if } } else { if ($GLOBALS['asfile']) { if ($GLOBALS['output_charset_conversion']) { $line = PMA_convertString( 'utf-8', $GLOBALS['charset'], $line ); } if ($GLOBALS['save_on_server'] && mb_strlen($line) > 0) { $write_result = @fwrite($GLOBALS['file_handle'], $line); // Here, use strlen rather than mb_strlen to get the length // in bytes to compare against the number of bytes written. if (! $write_result || $write_result != strlen($line) ) { $GLOBALS['message'] = Message::error( __('Insufficient space to save the file %s.') ); $GLOBALS['message']->addParam($save_filename); return false; } $time_now = time(); if ($time_start >= $time_now + 30) { $time_start = $time_now; header('X-pmaPing: Pong'); } // end if } else { // We export as file - output normally echo $line; } } else { // We export as html - replace special chars echo htmlspecialchars($line); } } return true; } // end of the 'PMA_exportOutputHandler()' function /** * Returns HTML containing the footer for a displayed export * * @param string $back_button the link for going Back * * @return string $html the HTML output */ function PMA_getHtmlForDisplayedExportFooter($back_button) { /** * Close the html tags and add the footers for on-screen export */ $html = '' . ' ' // bottom back button . $back_button . '' . '' . "\n"; return $html; } /** * Computes the memory limit for export * * @return int $memory_limit the memory limit */ function PMA_getMemoryLimitForExport() { $memory_limit = trim(@ini_get('memory_limit')); $memory_limit_num = (int)substr($memory_limit, 0, -1); $lowerLastChar = strtolower(substr($memory_limit, -1)); // 2 MB as default if (empty($memory_limit) || '-1' == $memory_limit) { $memory_limit = 2 * 1024 * 1024; } elseif ($lowerLastChar == 'm') { $memory_limit = $memory_limit_num * 1024 * 1024; } elseif ($lowerLastChar == 'k') { $memory_limit = $memory_limit_num * 1024; } elseif ($lowerLastChar == 'g') { $memory_limit = $memory_limit_num * 1024 * 1024 * 1024; } else { $memory_limit = (int)$memory_limit; } // Some of memory is needed for other things and as threshold. // During export I had allocated (see memory_get_usage function) // approx 1.2MB so this comes from that. if ($memory_limit > 1500000) { $memory_limit -= 1500000; } // Some memory is needed for compression, assume 1/3 $memory_limit /= 8; return $memory_limit; } /** * Return the filename and MIME type for export file * * @param string $export_type type of export * @param string $remember_template whether to remember template * @param ExportPlugin $export_plugin the export plugin * @param string $compression compression asked * @param string $filename_template the filename template * * @return array the filename template and mime type */ function PMA_getExportFilenameAndMimetype( $export_type, $remember_template, $export_plugin, $compression, $filename_template ) { if ($export_type == 'server') { if (! empty($remember_template)) { $GLOBALS['PMA_Config']->setUserValue( 'pma_server_filename_template', 'Export/file_template_server', $filename_template ); } } elseif ($export_type == 'database') { if (! empty($remember_template)) { $GLOBALS['PMA_Config']->setUserValue( 'pma_db_filename_template', 'Export/file_template_database', $filename_template ); } } else { if (! empty($remember_template)) { $GLOBALS['PMA_Config']->setUserValue( 'pma_table_filename_template', 'Export/file_template_table', $filename_template ); } } $filename = PMA\libraries\Util::expandUserString($filename_template); // remove dots in filename (coming from either the template or already // part of the filename) to avoid a remote code execution vulnerability $filename = PMA_sanitizeFilename($filename, $replaceDots = true); // Grab basic dump extension and mime type // Check if the user already added extension; // get the substring where the extension would be if it was included $extension_start_pos = mb_strlen($filename) - mb_strlen( $export_plugin->getProperties()->getExtension() ) - 1; $user_extension = mb_substr( $filename, $extension_start_pos, mb_strlen($filename) ); $required_extension = "." . $export_plugin->getProperties()->getExtension(); if (mb_strtolower($user_extension) != $required_extension) { $filename .= $required_extension; } $mime_type = $export_plugin->getProperties()->getMimeType(); // If dump is going to be compressed, set correct mime_type and add // compression to extension if ($compression == 'gzip') { $filename .= '.gz'; $mime_type = 'application/x-gzip'; } elseif ($compression == 'zip') { $filename .= '.zip'; $mime_type = 'application/zip'; } return array($filename, $mime_type); } /** * Open the export file * * @param string $filename the export filename * @param boolean $quick_export whether it's a quick export or not * * @return array the full save filename, possible message and the file handle */ function PMA_openExportFile($filename, $quick_export) { $file_handle = null; $message = ''; $save_filename = PMA\libraries\Util::userDir($GLOBALS['cfg']['SaveDir']) . preg_replace('@[/\\\\]@', '_', $filename); if (file_exists($save_filename) && ((! $quick_export && empty($_REQUEST['onserver_overwrite'])) || ($quick_export && $_REQUEST['quick_export_onserver_overwrite'] != 'saveitover')) ) { $message = Message::error( __( 'File %s already exists on server, ' . 'change filename or check overwrite option.' ) ); $message->addParam($save_filename); } elseif (@is_file($save_filename) && ! @is_writable($save_filename)) { $message = Message::error( __( 'The web server does not have permission ' . 'to save the file %s.' ) ); $message->addParam($save_filename); } elseif (! $file_handle = @fopen($save_filename, 'w')) { $message = Message::error( __( 'The web server does not have permission ' . 'to save the file %s.' ) ); $message->addParam($save_filename); } return array($save_filename, $message, $file_handle); } /** * Close the export file * * @param resource $file_handle the export file handle * @param string $dump_buffer the current dump buffer * @param string $save_filename the export filename * * @return object $message a message object (or empty string) */ function PMA_closeExportFile($file_handle, $dump_buffer, $save_filename) { $write_result = @fwrite($file_handle, $dump_buffer); fclose($file_handle); // Here, use strlen rather than mb_strlen to get the length // in bytes to compare against the number of bytes written. if (mb_strlen($dump_buffer) > 0 && (! $write_result || $write_result != strlen($dump_buffer)) ) { $message = new Message( __('Insufficient space to save the file %s.'), Message::ERROR, array($save_filename) ); } else { $message = new Message( __('Dump has been saved to file %s.'), Message::SUCCESS, array($save_filename) ); } return $message; } /** * Compress the export buffer * * @param array|string $dump_buffer the current dump buffer * @param string $compression the compression mode * @param string $filename the filename * * @return object $message a message object (or empty string) */ function PMA_compressExport($dump_buffer, $compression, $filename) { if ($compression == 'zip' && @function_exists('gzcompress')) { $filename = substr($filename, 0, -4); // remove extension (.zip) $zipfile = new ZipFile(); if (is_array($dump_buffer)) { foreach ($dump_buffer as $table => $dump) { $ext_pos = strpos($filename, '.'); $extension = substr($filename, $ext_pos); $zipfile->addFile( $dump, str_replace( $extension, '_' . $table . $extension, $filename ) ); } } else { $zipfile->addFile($dump_buffer, $filename); } $dump_buffer = $zipfile->file(); } elseif ($compression == 'gzip' && PMA_gzencodeNeeded()) { // without the optional parameter level because it bugs $dump_buffer = gzencode($dump_buffer); } return $dump_buffer; } /** * Saves the dump_buffer for a particular table in an array * Used in separate files export * * @param string $object_name the name of current object to be stored * @param boolean $append optional boolean to append to an existing index or not * * @return void */ function PMA_saveObjectInBuffer($object_name, $append = false) { global $dump_buffer_objects, $dump_buffer, $dump_buffer_len; if (! empty($dump_buffer)) { if ($append && isset($dump_buffer_objects[$object_name])) { $dump_buffer_objects[$object_name] .= $dump_buffer; } else { $dump_buffer_objects[$object_name] = $dump_buffer; } } // Re - initialize $dump_buffer = ''; $dump_buffer_len = 0; } /** * Returns HTML containing the header for a displayed export * * @param string $export_type the export type * @param string $db the database name * @param string $table the table name * * @return array the generated HTML and back button */ function PMA_getHtmlForDisplayedExportHeader($export_type, $db, $table) { $html = '
'; /** * Displays a back button with all the $_REQUEST data in the URL * (store in a variable to also display after the textarea) */ $back_button = '

[ $value) { if (!is_array($value)) { $back_button .= '&' . urlencode($name) . '=' . urlencode($value); } } $back_button .= '&repopulate=1">' . __('Back') . ' ]

'; $html .= $back_button . '
' . '