How to fix this download php script that distorts files?

I have a force-download script that gives good results using PDF and plain text and is semi-OK with ZIP archives (they work on Windows, not Linux). However, application files and images do not work. They make up a huge number of files that I have to process. Refusing all downloads, as I said, on these topics is not an option here.

Unsuccessful files are downloaded in full size and written to disk under the correct name. Attempts to open them result in an error message that differs between types. Comparing the downloaded files with their originals in hexdump, I see that the script inserts the following characters at the beginning of each downloaded file:

ef bb bf 

The downloaded file then plays the original until it stops at the specified size - so the original last 6 characters will be missing.

Unfortunately, I do not know anything about how binary files are created, what these symbols can mean, or how / why a script inserts them.

This is the script as it is:

 $file = '94.ppt'; $path = $_SERVER['DOCUMENT_ROOT']."/relative/path/"; $full_path = $path.$file; if ($fd = fopen ($full_path, "r")) { $fsize = filesize($full_path); $path_parts = pathinfo($full_path); $ext = strtolower($path_parts["extension"]); switch ($ext) { case "pdf": header("Content-type: application/pdf"); header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); break; case "txt": header("Content-type: text/plain"); header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); break; case "jpg": header("Content-type: image/jpeg"); header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); break; case "ppt": header("Content-Type: application/vnd.ms-powerpoint"); header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); break; default; header("Content-type: application/octet-stream"); header("Content-Disposition: filename=\"".$path_parts["basename"]."\""); } header("Content-Transfer-Encoding: binary"); header("Content-length: $fsize"); header("Cache-control: private"); while(!feof($fd)) { $buffer = fread($fd, 2048); echo $buffer; } } fclose ($fd); exit; 

Development system - PHP 5.3.2-1 on Apache 2.2.14 (Ubuntu). The production host is PHP 5.2.9 on Apache 2.0.63 (some type of Linux).

+4
source share
3 answers

EF BB BF is the UTF-8 Encoding of Byte Estimation (BOM). I suspect there is a configuration option to disable the specification.

Edit: File editors should allow you to disable the specification when saving the file in the appropriate character encodings (for example, UTF-8).

+1
source

EF BB BF is the standard byte order mark of UTF-8. Some people have reported that this happens when some of your PHP files that you include in a script are encoded in UTF-8; some versions of PHP respond to this by sending a UTF-8 byte order marker. In the above link, it is recommended to call ob_start() at the beginning of the script and ob_end_clean() before you begin to ob_end_clean() out the contents of your file - this way the byte order marker gets into the output buffer.

Alternatively, you can simply use fpassthru to output your file to output instead of reading and writing in a loop.

+3
source

Your PHP script file seems to be encoded in UTF-8 with a specification that is right at the beginning of the file before opening <?php . These bytes are sent before your actual output and thus corrupt your data.

You just need to remove it and configure the editor so as not to use the specification for UTF-8.

+3
source

All Articles