From d55152a18dd44b82c292d928f1d9b4d18f90fbc0 Mon Sep 17 00:00:00 2001 From: Wouter van der Loop | Toppy <40226924+wouter-toppy@users.noreply.github.com> Date: Fri, 15 Oct 2021 11:43:23 +0200 Subject: [PATCH] [FIX] CompileError: Array and string offset access --- src/GifCreator/AnimGif.php | 166 ++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/src/GifCreator/AnimGif.php b/src/GifCreator/AnimGif.php index 727ac6c..b33c864 100644 --- a/src/GifCreator/AnimGif.php +++ b/src/GifCreator/AnimGif.php @@ -45,7 +45,7 @@ /** * Create an animated GIF from multiple images - * + * * @link https://github.com/lunakid/AnimGif * @author Sybio (Clément Guillemain / @Sybio01), lunakid (@GitHub, @Gmail, @SO etc.) * @license http://opensource.org/licenses/gpl-license.php GNU Public License @@ -94,10 +94,10 @@ class AnimGif * @var array */ private static $errors; - + // Methods // =================================================================================== - + public function __construct() { $this->reset(); @@ -114,20 +114,20 @@ public function __construct() /** * Create animated GIF from source images - * - * @param array $frames The source iamges: can be a local dir path, or an array + * + * @param array $frames The source iamges: can be a local dir path, or an array * of file paths, resource image variables, binary data or image URLs. - * @param array|number $durations The duration (in 1/100s) of the individual frames, + * @param array|number $durations The duration (in 1/100s) of the individual frames, * or a single integer for each one. * @param integer $loop Number of loops before stopping the animation (set to 0 for infinite looping). - * + * * @return string The resulting GIF binary data. */ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) { $last_duration = self::DEFAULT_DURATION; // used only if $durations is an array - - $this->loop = ($loop > -1) ? $loop : 0; // Negatives would be fine for the GIF itself (all unsigned!), + + $this->loop = ($loop > -1) ? $loop : 0; // Negatives would be fine for the GIF itself (all unsigned!), // but better not take a chance with the PHP bit-ops... $this->dis = 2; // "reset to bgnd." (http://www.matthewflickinger.com/lab/whatsinagif/animation_and_transparency.asp) @@ -136,16 +136,16 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) $frames_dir = $frames; if (@is_dir($frames_dir)) { if ($frames = scandir($frames_dir)) { - $frames = array_filter($frames, function($x) { + $frames = array_filter($frames, function($x) { // Should these two below be selectable? return $x[0] != "."; // Or: $x != "." && $x != ".."; }); - array_walk($frames, function(&$x, $i) use ($frames_dir) { + array_walk($frames, function(&$x, $i) use ($frames_dir) { $x = "$frames_dir/$x"; }); } } - + if (!is_array($frames)) { // i.e. scandir() failed above! throw new \Exception(VERSION.': ' . sprintf(self::$errors['ERR05'], $frames_dir)); // $frames is expected to be a string here; see the other ERR05 case! @@ -172,11 +172,11 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) if (substr($this->frameSources[$i], 0, 6) != 'GIF87a' && substr($this->frameSources[$i], 0, 6) != 'GIF89a') { throw new \Exception(VERSION.': '.$i.' '.self::$errors['ERR01']); } - + } elseif (is_string($frame)) { // file path, URL or binary data - + if (@is_readable($frame)) { // file path - $bin = file_get_contents($frame); + $bin = file_get_contents($frame); } else if (filter_var($frame, FILTER_VALIDATE_URL)) { if (ini_get('allow_url_fopen')) { $bin = @file_get_contents($frame); @@ -186,10 +186,10 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) } else { $bin = $frame; } - + if (! ($bin && ($resourceImg = imagecreatefromstring($bin))) ) { - throw new \Exception(VERSION.': '.$i.' ' + throw new \Exception(VERSION.': '.$i.' ' . sprintf(self::$errors['ERR05'], substr($frame, 0, 200))); //!! $frame may be binary data, not a name! } @@ -197,7 +197,7 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) imagegif($resourceImg); $this->frameSources[] = ob_get_contents(); ob_end_clean(); - + } else { // Fail throw new \Exception(VERSION.': '.self::$errors['ERR02']); } @@ -206,18 +206,18 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) $this->transparent_color = imagecolortransparent($resourceImg); } - for ($j = (13 + 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))), $k = TRUE; $k; $j++) { - - switch ($this->frameSources[$i] { $j }) { - + for ($j = (13 + 3 * (2 << (ord($this->frameSources[$i] [ 10 ]) & 0x07))), $k = TRUE; $k; $j++) { + + switch ($this->frameSources[$i] [ $j ]) { + case '!': if ((substr($this->frameSources[$i], ($j + 3), 8)) == 'NETSCAPE') { - + throw new \Exception(VERSION.': '.self::$errors['ERR03'].' ('.($i + 1).' source).'); } - + break; - + case ';': $k = false; break; @@ -252,26 +252,26 @@ public function create($frames, $durations = self::DEFAULT_DURATION, $loop = 0) /** * Get the resulting GIF image binary - * + * * @return string */ public function get() { return $this->gif; } - + /** * Save the resulting GIF to a file. - * + * * @param $filename String Target file path - * + * * @return that of file_put_contents($filename) */ public function save($filename) { return file_put_contents($filename, $this->gif); } - + /** * Clean-up the current object (also used by the ctor.) */ @@ -284,7 +284,7 @@ public function reset() $this->dis = 2; $this->transparent_color = -1; } - + // Internals // =================================================================================== @@ -295,9 +295,9 @@ protected function gifAddHeader() { $cmap = 0; - if (ord($this->frameSources[0] { 10 }) & 0x80) { - - $cmap = 3 * (2 << (ord($this->frameSources[0] { 10 }) & 0x07)); + if (ord($this->frameSources[0] [ 10 ]) & 0x80) { + + $cmap = 3 * (2 << (ord($this->frameSources[0] [ 10 ]) & 0x07)); $this->gif .= substr($this->frameSources[0], 6, 7); $this->gif .= substr($this->frameSources[0], 13, $cmap); @@ -305,95 +305,95 @@ protected function gifAddHeader() $this->gif .= "!\xFF\x0BNETSCAPE2.0\x03\x01".word2bin($this->loop==0?0:$this->loop-1)."\x0"; } } - + /** * Add frame to the GIF data - * + * * @param integer $i: index of frame source * @param integer $d: delay time (frame display duration) */ protected function addGifFrames($i, $d) { - $Locals_str = 13 + 3 * (2 << (ord($this->frameSources[ $i ] { 10 }) & 0x07)); + $Locals_str = 13 + 3 * (2 << (ord($this->frameSources[ $i ] [ 10 ]) & 0x07)); $Locals_end = strlen($this->frameSources[$i]) - $Locals_str - 1; $Locals_tmp = substr($this->frameSources[$i], $Locals_str, $Locals_end); - $Global_len = 2 << (ord($this->frameSources[0 ] { 10 }) & 0x07); - $Locals_len = 2 << (ord($this->frameSources[$i] { 10 }) & 0x07); + $Global_len = 2 << (ord($this->frameSources[0 ] [ 10 ]) & 0x07); + $Locals_len = 2 << (ord($this->frameSources[$i] [ 10 ]) & 0x07); - $Global_rgb = substr($this->frameSources[ 0], 13, 3 * (2 << (ord($this->frameSources[ 0] { 10 }) & 0x07))); - $Locals_rgb = substr($this->frameSources[$i], 13, 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))); + $Global_rgb = substr($this->frameSources[ 0], 13, 3 * (2 << (ord($this->frameSources[ 0] [ 10 ]) & 0x07))); + $Locals_rgb = substr($this->frameSources[$i], 13, 3 * (2 << (ord($this->frameSources[$i] [ 10 ]) & 0x07))); $Locals_ext = "!\xF9\x04" . chr(($this->dis << 2) + 0) . word2bin($d) . "\x0\x0"; - if ($this->transparent_color > -1 && ord($this->frameSources[$i] { 10 }) & 0x80) { - - for ($j = 0; $j < (2 << (ord($this->frameSources[$i] { 10 } ) & 0x07)); $j++) { - - if (ord($Locals_rgb { 3 * $j + 0 }) == (($this->transparent_color >> 16) & 0xFF) && - ord($Locals_rgb { 3 * $j + 1 }) == (($this->transparent_color >> 8) & 0xFF) && - ord($Locals_rgb { 3 * $j + 2 }) == (($this->transparent_color >> 0) & 0xFF) + if ($this->transparent_color > -1 && ord($this->frameSources[$i] [ 10 ]) & 0x80) { + + for ($j = 0; $j < (2 << (ord($this->frameSources[$i] [ 10 ] ) & 0x07)); $j++) { + + if (ord($Locals_rgb [ 3 * $j + 0 ]) == (($this->transparent_color >> 16) & 0xFF) && + ord($Locals_rgb [ 3 * $j + 1 ]) == (($this->transparent_color >> 8) & 0xFF) && + ord($Locals_rgb [ 3 * $j + 2 ]) == (($this->transparent_color >> 0) & 0xFF) ) { $Locals_ext = "!\xF9\x04".chr(($this->dis << 2) + 1).chr(($d >> 0) & 0xFF).chr(($d >> 8) & 0xFF).chr($j)."\x0"; break; } } } - - switch ($Locals_tmp { 0 }) { - + + switch ($Locals_tmp [ 0 ]) { + case '!': - + $Locals_img = substr($Locals_tmp, 8, 10); $Locals_tmp = substr($Locals_tmp, 18, strlen($Locals_tmp) - 18); - + break; - + case ',': - + $Locals_img = substr($Locals_tmp, 0, 10); $Locals_tmp = substr($Locals_tmp, 10, strlen($Locals_tmp) - 10); - + break; } - - if (ord($this->frameSources[$i] { 10 }) & 0x80 && $this->imgBuilt) { - + + if (ord($this->frameSources[$i] [ 10 ]) & 0x80 && $this->imgBuilt) { + if ($Global_len == $Locals_len) { - + if ($this->gifBlockCompare($Global_rgb, $Locals_rgb, $Global_len)) { - + $this->gif .= $Locals_ext.$Locals_img.$Locals_tmp; - + } else { - - $byte = ord($Locals_img { 9 }); + + $byte = ord($Locals_img [9]); $byte |= 0x80; $byte &= 0xF8; - $byte |= (ord($this->frameSources[0] { 10 }) & 0x07); - $Locals_img { 9 } = chr($byte); + $byte |= (ord($this->frameSources[0] [ 10 ]) & 0x07); + $Locals_img [9] = chr($byte); $this->gif .= $Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp; } - + } else { - - $byte = ord($Locals_img { 9 }); + + $byte = ord($Locals_img [9]); $byte |= 0x80; $byte &= 0xF8; - $byte |= (ord($this->frameSources[$i] { 10 }) & 0x07); - $Locals_img { 9 } = chr($byte); + $byte |= (ord($this->frameSources[$i] [ 10 ]) & 0x07); + $Locals_img [9] = chr($byte); $this->gif .= $Locals_ext.$Locals_img.$Locals_rgb.$Locals_tmp; } - + } else { - + $this->gif .= $Locals_ext.$Locals_img.$Locals_tmp; } - + $this->imgBuilt = true; } - + /** * Add the gif string footer char */ @@ -401,38 +401,38 @@ protected function gifAddFooter() { $this->gif .= ';'; } - + /** * Compare two blocks and return 1 if they are equal, 0 if differ. - * + * * @param string $globalBlock * @param string $localBlock * @param integer $length - * + * * @return integer */ protected function gifBlockCompare($globalBlock, $localBlock, $length) { for ($i = 0; $i < $length; $i++) { - + if ($globalBlock [ 3 * $i + 0 ] != $localBlock [ 3 * $i + 0 ] || $globalBlock [ 3 * $i + 1 ] != $localBlock [ 3 * $i + 1 ] || $globalBlock [ 3 * $i + 2 ] != $localBlock [ 3 * $i + 2 ]) { - + return 0; } } return 1; } - + } /** * Convert an integer to 2-byte little-endian binary data - * + * * @param integer $word Number to encode - * + * * @return string of 2 bytes representing @word as binary data */ function word2bin($word)