Jump to content

display image inside zip archive - can't read the file if it has special chars


Recommended Posts

This script will find a zip archive in a specific folder, then read an image file inside the zip and output it as jpg. It works perfectly when using a simple image filename, but as soon as the image file has special characters it returns an error "could not load image".

Here's the code:

<?php
function showimage($zip_file, $file_name) {
    $z = new ZipArchive();
    if ($z->open($zip_file) !== true) {
        echo "File not found.";
        return false;
    }

    $stat = $z->statName($file_name);
    $fp   = $z->getStream($file_name);
    if(!$fp) {
        echo "Could not load image.";
        return false;
    }

    header('Content-Type: image/jpeg');
    header('Content-Length: ' . $stat['size']);
    fpassthru($fp);
    return true;
}

$imgsrcencoded = $_GET['i'];
$imagesrc = base64_decode($imgsrcencoded);
$explodez = explode("#",$imagesrc);
$imgg = utf8_encode($explodez[1]);
$dirnfile = $explodez[0];
$zipp = end((explode('/', $dirnfile)));
$dirr = str_replace($zipp,"",$dirnfile);
$dirr = rtrim($dirr,"/");
$imgg = urlencode(rtrim($imgg));
// $zipp = urlencode($zipp);
chdir($dirr);
    if (empty($_GET['debug'])) {
    echo showimage($zipp,$imgg);
    // echo showimage("jpg.zip","test.jpg");
    }




// debug
if (!empty($_GET['debug'])) {
echo "
base64 query = $imgsrcencoded<br>
decoded query = $imgsrc<br>
zipp = $zipp<br>
imgg = $imgg<br>
dirr = $dirr<br>
current directory = ";
echo getcwd();
}
?>


And here's what my debug returns:

 

base64 query = ZGwvcHAvNjI1MC84NiBDcmV3IC0gMjAwMCAtIEJhZCBCYWQgUmVnZ2FlLnppcCM4IDYgQ3JldyAtIEJhZCBCYWQgUmVnZ2FlLWZyb250ICBbd3d3LlBpcmF0ZS1QdW5rLm5ldF0uanBnCg==

decoded query = dl/pp/6250/86 Crew - 2000 - Bad Bad Reggae.zip#8 6 Crew - Bad Bad Reggae-front [www.Pirate-Punk.net].jpg

zipp = 86 Crew - 2000 - Bad Bad Reggae.zip

imgg = 8+6+Crew+-+Bad+Bad+Reggae-front++%5Bwww.Pirate-Punk.net%5D.jpg

dirr = dl/pp/6250

current directory = /var/www/clients/client2/web1/web/dl/pp/6250


So as you can see the script correctly switch to the corresponding directory and it is able to open the zip archive but it fails when come the time to read the JPG file if the filename has special characters

I tried with or without utf8_encode() on the image's filename, i tried with or without urlencode() or rawurlencode() but i always get the same result...

any suggestion ? i'm desperate.

huh..there seems to be a bug with getStatusString .. I tried out your code with an invalid filename and it is indeed returning "No error" ..

 

Okay so do this:

 

   echo "passed filename: ".$file_name. "<br/>";
   echo "files: <br/>";
   $i=0;
   while ($fileName = $z->statIndex($i)) {
     echo $fileName['name'] . "<br/>";
     $i++;
   }
Not sure how big your zip file is so if there's lots of stuff in there then you'll get a lot of stuff echoing out, but goal here is to compare the value you are actually passing to $file_name vs. what is listed in the zip.

Hello,

 

Sorry for late reply, i was away from home.

 

Here's the result:

 

 

Could not load image.
passed filename: 8 6 Crew - Bad Bad Reggae-front [www.Pirate-Punk.net].jpg
files:
86 Crew - 2000 - Bad Bad Reggae/
86 Crew - 2000 - Bad Bad Reggae/01 - You come... [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/02 - Nice town [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/03 - Rude boy escape [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/04 - Prohibition [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/05 - R‚pression [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/06 - The pig [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/07 - Vieille France [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/08 - Bad bad reggae [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/09 - Un doute qui plane [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/10 - Laisses moi rˆver [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/11 - Harmoniska [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/12 - Emeute [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/13 - Worcking class heros [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/14 - Un r“le … jouer [www.Pirate-Punk.net].mp3
86 Crew - 2000 - Bad Bad Reggae/8 6 Crew - Bad Bad Reggae-front [www.Pirate-Punk.net].jpg
86 Crew - 2000 - Bad Bad Reggae/AlbumArtSmall [www.Pirate-Punk.net].jpg
86 Crew - 2000 - Bad Bad Reggae/Folder [www.Pirate-Punk.net].jpg
86 Crew - 2000 - Bad Bad Reggae/Thumbs.db

 

The filename inside the archive and the passed filename seems to be exactly the same thing... I'm really confused.

Okay well no, it's not the same thing.

 

someFile.jpg

 

is not the same as

 

directory/someFile.jpg

 

The file inside your zip is actually inside a directory "86 Crew - 2000 - Bad Bad Reggae/" so you need to include that in what you are passing to getStream

 

Unless you have some other way of knowing exactly where it should be located within the zip, you're gonna have to go with a "best guess" approach. Here is the simplest way you can handle this:

 

// search for a path/to/file matching file, returning the index of it
$index = $z->locateName($file_name, ZipArchive::FL_NOCASE|ZipArchive::FL_NODIR);
// get the name of the file based on the index
$full_file_name = $zip->getNameIndex($index);
// now get the stream
$fp = $z->getStream($full_file_name);
 

So here is the caveat with this:

 

Let's say the zip file contains this:

 

someFile.jpg

dir1/someFile.jpg

dir2/someFile.jpg

 

locateStream returns the first match found, and this may or may not be what you are looking for. Only way to get exactly what you are looking for is to know exactly where to find it. So this approach may be okay for you (maybe your zips will only have the one file in it, and maybe your zips might sometimes actually have the files in a subdir or not).

 

So maybe this will work for you, and if not..you need to figure out some way of enforcing knowledge of exact path/to/file to look for (getting it from a user, doing some manual labor on all your zip file(s) to map things, etc..).

Awesome !!!!!! it seems to be working perfectly now !!!! thanks a lot for the time you spent on this, you were very helpful and explained things very well. I'm going to consider making a donation next month :)

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.