php - base64_decode creates corrupted image when run in a loop -


this code works fine (but concerned fail large input files). example 1 reads whole file , not loop, example 2 reads 3k chunks , loops until eof.

 $in = fopen("in.b64", 'r');  $out = fopen("out.png", 'wb');  if ((!$in) || (!$out)) die ("convert: i/o error in base64 convert");  $first = true;  while (!feof($in))  {     $b64 = fread($in,filesize($in_fn));     // strip content tag start of stream     if ($first)      {         $b64 = substr($b64,strpos($b64,',')+1);         $first = false;     }     $bin = base64_decode($b64);     if (!fwrite($out,$bin)) die("convert write error in base64 convert");  }  fclose($in);  fclose($out); 

while code produces corrupt image :

 $in = fopen("in.b64", 'r');  $out = fopen("out.png", 'wb');  if ((!$in) || (!$out)) die ("convert: i/o error in base64 convert");  $first = true;  while (!feof($in))  {     $b64 = fread($in,3072);     // strip content tag start of stream     if ($first)      {         $b64 = substr($b64,strpos($b64,',')+1);         $first = false;     }     $bin = base64_decode($b64);     if (!fwrite($out,$bin)) die("convert write error in base64 convert");  }  fclose($in);  fclose($out); 

while 3072 evenly divisible 4, making boundaries line correctly, you're taking characters off of front of it, making not aligned correctly. in addition, base64 spec says have newline every 64 characters, may offset alignment , break parsing too.

my solution below maintains buffer of characters decode, , takes chunks of n*4 characters @ time. test, read in 21 bytes @ time, , seems work. 1 caveat, number of bytes @ time ought more characters expect take off front of string (to comma).

$in = fopen("in.b64", 'r'); $out = fopen("out.txt", 'wb'); if ((!$in) || (!$out)) die ("convert: i/o error in base64 convert"); $first = true; $buffer = ''; while (!feof($in)) {    $b64 = preg_replace("/[\s]+/", "", fread($in,21));    // strip content tag start of stream    if ($first)    {        $b64 = substr($b64,strpos($b64,',')+1);        $first = false;    }    $buffer .= $b64;    $length = strlen($buffer);    $leftover = $length % 4;    if ($leftover == 0)    {      $chunk = $buffer;      $buffer = '';    }    else    {      $chunk = substr($buffer, 0, -$leftover);      $buffer = substr($buffer, $length - $leftover);    }     if (!empty($chunk))    {      $bin = base64_decode($chunk);      if (!fwrite($out,$bin)) die("convert write error in base64 convert");    } } fclose($in); fclose($out); 

Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

qt - Errors in generated MOC files for QT5 from cmake -