누군가가 Magento CE 1.9.1.0과 1.9.2.0 사이에 도입 된 다음 코드가 무엇에 사용되는지 설명 할 수 있습니까?
class Varien_Image_Adapter_Gd2:
public function __construct()
{
// Initialize shutdown function
register_shutdown_function(array($this, 'destruct'));
}
/**
* Destroy object image on shutdown
*/
public function destruct()
{
@imagedestroy($this->_imageHandler);
}
이 두 기능이 추가 된 후 ImportExport 인터페이스를 사용하여 제품 갤러리 이미지 가져 오기가 작동을 멈췄습니다. 오류는 메모리 제한 때문입니다 (최대 열린 파일 크기 제한으로 나타남).
내 생각은 가져 오기로 열린 파일이 올바르게 닫히지 않는다는 것입니다.
또한 빈 destruct()
함수 ( Mage_ImportExport_Model_Import_Adapter_Abstract
)가 도입 되었지만 부모 논리와 일치하도록 확장해도 도움이되지 않습니다.
답변
이미지 리소스를 파괴하려고 시도했지만 메모리 누수가 발생했습니다. 나는이 코드에 대한 타당한 이유를 생각할 수없고, 정직하지만, 무엇이 바뀌 었는지 설명 할 수있다 :
원래 imagedestroy()
디스크립터에서 호출되었을 것입니다__destruct()
function __destruct()
{
@imagedestroy($this->_imageHandler);
}
소멸자는 PHP 가비지 수집기가 사용되지 않는 객체 (즉, 더 이상 참조되지 않는 메모리의 객체)를 삭제할 때마다 호출됩니다.
이제는 종료 함수imagedestroy()
에서 호출되며 이것이 객체 의 메소드에 대한 콜백 이므로 끝까지 가비지 수집조차 할 수 없습니다. 이런 식으로 모든 이미지 리소스는 스크립트 실행이 완료 될 때까지 열려 있습니다.Varien_Image_Adapter_Gd2
답변
내 Magento 1.9.2.0과 동일한 문제가 발생했습니다 …
난 단지 변경 작업이 얻을 Varien_Image_Adapter_Gd2을 에서 /lib/Varien/Image/Adapter/Gd2.php
다음과 같이 :
public function __construct()
{
// Initialize shutdown function
// register_shutdown_function(array($this, 'destruct'));
}
/**
* Destroy object image on shutdown
*/
public function __destruct()
{
@imagedestroy($this->_imageHandler);
}
- register_shutdown_function으로 줄을 제거 하거나 주석 처리하십시오.
- 변경 기능 이름의 파괴 에 __destruct
memory_limit를 1G로 다시 설정했으며 (이전 32GB까지 올렸습니다) 이제 작동합니다 …
이 프로젝트 는 modman 친화적 인 방식으로 상기 절차를 구현합니다. 작곡가와 함께 설치하기 만하면됩니다.
답변
직렬화 해제와 관련된 보안 문제 해결의 일부였습니다. __destruct와 같은 마술 메서드에는 직렬화에 고유 한 문제가 있습니다.
우리는 파일 시스템에서 파일을 생성하기 위해 직렬화와 __destruct를 사용하는 익스플로잇을 제안했습니다.이 변경 (다른 장소에서 더 유사한 변경 사항이 표시됨)은 이것을 피하기 위해 수행되었습니다.
스크립트가 끝날 때까지 메모리 누수가 발생하거나 더 많은 메모리를 사용합니까?
/security/77549/is-php-unserialize-exploitable-without-any-interesting-methods
답변
그래서 이미지 가져 오기 프로세스에서 메모리 사용 문제를 처리해야하는 “솔루션”을 포함하여 Magento에 버그를 제기했습니다.
해결책은 github의 https://github.com/sitewards/import_image_memory_leak_fix 에서 찾을 수 있지만 기본 아이디어는 다음과 같습니다.
이미지 프로세서에서 Mage_Catalog_Helper_Image::validateUploadFile
실제로 destruct
메소드를 호출하도록 수정했습니다 . 슬프게도 기본값 Varien_Image
이 처리되지 않는 것처럼 보이므로 destruct
자체 클래스를 추가해야했습니다.
<?php
/**
* @category Sitewards
* @package Sitewards_ImportImageMemoryLeakFix
* @copyright Copyright (c) Sitewards GmbH (http://www.sitewards.com/)
*/
class Sitewards_ImportImageMemoryLeakFix_Model_Destructable_Image extends Varien_Image
{
/**
* Constructor,
* difference from original constructor - we register a destructor here.
*
* @param string $sFileName
* @param Varien_Image_Adapter $oAdapter Default value is GD2
*/
public function __construct($sFileName = null, $oAdapter = Varien_Image_Adapter::ADAPTER_GD2)
{
parent::__construct($sFileName, $oAdapter);
// Initialize shutdown function
register_shutdown_function(array($this, 'destruct'));
}
/**
* Destroy object image on shutdown
*/
public function destruct()
{
$oAdapter = $this->_getAdapter();
if (method_exists($oAdapter, 'destruct')) {
$oAdapter->destruct();
} else {
Mage::log('Image can not be destructed properly, adapter doesn\'t support the method.');
}
}
}
그런 다음 도우미를 다시 작성하십시오.
<?xml version="1.0"?>
<config>
<modules>
<Sitewards_ImportImageMemoryLeakFix>
<version>0.1.0</version>
</Sitewards_ImportImageMemoryLeakFix>
</modules>
<global>
<models>
<sitewards_importimagememoryleakfix>
<class>Sitewards_ImportImageMemoryLeakFix_Model</class>
</sitewards_importimagememoryleakfix>
</models>
<helpers>
<catalog>
<rewrite>
<image>Sitewards_ImportImageMemoryLeakFix_Helper_Catalog_Helper_Image</image>
</rewrite>
</catalog>
</helpers>
</global>
</config>
그리고 새로운 함수는 새로운 파괴 가능한 이미지 클래스를 호출합니다.
<?php
/**
* @category Sitewards
* @package Sitewards_ImportImageMemoryLeakFix
* @copyright Copyright (c) Sitewards GmbH (http://www.sitewards.com/)
*/
class Sitewards_ImportImageMemoryLeakFix_Helper_Catalog_Helper_Image extends Mage_Catalog_Helper_Image
{
/**
* Check - is this file an image
*
* Difference from original method - we destroy the image object here,
* i.e. we are not wasting memory, without that fix product import with images
* easily goes over 4Gb on memory with just couple hundreds of products.
*
* @param string $sFilePath
*
* @return bool
* @throws Mage_Core_Exception
*/
public function validateUploadFile($sFilePath) {
if (!getimagesize($sFilePath)) {
Mage::throwException($this->__('Disallowed file type.'));
}
/** @var Sitewards_ImportImageMemoryLeakFix_Model_Destructable_Image $oImageProcessor */
$oImageProcessor = Mage::getModel('sitewards_importimagememoryleakfix/destructable_image', $sFilePath);
$sMimeType = $oImageProcessor->getMimeType();
$oImageProcessor->destruct();
return $sMimeType !== null;
}
}