Discussion:
Type d'image
(trop ancien pour répondre)
Pascale
2008-09-15 16:19:04 UTC
Permalink
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
Olivier Miakinen
2008-09-15 16:30:09 UTC
Permalink
Post by Pascale
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
2008-09-15 19:05:04 UTC
Permalink
Post by Olivier Miakinen
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
2008-09-15 19:33:54 UTC
Permalink
Post by Pascale
Oui, je suis en train de chercher ce que je peux faire avec getimagesize().
A priori, pour être sûr que ce soit un jpg, il faudrait que je vérifie un
$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 à <http://fr.php.net/manual/fr/features.file-upload.php> n'est
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.
Post by Pascale
(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 :

<cit. http://fr.php.net/manual/fr/features.file-upload.php>
$_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.
</cit.>
Pascale
2008-09-15 21:15:08 UTC
Permalink
Post by Olivier Miakinen
La doc à <http://fr.php.net/manual/fr/features.file-upload.php> n'est
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.
Post by Olivier Miakinen
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.
Post by Olivier Miakinen
À propos de ta question précédente concernant la fiabilité du
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
Sylvain SF
2008-09-15 21:15:08 UTC
Permalink
Post by Olivier Miakinen
À propos de ta question précédente concernant la fiabilité du
paramètre $_FILES['photo']['type'], elle est nulle
je confirme.
Post by Olivier Miakinen
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.
Post by Olivier Miakinen
if ($header == chr(0xff).chr(0xd8).chr(0xff).chr(0xe0)) ; // c'est du
JPG else
Gerard95
2008-09-20 09:23:24 UTC
Permalink
Post by 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 ?
Dans les 7 premiers octets du fichier jepg il y les lettres JFIF .
est-ce suffisant ?
Gerard95
2008-09-20 17:29:40 UTC
Permalink
Post by Gerard95
Post by 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 ?
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
2008-10-02 19:58:57 UTC
Permalink
Post by 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 ?
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
2008-10-03 18:38:02 UTC
Permalink
Post by Alarch
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
2008-10-07 00:22:48 UTC
Permalink
Post by Pascale
Post by Alarch
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
Pascale
2008-10-09 13:29:53 UTC
Permalink
Post by Alarch
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). [couic]
Mreci d'avoir détaillé, c'est en effet plus clair comme ça.
Post by Alarch
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.
Je suis entièrement de ton avis !
Post by Alarch
Bon courage
Merci ! (:
--
Pascale
Continuer la lecture sur narkive:
Loading...