1.9.2.0에서 Varien_Image_Adapter_Gd2의 새로운 소멸자와의 ImportExport 문제 register_shutdown_function(array($this, ‘destruct’)); } /**

누군가가 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;
    }
}


답변