Type d'image

Le
Pascale
Toute contente d'avoir ENFIN réussi à générer mes vignettes, je m'aperçois
qu'il y en a une poignée qui sont noires.
Je me dis qu'il y a encore une erreur dans le code, mais non.
Les images d'origines sont chargées par les utilisateurs, seul le format
jpg est autorisé.
Et je me suis aperçu que les vignettes noires provenaient de faux jpg,
d'images qui sont en fait des gif ou des bmp, mais auxquelles l'utilisateur
a rajouté probablement une extension jpg !
Bêtement, je testais à partir de $_FILES['photo1']['name'] , je vérifiais
simplement qu'il y a à la fin un point suivi de jpeg, jpg, JPG ou JPEG.

Visiblement, ce n'est pas suffisant, faut-il tester sur
$_FILES['photo1']['type'] ? Est-ce fiable ?

--
Pascale
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Olivier Miakinen
Le #17234571
Le 15/09/2008 18:19, Pascale a écrit :

Bêtement, je testais à partir de $_FILES['photo1']['name'] , je vérifiais
simplement qu'il y a à la fin un point suivi de jpeg, jpg, JPG ou JPEG.

Visiblement, ce n'est pas suffisant, faut-il tester sur
$_FILES['photo1']['type'] ? Est-ce fiable ?



Personnellement, j'irais plutôt lire l'information directement dans le
fichier, soit par getimagesize() qui te retourne en même temps ses
dimensions, soit par exif_imagetype() (non testé).
Pascale
Le #17239691
Olivier Miakinen news:48ce8cc3$:

Personnellement, j'irais plutôt lire l'information directement dans le
fichier, soit par getimagesize() qui te retourne en même temps ses
dimensions, soit par exif_imagetype() (non testé).



Oui, je suis en train de chercher ce que je peux faire avec getimagesize().
Re-merci (-:
A priori, pour être sûr que ce soit un jpg, il faudrait que je vérifie un
truc du genre :

$testype=getimagesize($_FILES['photo']['tmp_name']);
if ($testype[2]=='2')
....

Enfin bon, ça a pas l'air trop au point mon truc avec tmp_name... (je préfèrerais
tester avant que la photo ne soit réellement uploadée...)

--
Pascale
Olivier Miakinen
Le #17239681
Le 15/09/2008 21:05, Pascale a écrit :

Oui, je suis en train de chercher ce que je peux faire avec getimagesize().
Re-merci (-:
A priori, pour être sûr que ce soit un jpg, il faudrait que je vérifie un
truc du genre :

$testype=getimagesize($_FILES['photo']['tmp_name']);
if ($testype[2]=='2')
....

Enfin bon, ça a pas l'air trop au point mon truc avec tmp_name...



La doc à pas très claire, ou alors c'est moi qui ne sais pas lire : je n'arrive
pas à voir si $_FILES['photo']['tmp_name'] contient le chemin d'accès
complet au fichier, ou bien s'il faut le préfixer par l'upload_tmp_dir.

(je préfèrerais
tester avant que la photo ne soit réellement uploadée...)



Note que tu peux le faire en deux étapes : d'abord move_uploaded_file()
vers un répertoire de test, puis rename() vers sa destination finale
quand tout est OK.


À propos de ta question précédente concernant la fiabilité du paramètre
$_FILES['photo']['type'], elle est nulle :

$_FILES['userfile']['type']

Le type MIME du fichier, si le navigateur a fourni cette information.
Par exemple, cela pourra être "image/gif". Ce type mime n'est cependant
pas vérifié du côté de PHP et, donc, ne prend pas sa valeur pour se
synchroniser.
Sylvain SF
Le #17239661
Olivier Miakinen wrote on 15/09/2008 21:33:

À propos de ta question précédente concernant la fiabilité du
paramètre $_FILES['photo']['type'], elle est nulle



je confirme.

concernant l'autre question:

je préfèrerais tester avant que la photo ne soit réellement uploadée



c'est impossible, comment tester ce qui est encore chez le client ?

il faut réaliser le transfert (vers un rep. de transfert) et là ouvrir
le fichier pour une lecture binaire:

$handle = fopen($pathname, 'r');

lire alors l'entête (4 octets suffisent)

$header = fread($handle, 4);

fermer les portes

fclose($handle);

et tester le type lu, à savoir:

if ($header == chr(0xff).chr(0xd8).chr(0xff).chr(0xe0))
; // c'est du JPG
else if ($header == 'GIF8')
; // c'est du GIF

Sylvain.

if ($header == chr(0xff).chr(0xd8).chr(0xff).chr(0xe0)) ; // c'est du
JPG else


Pascale
Le #17239671
Olivier Miakinen news:48ceb651$:

La doc à pas très claire, ou alors c'est moi qui ne sais pas lire : je n'arrive
pas à voir si $_FILES['photo']['tmp_name'] contient le chemin d'accès
complet au fichier, ou bien s'il faut le préfixer par
l'upload_tmp_dir.



Oui, en fait ça marche. Cette fonction getimagesize() est vraiment
intéressante.

Note que tu peux le faire en deux étapes : d'abord
move_uploaded_file() vers un répertoire de test, puis rename() vers sa
destination finale quand tout est OK.



C'est comme ça que je procède, mais j'aime bien faire mes petits tests
autant en amont que possible.

À propos de ta question précédente concernant la fiabilité du
paramètre $_FILES['photo']['type'], elle est nulle :



Exact, je l'ai constaté : c'est bien le type jpg qui ressortait pour mes
« faux jpg », donc aucun intérêt pour mon problème.

--
Pascale
Gerard95
Le #17280631
Le 15/09/2008, Pascale a supposé :
Toute contente d'avoir ENFIN réussi à générer mes vignettes, je m'aperçois
qu'il y en a une poignée qui sont noires.
Je me dis qu'il y a encore une erreur dans le code, mais non.
Les images d'origines sont chargées par les utilisateurs, seul le format
jpg est autorisé.
Et je me suis aperçu que les vignettes noires provenaient de faux jpg,
d'images qui sont en fait des gif ou des bmp, mais auxquelles l'utilisateur
a rajouté probablement une extension jpg !
Bêtement, je testais à partir de $_FILES['photo1']['name'] , je vérifiais
simplement qu'il y a à la fin un point suivi de jpeg, jpg, JPG ou JPEG.

Visiblement, ce n'est pas suffisant, faut-il tester sur
$_FILES['photo1']['type'] ? Est-ce fiable ?



Dans les 7 premiers octets du fichier jepg il y les lettres JFIF .
est-ce suffisant ?
Gerard95
Le #17284901
Le 20/09/2008, Gerard95 a supposé :
Le 15/09/2008, Pascale a supposé :
Toute contente d'avoir ENFIN réussi à générer mes vignettes, je m'aperçois
qu'il y en a une poignée qui sont noires.
Je me dis qu'il y a encore une erreur dans le code, mais non.
Les images d'origines sont chargées par les utilisateurs, seul le format
jpg est autorisé.
Et je me suis aperçu que les vignettes noires provenaient de faux jpg,
d'images qui sont en fait des gif ou des bmp, mais auxquelles l'utilisateur
a rajouté probablement une extension jpg !
Bêtement, je testais à partir de $_FILES['photo1']['name'] , je vérifiais
simplement qu'il y a à la fin un point suivi de jpeg, jpg, JPG ou JPEG.

Visiblement, ce n'est pas suffisant, faut-il tester sur
$_FILES['photo1']['type'] ? Est-ce fiable ?



Dans les 7 premiers octets du fichier jepg il y les lettres JFIF .
est-ce suffisant ?



<correction> A partir du 7e octet du ficheir il y a les lettres JFIF
Alarch
Le #17405451
Pascale wrote:

Toute contente d'avoir ENFIN réussi à générer mes vignettes, je m'aperçois
qu'il y en a une poignée qui sont noires.
Je me dis qu'il y a encore une erreur dans le code, mais non.
Les images d'origines sont chargées par les utilisateurs, seul le format
jpg est autorisé.
Et je me suis aperçu que les vignettes noires provenaient de faux jpg,
d'images qui sont en fait des gif ou des bmp, mais auxquelles
l'utilisateur a rajouté probablement une extension jpg !
Bêtement, je testais à partir de $_FILES['photo1']['name'] , je vérifiais
simplement qu'il y a à la fin un point suivi de jpeg, jpg, JPG ou JPEG.

Visiblement, ce n'est pas suffisant, faut-il tester sur
$_FILES['photo1']['type'] ? Est-ce fiable ?




Non ce n'est pas suffisant !

J'arrive peut-être un peu tard, mais j'ai retrouvé dans une classe d'upload
de fichier cette méthode que tu pourrais sans doute arranger. Il y est fait
allusion à des propriétés de la classe $this->nom_propriété, mais tu
devrais pouvoir comprendre le mécanisme.

private function verifImage ()
{
/**
La vérification des fichiers binaires d'image se fait en contrôlant la
signature hexadécimale de début de fichier
En analysant des images existantes il semble qu'en hexadécimal les débuts de
fichiers soient les suivants :
Jpeg : FFD8FF
PNG : 89504E470D
Gif : 474946383961 (Gif89) et 474946383761 (Gif87)
*/
if(file_exists($this->working_copy_name)) {
$id = fopen($this->working_copy_name,'rb');
$buffer = fread($id,6);
fclose($id);
}
$signature = bin2hex ($buffer);
$image_ok = false;
$result = Array();
$suffixe = '';
if (substr($signature,0,6) == 'ffd8ff') {
$image_ok = true;
$info_message = "<li>La signature (".substr($signature,0,6).") de l'image
d'origine ".$this->original_name." atteste que c'est une image .jpg. Son
type mime annoncé était ".$this->mime_type."</li>n";
$suffixe = '.jpg';
}
elseif (substr($signature,0,10) == '89504e470d') {
$image_ok = true;
$info_message = "<li>La signature (".substr($signature,0,10).") de l'image
d'origine ".$this->original_name." atteste que c'est une image .png. Son
type mime annoncé était ".$this->mime_type."</li>n";
$suffixe = '.png';

}
elseif (substr($signature,0,12) == '474946383961' ||
substr($signature,0,12) == '474946383761') {
$image_ok = true;
$info_message = "<li>La signature (".substr($signature,0,12).") de l'image
d'origine ".$this->original_name." atteste que c'est une image .gif. Son
type mime annoncé était ".$this->mime_type."</li>n";
$suffixe = '.gif';
}
else {
$warning_message = "<li>!!!ALERTE : Ce fichier n'est pas à format d'image
reconnu par l'application. Son type mime est "
$this->mime_type.".</li>n";
}
$result[0] = $image_ok;
$result[1] = $info_message;
$result[2] = $warning_message;
$result[3] = $suffixe;
return $result;
} // fin de méthode verifImage
Pascale
Le #17413771
Alarch news:48e510b2$0$933$:

Non ce n'est pas suffisant !

J'arrive peut-être un peu tard, mais j'ai retrouvé dans une classe
d'upload de fichier cette méthode que tu pourrais sans doute arranger.
Il y est fait allusion à des propriétés de la classe
$this->nom_propriété, mais tu devrais pouvoir comprendre le mécanisme.

private function verifImage () [...]



Bigre, c'est pas simple...
Je vais essayer de comprendre (c'est pas gagné), et en attendant, je te
remercie !

--
Pascale
Alarch
Le #17442901
Pascale wrote:

Alarch news:48e510b2$0$933$:

Non ce n'est pas suffisant !

J'arrive peut-être un peu tard, mais j'ai retrouvé dans une classe
d'upload de fichier cette méthode que tu pourrais sans doute arranger.
Il y est fait allusion à des propriétés de la classe
$this->nom_propriété, mais tu devrais pouvoir comprendre le mécanisme.

private function verifImage () [...]



Bigre, c'est pas simple...
Je vais essayer de comprendre (c'est pas gagné), et en attendant, je te
remercie !



En fait c'est assez simple, on utilise la fonction bin2hex qui est une
fonction fournie par php (voir
http://docs.php.net/manual/fr/function.bin2hex.php) et qui permet de lire
les octets composant un fichier et d'afficher leur valeur hexadécimal (plus
lisible pour un humain).

La fonction extrait avec bin2hex substr la chaîne hexadécimale qui compose
le début du fichier que tu uploade et la compare aux valeurs caractérsant
le jpg, le png et le gif (valeur qui sont en hexadécimal, ça tombe
bien ;-) ). En fait les premiers octets des fichiers d'image (et d'autres
fichiers) représentent une sorte de signature qui permet au système de
reconnaître le type de fichier (indépendemment du type mime).

Si tu ne connais pas trop php, regarde la doc pour les fonctions fopen pour
ouvrir le fichier, substr pour extraire une portion de chaîne. Tu vas voir
que ça va te sembler d'un coup beaucoup moins difficile...

Si tu as besoin je peux t'envoyer toute ma classe d'upload, mais c'est
toujours mieux de comprendre ce qu'on fait plutôt que d'utiliser un truc
tout fait si on ne comprend pas bien ce qu'il fait et surtout comment il le
fait.

Bon courage
Publicité
Poster une réponse
Anonyme