Фон:
Я работал над проблемой, при которой форма загрузки файла будет принимать только определенные изображения, это не проблема с размером изображения (размерами) или с размером (размером файла), но я думаю, что я обнаружил, что это связано с битовой глубиной изображения, поскольку PHP-скрипт изменяет размер изображения и применяет к изображению статический (полупрозрачный) файл водяных знаков и сохраняет результат.
Сегодня и вчера я прошел долгий процесс, работая с этим, так как ошибка, возникающая на сервере «Сброс соединения сервером» . Который я считать Я ограничился тем, что на сервере недостаточно свободной памяти для выполнения манипуляций с ресурсами изображения.
Выпуск:
Затем, после всего этого, эта ошибка появляется при отправке файла:
Обнаружен IPS для «WEB PHP EXIF Process IFD TAG Удаленное целочисленное переполнение -2 (CVE-20 / переполнение буфера»)
Гугл только говорит мне, что это секретная уязвимость для PHP < 4.2 или около того, и не имеет отношения к тому, что происходит на самом деле.
Я просмотрел свой код и очень уверен, что
Мой запрос состоит в том, чтобы попытаться пролить некоторый свет на то, что означает это заявление об ошибке (и как я могу исправить его)?
Заметки:
PHP 5.6.16
На странице не работают функции PHP EXIF.
Я не вижу нигде на странице, что могло бы вызвать переполнение целых чисел (я думаю, до бесконечности)
Страница использует imagecopy
, imagealphablending
а также imagesavealpha
Но это сообщение об ошибке кажется появляться до запуска скрипта в загруженном файле.
Эта ошибка возникает только на немного загруженные изображения, а не на других.
Я не нашел журналов ошибок Apache, связанных с этим
У меня нет ошибок PHP.
Код:
Как мне кажется, проблема может произойдет как-то до загрузки страницы, я не уверен, насколько полезным будет этот блок кода, но посмотрите:
(также обратите внимание, что я знаю, что этой странице уже 5 лет и она не самая умная в программировании, я исправил ее по частям, но знаю, что, возможно, ее можно будет привести в порядок)
<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);
///first set out variables.
$goodImage = 0;
$maxfilesize = (int)$_POST['MAX_FILE_SIZE'];
$gallery = (int)$_POST['galfolderid']
if (empty($gallery)) {
$_SESSION['message'] = $gallery . "<br/>Gallery Value has not been set.";
}
elseif (!is_numeric($gallery)) {
$_SESSION['message'] = $gallery . "<br/>Gallery Value is not a numeric value.";
}
elseif (!is_dir($_SERVER['DOCUMENT_ROOT']."/images/gallery/" . $gallery )) {
$_SESSION['message'] = $gallery . "<br/>Gallery Value, while being a number, is not a valid numeric value.";
}
if(!empty($_SESSION['message'])) {
header("Location:editgallery.php?gallery=".$galleryid);
exit;
}
for($count=0;$count<5;$count++) {
if ($_FILES['image']['error'][$count] == 0) {
clearstatcache();
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$imageType = finfo_file($finfo, $_FILES['image']['tmp_name'][$count]);
finfo_close($finfo);
unset($finfo);
if (strtolower($imageType) == "image/png") {
$imgtype = "PNG";
$original = imagecreatefrompng($_FILES['image']['tmp_name'][$count]);
} elseif (strtolower($imageType) == "image/jpeg" || strtolower($imageType) == "image/jpg") {
$imgtype = "JPG";
$original = imagecreatefromjpeg($_FILES['image']['tmp_name'][$count]);
} else {
//not a JPG or PNG type... set error.
$_SESSION['message'] = "Image " . ($count+1) . " does not appear to be a valid .JPG or .PNG file. ";
error_log($_SESSION['message']);
header("Location:editgallery.php");
exit;
}
unlink($_FILES['image']['tmp_name'][$count]);
$edgePadding = (int)$_POST['WMedge'][$count]; //integer
$watermarkScale = $_POST['WMscale'][$count]; //float
$h_position = $_POST['Hpos'][$count]; //text array
$v_position = $_POST['Vpos'][$count]; //text array
$Hoz = $h_position[0];
$Vez = $v_position[0];if (!isset($watermarkScale) || empty($watermarkScale) || !is_numeric($watermarkScale)) {
$watermarkScale = 1.0;
}
elseif($watermarkScale > 2.0) {
$watermarkScale = 2.0;
}
elseif($watermarkScale < 0.5) {
$watermarkScale = 0.5;
}
if ((!isset($edgePadding) || empty($edgePadding) || !is_numeric($edgePadding)) && $edgePadding !== "0") {
$edgePadding = 5;
}
// be sure that the other options we need have some kind of value
if ($_FILES['image']['size'][$count] > $maxfilesize) {
$_SESSION['message'] .= "Image file ".($count+1)." appears to be too big. There is a limit of 2Mb on the
size of the image you can upload. Please click 'Back' on your browser and resubmit a valid image.";
error_log($_SESSION['message']);
//file too big.
}
//target name is the number of images in the LARGE gallery,
///cycle through imagenames to find the first "clear" image number.
$newimagename = 1;
clearstatcache();
/***
NOTE: Only possible place an integer oveflow might occur I think
***/
while (file_exists($_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $gallery . "/S/" . $newimagename . ".jpg")) {
$newimagename++;
}
///newimagename is the new filename of the image.$target_name = $newimagename . ".jpg";
$target = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $gallery . "/L/" . $target_name;
$targetSmall = $_SERVER['DOCUMENT_ROOT'] . "/images/gallery/" . $gallery . "/S/" . $target_name;
//targetSM is used below to make the thumbnail image. for the SMALL gallery.
//full target directory and name.
// file upload success
// now file need resizing before the watermark is applied.
// resize new dimensions (Large- 800px)
$originalImageSize[0] = imagesx($original);
$originalImageSize[1] = imagesy($original);
/***
* Resize new dimensions for small thumbnail.
***/
if ($originalImageSize[0] > 133) {
$percent = 133 / $originalImageSize[0];
} else {
$percent = 1;
}
$newThumbHeight = $originalImageSize[1] * $percent;
$newThumbWidth = $originalImageSize[0] * $percent;
// Resample
$imageThumbFinal = imagecreatetruecolor($newThumbWidth, $newThumbHeight);
imagecopyresampled($imageThumbFinal, $original, 0, 0, 0, 0, $newThumbWidth, $newThumbHeight, $originalImageSize[0], $originalImageSize[1]);
// Output
imagejpeg($imageThumbFinal, $targetSmall, 80);
imagedestroy($imageThumbFinal);
unset($imageThumbFinal, $percent,$newThumbWidth,$newThumbHeight);
/***
* End Thumbnail generation.
*/
/***
* Resize main sized image (max 800px wide)
***/
if ($originalImageSize[0] > 800) {
$percent = 800 / $originalImageSize[0];
} else {
$percent = 1;
}
$newPictureHeight = $originalImageSize[1] * $percent;
$newPictureWidth = $originalImageSize[0] * $percent;
// Resample main image to reduce max size.
$imageCleanFinal = imagecreatetruecolor($newPictureWidth, $newPictureHeight);
imagecopyresampled($imageCleanFinal, $original, 0, 0, 0, 0, $newPictureWidth, $newPictureHeight, $originalImageSize[0], $originalImageSize[1]);/***
* Now resize the watermark and save onto the final image.
***/
//full target directory and name.
$watermark = $_SERVER['DOCUMENT_ROOT'] . "/images/watermark2.png";
$wmTarget = substr($watermark, 0, -3) . "tmp"; //image/watermark2.tmp is resized.
$sourceWaterImage = imagecreatefrompng($watermark);
$waterMarkWidth = imagesx($sourceWaterImage);
$waterMarkHeight = imagesy($sourceWaterImage);
$destinationHeight = $waterMarkHeight * $watermarkScale;
$destinationWidth = $waterMarkWidth * $watermarkScale;
$destinationHeight = floor($destinationHeight);
$destinationWidth = floor($destinationWidth);
$destinationWatermarkImage = imagecreatetruecolor($destinationWidth, $destinationHeight);
imagealphablending($destinationWatermarkImage, FALSE);
imagesavealpha($destinationWatermarkImage, TRUE);
imagecopyresampled($destinationWatermarkImage, $sourceWaterImage, 0, 0, 0, 0, $destinationWidth,
$destinationHeight, $waterMarkWidth, $waterMarkHeight);
imagedestroy($sourceWaterImage);
unset($sourceWaterImage);
clearstatcache();
/***
* Set watermark location on final image.
***/
$differenceX = $newPictureWidth - $destinationWidth;
$differenceY = $newPictureHeight - $destinationHeight;
switch ($Hoz) {
// find the X coord for placement
case 'left':
$placementX = $edgePadding;
break;
case 'center':
$placementX = round($differenceX / 2);
break;
case 'right':
$placementX = $newPictureWidth - ($destinationWidth + $edgePadding);
break;
default:
$placementX = 0;
break;
}
switch ($Vez) {
// find the Y coord for placement
case 'top':
$placementY = $edgePadding;
break;
case 'middle':
$placementY = round($differenceY / 2);
break;
case 'bottom':
$placementY = $newPictureHeight - ($destinationHeight + $edgePadding);
break;
default:
$placementY = 0;
break;
}
/***
* Finish set Watermark location
***/
imagecopy($imageCleanFinal,
$destinationWatermarkImage,
$placementX,
$placementY,
0,
0,
$destinationWidth,
$destinationHeight);
imagejpeg($imageCleanFinal, $target, 80);
/***
* Image final save
***/
// Output
imagejpeg($imageCleanFinal, $target, 80);
imagedestroy($imageCleanFinal);
imagedestroy($destinationWatermarkImage);
unset($imageCleanFinal, $percent);
unlink($wmTarget);
$output[$goodImage]['targetName'] = $target_name;
$output[$goodImage]['targetAddr'] = $target;
$goodImage++;
} elseif (!isset($_FILES['image']['name'][$count]) || ($_FILES['image']['error'][$count] != 0 && $_FILES['image']['error'][$count] != 4)) {
//error in file upload.
$_SESSION['message'] .= " There is a file upload error number " . $_FILES['image']['error'][$count] . ". for image ".($count+1).".
Please try resubmitting a valid image.";
error_log($_SESSION['message']);
}
}
if (empty($_SESSION['message'])){
$_SESSION['message'] = $goodImage." New Image(s) Uploaded";
}
// display resulting image for download
header("Location:editgallery.php?special=yes&gallery=".$galleryid);
exit;
Детали сервера:
Apache 2.4
WebHostManger & CPanel (комбинированная) версия 54.0.19
PHP 5.6 используя мод suPHP 0.7.2
2 ядра 2,2 ГГц (т. Х2) Intel с
1896Mb / 2097Mb физической памяти (используется / доступно)
Задача ещё не решена.
Других решений пока нет …