php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77546 iptcembed broken function
Submitted: 2019-01-30 10:24 UTC Modified: 2019-02-08 09:40 UTC
From: php at degoulet dot net Assigned: nikic (profile)
Status: Closed Package: *Graphics related
PHP Version: 7.3.1 OS: linux
Private report: No CVE-ID: None
 [2019-01-30 10:24 UTC] php at degoulet dot net
Description:
------------
iptcembed ( string $iptcdata , string $jpeg_file_name [, int $spool = 0 ] ) : mixed

when spool is < 2, this function should return a valid jpeg stream content.
on php 7.3 branch, sometime the stream is not valid : this bug this to be related to this commit https://github.com/php/php-src/commit/4fbff82c1079f2c48c769c94f0d9269be7508a59#diff-98113f2c152c3d95d366989462658a39

ext/standard/iptc.c +278

actual code
psheader[ 2 ] = (char) (iptcdata_len+28)>>8;

patch
psheader[ 2 ] = (char) ((iptcdata_len+28)>>8);


Test script:
---------------
<?php
/*
$file="1x1.jpg";
$ret=imagejpeg(imagecreatetruecolor(1, 1), $file, 100);
echo md5(file_get_contents($file)).PHP_EOL;
echo base64_encode(file_get_contents($file)).PHP_EOL;
unlink($file);
*/

function iptc_make_tag($rec, $data, $value)
  {
    $length = strlen($value);
    $retval = chr(0x1C) . chr($rec) . chr($data);
    if($length < 0x8000) { $retval .= chr($length >> 8) .  chr($length & 0xFF); }
    else { $retval .= chr(0x80) .  chr(0x04) .  chr(($length >> 24) & 0xFF) .  chr(($length >> 16) & 0xFF) .  chr(($length >> 8) & 0xFF) .  chr($length & 0xFF); }
    return $retval . $value;
  }


$file="1x1.jpg";
$file2="1x1_with_iptc_tags.jpg";
$base64_1x1_jpeg="/9j/4AAQSkZJRgABAQEAYABgAAD//gA8Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2ODApLCBxdWFsaXR5ID0gMTAwCv/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/bAEMBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAEAAQMBEQACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP8AP/oA/9k=";
#write file
$fd=fopen($file,"wb");
if ($fd) { fputs($fd,base64_decode($base64_1x1_jpeg)); fclose($fd); }
#check file md5
$md5=md5_file($file);
if ($md5!="07dd8594450e8c18ab8a79d7cb4573c7") { echo "md5 error".PHP_EOL;exit(1); }
#check jpeg properties
list($width, $height, $type, $attr) = getimagesize($file,$info);
if ($width!=1) { echo "width error".PHP_EOL;exit(1); }
if ($height!=1) { echo "height error".PHP_EOL;exit(1); }
if ($type!=2) { echo "type error".PHP_EOL;exit(1); }
if (!isset($info["APP0"])) { echo "APP0 error".PHP_EOL;exit(1); }

#our iptc tags
$tags=array();
$tags["2#105"]= "Tauren";
$tags["2#120"]= "Tauren with Trunk";
$tags["2#110"]= "Copyright 2004-2016, Blizzard";
$tags["2#025"]= "Tauren, Chaman, Blizzard";
$tags["2#090"]= "Thunder Bluffs";
#feed iptc string for iptcembed
$iptc='';
foreach ($tags as $tag => $string) { $rec=$tag[0]; $tag = substr($tag, 2); $iptc .= iptc_make_tag($rec, $tag, $string); }
#check iptc string md5
if (md5(base64_encode($iptc))!="7056c4b3060f92a4f9e5b7d0caa61859") { echo "iptc md5 error".PHP_EOL;exit(1); }

#
$content = iptcembed($iptc, $file,0);
if ($content === false) {echo "iptcembed error".PHP_EOL;exit(1); }
$fd=fopen($file2,"wb");
if ($fd) { fputs($fd,$content); fclose($fd); }

#check jpeg properties for new image with iptc tags
echo "new generated image with itpc tags : $file2".PHP_EOL;
$ret = getimagesize($file2,$info);
if ($ret===false) { echo "getimagesize error".PHP_EOL;exit(1); }
list($width, $height, $type, $attr) = $ret;
if ($width!=1) { echo "width error".PHP_EOL;exit(1); }
if ($height!=1) { echo "height error".PHP_EOL;exit(1); }
if ($type!=2) { echo "type error".PHP_EOL;exit(1); }
if (!isset($info["APP0"])) { echo "APP0 error".PHP_EOL;exit(1); }
if (!isset($info["APP13"])) { echo "APP13 error".PHP_EOL;exit(1); }

$error=0;
$iptc_data_from_created_image = iptcparse($info['APP13']);
foreach ($tags as $tag => $string) {
  #check if tag exists
  if (!isset($iptc_data_from_created_image[$tag])) {
    echo "error iptc tag $tag not found".PHP_EOL;
    $error++;
  } else {
    #check value
    if ($iptc_data_from_created_image[$tag][0]!=$string) {
      echo "error tag $tag : bad value ($string != ".$iptc_data_from_created_image[$tag][0].")".PHP_EOL;
      $error++;
    }
  }
}
if ($error==0) { echo "OK".PHP_EOL;exit(0);}
echo "something wrong: $error errors".PHP_EOL;
@unlink($file);
@unlink($file2);
?>

Expected result:
----------------
on php 7.2, my debug script returns


new generated image with itpc tags : 1x1_with_iptc_tags.jpg
OK


Actual result:
--------------
on php 7.3, my debug script returns

generated image : 1x1_with_iptc_tags.jpg
getimagesize error

Patches

patch-iptc (last revision 2019-01-30 10:24 UTC by php at degoulet dot net)

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-01-30 10:42 UTC]
The following pull request has been associated:

Patch Name: bug: https://bugs.php.net/bug.php?id=77546
On GitHub:  https://github.com/php/php-src/pull/3774
Patch:      https://github.com/php/php-src/pull/3774.patch
 [2019-01-30 16:11 UTC] krakjoe@php.net
Automatic comment on behalf of g.degoulet@of2m.fr
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f27f9022660d28c13c6209f4679768dcbd961b43
Log: Fix #77546 iptcembed broken function
 [2019-01-30 16:11 UTC] krakjoe@php.net
-Status: Open +Status: Closed
 [2019-02-06 07:48 UTC] imagevuex at gmail dot com
+1

PHP 7.3 breaks our gallery app as iptcembed() is corrupting JPG images (getimagesize error). Looking forward to see this fixed.
 [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
 [2019-02-08 09:32 UTC] php at degoulet dot net
commit f27f9022660d28c13c6209f4679768dcbd961b43 not integrated on php 7.3.2 ?? 

https://github.com/php/php-src/commit/f27f9022660d28c13c6209f4679768dcbd961b43
 [2019-02-08 09:40 UTC] nikic@php.net
-Assigned To: +Assigned To: nikic
 [2019-02-08 09:40 UTC] nikic@php.net
This change will be part of PHP 7.3.3.
 [2019-03-09 09:07 UTC] imagevuex at gmail dot com
Thanks for the fix in PHP 7.3.3.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Nov 25 11:01:33 2024 UTC