phpmetadatajpegphp-7.3iptc

iptcembed() corrupts JPG data


It seems that PHP's iptcembed() function corrupts JPG files.
This demonstration extracts the IPTC data and immediately embeds it again:

// extract IPTC data
getimagesize($sourceFile,$info);
$iptcData = $info['APP13'];

// embed IPTC data
$newFile = iptcembed($iptcData,$sourceFile);

// write new file to disk
$fp = fopen($sourceFile,"w");
fwrite($fp,newFile);
fclose($fp);

// get size of file
$size = getimagesize($sourceFile,$info);

Warning: getimagesize(): corrupt JPEG data: 1382 extraneous bytes before marker in example.php on line XX

What's going wrong?


Solution

  • PHP bug #77546 was reported January 30, 2019:

    on php 7.3 branch, sometime the stream is not valid

    This affects PHP versions 7.3.0, 7.3.1 and 7.3.2.
    A patch was issued and the bug is fixed in PHP 7.3.3.

    [2019-02-08 09:40 UTC] nikic@php.net
    This change will be part of PHP 7.3.3.

    I have verified that the bug doesn't exist in PHP 7.2 or 7.4.


    A temporary solution was also offered:

    [2019-02-08 05:06 UTC] imagevuex at gmail dot com
    Temporary solution, check if the image stream is valid with getimagesizefromstring() before writing to file:

    $content = iptcembed($iptc, $file,0);
    if($content && @getimagesizefromstring($content)) // is valid
    

    Also see PHP 7.3 Critical Bug Warning, which offers this method of detecting image corruption:

    // PHP 7.3 bug https://bugs.php.net/bug.php?id=77546
    // detect if image is corrupt before writing
    if(
        version_compare(PHP_VERSION, '7.3') >= 0 && 
        version_compare(PHP_VERSION, '7.3.3') < 0 && 
        !@getimagesizefromstring($content)
    ) return;