VirtueMart Forum

VirtueMart 2 + 3 + 4 => Virtuemart Development and bug reports => Topic started by: stAn99 on June 01, 2018, 14:41:32 PM

Title: High CPU on VM3.2.14-official due to thumb recreation
Post by: stAn99 on June 01, 2018, 14:41:32 PM
Hello, we just discovered another bug with VM3.2.14-official which causes large CPU load and thus can put down your site or your browser since images are recreated without checking if the resizing was already done.

for VM 3.2.14 you may want to adjust:
\administrator\components\com_virtuemart\helpers\image.php

fine this code:

/**
* This function actually creates the thumb
* and when it is instanciated with one of the getImage function automatically updates the db
*
* @author Max Milbers
* @param boolean $save Execute update function
* @return name of the thumbnail
*/
public function createThumb($width=0,$height=0) {

if(empty($this->file_url_folder)){
vmError('Couldnt create thumb, no directory given. Activate vmdebug to understand which database entry is creating this error');
vmdebug('createThumb, no directory given',$this);
return FALSE;
}

if(empty($this->file_name)){
vmError('Couldnt create thumb, no name given. Activate vmdebug to understand which database entry is creating this error');
vmdebug('createThumb, no name given',$this);
return false;
}

$synchronise = vRequest::getString('synchronise',false);

if(!VmConfig::get('img_resize_enable') || $synchronise) return;

//now lets create the thumbnail, saving is done in this function
$dim = self::determineWH($width, $height);
$width = $dim['width'];
$height = $dim['height'];

// Don't allow sizes beyond 2000 pixels //I dont think that this is good, should be config
// $width = min($width, 2000);
// $height = min($height, 2000);

$maxsize = false;
$bgred = 255;
$bggreen = 255;
$bgblue = 255;

$root = '';
$this->file_name_thumb = $this->createThumbName($width,$height);

if($this->file_is_forSale==0){
$rel_path = str_replace('/',DS,$this->file_url_folder);
$fullSizeFilenamePath = VMPATH_ROOT.DS.$rel_path.$this->file_name.'.'.$this->file_extension;
} else {
$fullSizeFilenamePath = $this->file_url_folder.$this->file_name.'.'.$this->file_extension;
}

$file_path_thumb = str_replace('/',DS,$this->file_url_folder_thumb);
$resizedFilenamePath = VMPATH_ROOT.DS.$file_path_thumb.$this->file_name_thumb.'.'.$this->file_extension;

$this->checkPathCreateFolders($file_path_thumb);

if (file_exists($fullSizeFilenamePath)) {
if (!class_exists('Img2Thumb')) require(VMPATH_ADMIN.DS.'helpers'.DS.'img2thumb.php');
$createdImage = new Img2Thumb($fullSizeFilenamePath, (int)$width, (int)$height, $resizedFilenamePath, $maxsize, $bgred, $bggreen, $bgblue);
if($createdImage){
return $this->file_url_folder_thumb.$this->file_name_thumb.'.'.$this->file_extension;
} else {
return 0;
}
} else {
vmError('Couldnt create thumb, file not found '.$fullSizeFilenamePath);
return 0;
}

}


and replace with:

/**
* This function actually creates the thumb
* and when it is instanciated with one of the getImage function automatically updates the db
*
* @author Max Milbers
* @param boolean $save Execute update function
* @return name of the thumbnail
*/
public function createThumb($width=0,$height=0) {

if(empty($this->file_url_folder)){
vmError('Couldnt create thumb, no directory given. Activate vmdebug to understand which database entry is creating this error');
vmdebug('createThumb, no directory given',$this);
return FALSE;
}

if(empty($this->file_name)){
vmError('Couldnt create thumb, no name given. Activate vmdebug to understand which database entry is creating this error');
vmdebug('createThumb, no name given',$this);
return false;
}

$synchronise = vRequest::getString('synchronise',false);

if(!VmConfig::get('img_resize_enable') || $synchronise) return;

//now lets create the thumbnail, saving is done in this function
$dim = self::determineWH($width, $height);
$width = $dim['width'];
$height = $dim['height'];

// Don't allow sizes beyond 2000 pixels //I dont think that this is good, should be config
// $width = min($width, 2000);
// $height = min($height, 2000);

$maxsize = false;
$bgred = 255;
$bggreen = 255;
$bgblue = 255;

$root = '';
$this->file_name_thumb = $this->createThumbName($width,$height);

if($this->file_is_forSale==0){
$rel_path = str_replace('/',DS,$this->file_url_folder);
$fullSizeFilenamePath = VMPATH_ROOT.DS.$rel_path.$this->file_name.'.'.$this->file_extension;
} else {
$fullSizeFilenamePath = $this->file_url_folder.$this->file_name.'.'.$this->file_extension;
}

$file_path_thumb = str_replace('/',DS,$this->file_url_folder_thumb);
$resizedFilenamePath = VMPATH_ROOT.DS.$file_path_thumb.$this->file_name_thumb.'.'.$this->file_extension;
if (file_exists($resizedFilenamePath)) {
return $this->file_url_folder_thumb.$this->file_name_thumb.'.'.$this->file_extension;
}
$this->checkPathCreateFolders($file_path_thumb);

if (file_exists($fullSizeFilenamePath)) {
if (!class_exists('Img2Thumb')) require(VMPATH_ADMIN.DS.'helpers'.DS.'img2thumb.php');
$createdImage = new Img2Thumb($fullSizeFilenamePath, (int)$width, (int)$height, $resizedFilenamePath, $maxsize, $bgred, $bggreen, $bgblue);
if($createdImage){
return $this->file_url_folder_thumb.$this->file_name_thumb.'.'.$this->file_extension;
} else {
return 0;
}
} else {
vmError('Couldnt create thumb, file not found '.$fullSizeFilenamePath);
return 0;
}

}


new code added to the function above is:


if (file_exists($resizedFilenamePath)) {
return $this->file_url_folder_thumb.$this->file_name_thumb.'.'.$this->file_extension;
}



original issue was caused by this backtrace:

/administrator/components/com_virtuemart/helpers/img2thumb.php 96<br />
/administrator/components/com_virtuemart/helpers/image.php 192<br />
/administrator/components/com_virtuemart/helpers/mediahandler.php 531<br />
/templates/avant/html/com_virtuemart/category/default.php 248<br />
/libraries/src/MVC/View/HtmlView.php 695<br />
/components/com_virtuemart/helpers/vmview.php 40<br />
/components/com_virtuemart/views/category/view.html.php 509<br />
/components/com_virtuemart/controllers/category.php 54<br />
/libraries/src/MVC/Controller/BaseController.php 710<br />
/components/com_virtuemart/virtuemart.php 126<br />
/libraries/src/Component/ComponentHelper.php 382<br />
/libraries/src/Component/ComponentHelper.php 357<br />
/libraries/src/Application/SiteApplication.php 194<br />
/libraries/src/Application/SiteApplication.php 233<br />
/libraries/src/Application/CMSApplication.php 195<br />
/index.php 49<br />




if you need support while using our RuposTel.com extensions, please use our official forum here:
https://www.rupostel.com/phpBB3/posting.php?mode=edit&f=7&p=7679

i hope this helps, best regards, stan
Title: Re: High CPU on VM3.2.14-official due to thumb recreation
Post by: Studio 42 on June 01, 2018, 15:56:00 PM
Hi, I had similar problem, but this was because optiPNG image was not recognized as  image by internal Virtuemart code, so he recreated the thumb and i loosed optiPNG generated image.
But the problem is perhaps because in Img2Thumb > new creates new image at maxSize modification ?
Have you checked if your patch is compatible with it ?