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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: php at degoulet dot net
New email:
PHP Version: OS:

 

 [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 13:01:32 2024 UTC