Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is PHP not returning correct mime for json files?

I am aware that the correct MIME type fo json files is applicattion/json as may be confirmed by this post What is the correct JSON content type?.

However, I wonder why my PHP installation is returning text/plain. I need to test for the correct mime before parsing the json file.

I have the following code

$fileinfo = new finfo();
$fileType = $fileinfo->file( $_FILES['tmp_name'], FILEINFO_MIME_TYPE );

in which $fileType returns text/plain instead of applicattion/json.

Again, $_FILES['type'] returns application/octet-stream instead of applicattion/json.

What am I missing?

Edit

I am sending the file through jQuery ajax:

var formData = new FormData( $(form)[0] );
var jsonFile = $( 'input:file[name=contents]', form ).get(0).files[0];

formData.append( 'jsonFile', jsonFile );

$.ajax({ 

    type: 'POST',
    url: 'url',
    data: formData,
    dataType:'json',
    enctype : 'multipart/form-data',
    processData: false,
    contentType : false,
    encode:true,
})
like image 419
Stephen Adelakun Avatar asked Jan 05 '23 12:01

Stephen Adelakun


2 Answers

finfo identifies file type by it content, not file extension.

Only file with signature could be identified properly. Otherwise, will be id-ed as either text/plain (ASCII) or application/octet-stream (Binary) based on it's content.

Unfortunately JSON encoded content has no signature and hence being id-ed as text/plain or application/octet-stream.

For further reading, please visit:-

List of file signatures

Hope this helps.

[Edit 1] Below is my test script for the above. Cheers.

$filename = "test.json";

$finfo = finfo_open(FILEINFO_MIME_TYPE);

file_put_contents($filename, "<?php \n");
printf("%s\n", finfo_file($finfo, $filename));

file_put_contents($filename, "@echo off\n");
printf("%s\n", finfo_file($finfo, $filename));

file_put_contents($filename, json_encode(array("a" => "1")));
printf("%s\n", finfo_file($finfo, $filename));

file_put_contents($filename, "\xff");
printf("%s\n", finfo_file($finfo, $filename));

finfo_close($finfo);
like image 55
Capital C Avatar answered Jan 13 '23 11:01

Capital C


I'm not exactly sure what your actual problem is. It refers to two ways to obtain some MIME type.

Fileinfo uses libmagic. As the name indicates there is magic happening here. Essentially it looks at the file and tries to guess what type a file might be. If it i.e. begins with GIF89a it will report image/gif. The guess is often wrong but can be enough.

$_FILES contains information the client (web browser) is sending. the type in there is what the browser things. This often is completely useless.

If you need a precise type you have to ensure this yourself. How to do this depends on where the file is coming from and what you plan to do. i.e. if this comes from a trustworthy admin you might look at the file extension. For images uploaded from less trusted users (I hope you're not planning to accept javascript files uploaded from not fully trusted users to be executed) a good way is to actually trying to open the image and maybe even re-encoding it (i.e. to get rid of exif data)

like image 42
johannes Avatar answered Jan 13 '23 09:01

johannes