php: изменение влияния mysql_real_escape_string на двоичный файл

Я создал веб-страницу, на которой пользователи могут отправить PDF-файл, который затем вставляется в базу данных MySQL в файле mediumblob для последующего извлечения.

Все это работает нормально, за исключением случаев, когда PDF-файл содержит изображения или встроенные шрифты, и в этом случае изображения повреждены, а любой текст, использующий шрифт, исчезает (Acrobat отображает сообщение об отсутствующем шрифте).

Я определил, что проблема возникает из-за передачи данных в формате PDF через mysql_real_escape_string_function. Я переключился на base64_encode/base64_decode при отправке/извлечении, что устранило проблему для всех новых файлов, но у меня есть около 25 уже отправленных PDF-файлов, которые мне нужно прочитать.

Можно ли отменить действие mysql_real_escape_string? Или эти файлы повреждены и не подлежат восстановлению?


person Community    schedule 19.05.2009    source источник


Ответы (4)


Конечно, должно быть поправимо. Вам просто нужно выяснить, точно что делает mysql_real_escape_string. Я считаю, что вам просто нужно удалить все косые черты, которые непосредственно предшествуют CR, LF, TAB, одинарной, двойной кавычке, NUL или другой косой черте. Должно быть однострочное исправление регулярного выражения.

person Eli    schedule 19.05.2009

mysql_real_escape_string() добавляет к этим символам обратную косую черту.

\x00, \n, \r, \, ', " and \x1a

Дело в том, что если ваш двоичный вывод имеет обратную косую черту, это двоичные данные, это может быть очень сложно исправить. При этом нет никакой волшебной функции, чтобы отменить эту функцию.

person Ólafur Waage    schedule 19.05.2009

Я честно не знаю, что еще может быть. Когда я изменил этот фрагмент кода, проблема исчезла, и я нашел в Интернете другие случаи, когда у людей была такая же проблема (но не было решений).

Вот код вставки:

function db_value( $mysqli, $value ) {
if( empty($value) )
    return "''";

if( get_magic_quotes_gpc() )
    $value = stripslashes($value);

if( !is_numeric($value) || ($value[0] == '0' && $value != 0) )
    $value = "'".mysqli_real_escape_string($mysqli, $value)."'";

return $value;
}

function saveToDatabase( $data, $fileTempName, $abstractFileName ) {
$fileHandle = fopen( $fileTempName, 'r' );
$abstractFile = fread( $fileHandle, filesize( $fileTempName ) );
fclose( $fileHandle );
$abstractFileMimeType = $fileUpload->get_mime();

$mysqli = connect_to_database();

if( $mysqli != FALSE ) {
    $insertQuery = "INSERT INTO `paper_submissions` (
        `name`,
        `affiliation`,
        `email`,
        `phone_number`,
        `title`,
        `abstract`,
        `abstract_file`,
        `abstract_file_name`,
        `abstract_file_mime_type`,
        `requests_financial_support`,
        `HTTP_USER_AGENT`,
        `REMOTE_ADDR`
    )
    VALUES ( 
        ".db_value( $mysqli, $data['submitter_name'] ).",
        ".db_value( $mysqli, $data['submitter_affiliation'] ).",
        ".db_value( $mysqli, $data['submitter_email'] ).",
        ".db_value( $mysqli, $data['submitter_phone'] ).",
        ".db_value( $mysqli, $data['paper_title'] ).",
        ".db_value( $mysqli, $data['abstract_text'] ).",
        ".db_value( $mysqli, $abstractFile ).",
        ".db_value( $mysqli, $abstractFileName ).",
        ".db_value( $mysqli, $abstractFileMimeType ).",
        ".db_value( $mysqli, $data['request_financial_support'] ).",
        ".db_value($mysqli, $_SERVER['HTTP_USER_AGENT']).",
        ".db_value($mysqli, $_SERVER['REMOTE_ADDR'])."
    )";

    $insertResult = $mysqli->query( $insertQuery );

    close_database( $insertResult, $mysqli );

    return $insertResult;
}

return FALSE;
}

А вот код извлечения:

$selectQuery = "SELECT `abstract_file_name`, `abstract_file_mime_type`, `abstract_file`
FROM `paper_submissions`
WHERE `id` = ".db_value( $mysqli, $id );


$result = $mysqli->query( $selectQuery );

if( $result != FALSE ) {
if( $result->num_rows ) {
    $paper = $result->fetch_array( MYSQL_ASSOC );

    $fileSize = strlen( $paper['abstract_file'] );

    header( 'Date: '.gmdate( "D, d M Y H:i:s" ).' GMT' );
    header( 'Expires: Thu, 19 Nov 1981 08:52:00 GMT' );
    header( 'Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0' );
    header( 'Pragma: no-cache' );
    header( 'Content-Type: '.$paper['abstract_file_mime_type'].'; charset=utf-8' );
    header( 'Content-Length: '.$paper['abstract_file_size'] );
    header( 'Content-Disposition: inline; filename="'.$paper['abstract_file_name'].'"' );
    echo $paper['abstract_file'];
    exit();
}
}
person Community    schedule 19.05.2009

Олафур,

Я понял это из руководства по php и даже попробовал следующее:

$search = array( "\\0", "\\n", "\\r", "\\\\", "\\'", "\\\"", "\Z", );
$replace = array( "\x00", "\n", "\r", "\\", "'", "\"", "\x1a" );
$desiredString = str_replace( $search, $replace, $escapedString );

Кажется, это отлично работает при работе с текстом, но применение его к двоичным данным только еще больше ухудшает PDF (например, пропадают абзацы).

person Community    schedule 19.05.2009
comment
У вас могут быть обычные данные, соответствующие этим критериям, поэтому их трудно исправить. - person Ólafur Waage; 20.05.2009