= 43; // see bug #4942
if (function_exists('gzencode')
&& ((! ini_get('zlib.output_compression')
&& ! self::isGzHandlerEnabled())
|| $GLOBALS['save_on_server']
|| $chromeAndGreaterThan43)
) {
return true;
}
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
*/
public static function outputHandler($line)
{
global $time_start, $dump_buffer, $dump_buffer_len, $save_filename;
// Kanji encoding convert feature
if ($GLOBALS['output_kanji_conversion']) {
$line = Encoding::kanjiStrConv(
$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 += strlen($line);
if ($dump_buffer_len > $GLOBALS['memory_limit']) {
if ($GLOBALS['output_charset_conversion']) {
$dump_buffer = Encoding::convertString(
'utf-8',
$GLOBALS['charset'],
$dump_buffer
);
}
if ($GLOBALS['compression'] == 'gzip'
&& self::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 = Encoding::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 'self::outputHandler()' function
/**
* Returns HTML containing the footer for a displayed export
*
* @param string $back_button the link for going Back
* @param string $refreshButton the link for refreshing page
*
* @return string $html the HTML output
*/
public static function getHtmlForDisplayedExportFooter($back_button, $refreshButton)
{
/**
* Close the html tags and add the footers for on-screen export
*/
$html = ''
. ' '
. '
'
// bottom back button
. $back_button
. $refreshButton
. ''
. '' . "\n";
return $html;
}
/**
* Computes the memory limit for export
*
* @return int $memory_limit the memory limit
*/
public static function getMemoryLimit()
{
$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 string[] the filename template and mime type
*/
public static function getFilenameAndMimetype(
$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 = 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 = Sanitize::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
*/
public static function openFile($filename, $quick_export)
{
$file_handle = null;
$message = '';
$doNotSaveItOver = true;
if(isset($_POST['quick_export_onserver_overwrite'])) {
$doNotSaveItOver = $_POST['quick_export_onserver_overwrite'] != 'saveitover';
}
$save_filename = Util::userDir($GLOBALS['cfg']['SaveDir'])
. preg_replace('@[/\\\\]@', '_', $filename);
if (@file_exists($save_filename)
&& ((! $quick_export && empty($_POST['onserver_overwrite']))
|| ($quick_export
&& $doNotSaveItOver))
) {
$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 Message $message a message object (or empty string)
*/
public static function closeFile($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 (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)
*/
public static function compress($dump_buffer, $compression, $filename)
{
if ($compression == 'zip' && function_exists('gzcompress')) {
$zipExtension = new ZipExtension();
$filename = substr($filename, 0, -4); // remove extension (.zip)
$dump_buffer = $zipExtension->createFile($dump_buffer, $filename);
} elseif ($compression == 'gzip' && self::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
*/
public static function 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 string[] the generated HTML and back button
*/
public static function getHtmlForDisplayedExportHeader($export_type, $db, $table)
{
$html = '