Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Tester la validite du nom d'un fichier uploade ?

45 réponses
Avatar
paul
Bonjour,

je voudrais vérifier la validité du nom d'un fichier photo uploadé (pas
de caractère accentué, d'espace,...).

J'ai mon champ input :
<input type="file" name="submitfiles[]" size="50">


J'ai essayé ce code :

if(ereg('[^[:space:]a-zA-Z0-9_.-]{1,}',
$HTTP_POST_FILES["submitfiles"]))
{
die ("<span class='attention'>Nom de fichier non
valide.<br><input type='button' value='Modifier'
onclick='goBack();'></span>");
}
else
{
include ("upload.php");
}




Mais ça ne fonctionne pas, je n'arrive pas à rentrer dans le if(ereg(...
:-((

Vous savez pourquoi ?
A cause du $HTTP_POST_FILES["submitfiles"] mal écrit ?


Merci pour votre aide !

Paul

10 réponses

1 2 3 4 5
Avatar
paul
Je poste en aveugle car je ne vois pas le message que j'ai placé il y a
2 heures environ (d'ailleurs il arrive fréquemment qu'il y ait une
demi-journée entre l'envoi du message et sa parution chez moi, sans que
je sache si cela provient de ma config ou de fr.comp.lang.php..)

Bref,
j'ai trouvé pour mon problème de if
j'ai remplacé
if (!empty($_FILES["submitfiles"])) {
par
if (!empty($_FILES["submitfiles"]["name"])) {

et ça va beaucoup mieux !
Désolé pour le bruit.
Avatar
Olivier Miakinen

J'ai essayé de mettre (mais j'ai sans doute mal compris...) :

$tmpfile = "$submitfiles['tmp_name']";
$photo = "$submitfiles['name']"

Et j'obtiens :

Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE,
expecting T_STRING or T_VARIABLE or T_NUM_STRING in
/home.2/v/e/u/veu/www/upload.php on line 12


RTFM ?
http://www.php.net/manual/fr/language.types.string.php

Incorrect :
$tmpfile = "$submitfiles['tmp_name']";

Corrects :
$tmpfile = $submitfiles['tmp_name'];
$tmpfile = $submitfiles["tmp_name"];
$tmpfile = "$submitfiles[tmp_name]";
$tmpfile = "{$submitfiles['tmp_name']}";

Avatar
paul
In article <45a04985$,
Olivier Miakinen <om+ wrote:

Incorrect :
$tmpfile = "$submitfiles['tmp_name']";
OK


Corrects :
$tmpfile = $submitfiles['tmp_name'];
Correct oui, mais ImageMagick m'avait fait des misères s'il y a un

espace dans le nom du fichier

J'ai essayé 3 les autres possibilités avec un nom de fichier :
A<- >'Moreil.jpg
ça ne plante pas mais la photo n'est pas traitée. Pas de message
d'erreur.

$tmpfile = $submitfiles["tmp_name"];
$tmpfile = "$submitfiles[tmp_name]";
$tmpfile = "{$submitfiles['tmp_name']}";



Par ailleurs j'ai essayé de passer un fichier avec "seulement' des
caractères accentués : ça passe, l'image est traitée normalement.

Comment écrire le masque pour que les caractères accentués soient
possibles mais pas les espaces, apostrophes, <, >, etc ?...

Actuellement j'ai :
elseif(preg_match('`[^-a-z0-9._]`i', $_FILES['submitfiles']['name']))

Merci
Paul

Avatar
Olivier Miakinen

Incorrect :
$tmpfile = "$submitfiles['tmp_name']";
OK


Corrects :
$tmpfile = $submitfiles['tmp_name'];
Correct oui, mais ImageMagick m'avait fait des misères s'il y a un

espace dans le nom du fichier


D'accord, mais ça c'est indépendant de la syntaxe pour insérer un
élément de tableau dans une chaîne. Si tu veux rajouter des guillemets
au début et à la fin, tu peux faire par exemple :

$tmpfile = '"' . $submitfiles['tmp_name'] . '"';

Autres exemples :

$tmpfile = ""$submitfiles[tmp_name]"";
$tmpfile = ""{$submitfiles['tmp_name']}"";

Cela dit, je ne connais pas ImageMagick, et je ne sais donc pas comment
on y accède.

Par ailleurs j'ai essayé de passer un fichier avec "seulement' des
caractères accentués : ça passe, l'image est traitée normalement.

Comment écrire le masque pour que les caractères accentués soient
possibles mais pas les espaces, apostrophes, <, >, etc ?...

Actuellement j'ai :
elseif(preg_match('`[^-a-z0-9._]`i', $_FILES['submitfiles']['name']))


Ce test devrait réussir s'il existe au moins un caractère qui ne soit
pas un -, une lettre minuscule (ou majuscule d'après le i), un chiffre,
un point ou un blanc souligné. Pour être sûr que cela fait bien ça,
j'aurais mis le - à la fin plutôt qu'après le ^, et A-Z au lieu du
flag i : '`[^A-Za-z0-9._-]`'. Je suppose bien entendu que ce elseif
retourne une erreur dans le cas où le test réussit.

Pour ce qui est des caractères accentués, je ne peux pas te répondre
sans savoir dans quel charset est stocké ton fichier PHP.


Avatar
Antoine Polatouche
In article <45a04985$,
Olivier Miakinen <om+ wrote:

Incorrect :
$tmpfile = "$submitfiles['tmp_name']";
OK


Corrects :
$tmpfile = $submitfiles['tmp_name'];
Correct oui, mais ImageMagick m'avait fait des misères s'il y a un

espace dans le nom du fichier

J'ai essayé 3 les autres possibilités avec un nom de fichier :
A<- >'Moreil.jpg
ça ne plante pas mais la photo n'est pas traitée. Pas de message
d'erreur.


et avec

$tmpfile = '"'.$submitfiles["tmp_name"].'"';

?


Avatar
paul
In article <45a16159$,
Olivier Miakinen <om+ wrote:

$tmpfile = '"' . $submitfiles['tmp_name'] . '"';
Malheureusement, je n'y arrive pas mieux actuellement...


Warning: getimagesize("/tmp/phpifBlH9") [function.getimagesize]: failed
to open stream: No such file or directory in
/home.2/v/e/u/veu/www/upload.php on line 91

Warning: Division by zero in /home.2/v/e/u/veu/www/upload.php on line 92

Warning: copy("/tmp/phpifBlH9") [function.copy]: failed to open stream:
No such file or directory in /home.2/v/e/u/veu/www/upload.php



Mais je crois que je vais me plutôt me recentrer sur le masque, ou
peut-être mieux sur un eregi_replace des caractères posant un souci dans
le nom du fichier (espace, apostrophe, etc...).



Actuellement j'ai :
elseif(preg_match('`[^-a-z0-9._]`i', $_FILES['submitfiles']['name']))


Ce test devrait réussir s'il existe au moins un caractère qui ne soit
pas un -, une lettre minuscule (ou majuscule d'après le i), un chiffre,
un point ou un blanc souligné. Pour être sûr que cela fait bien ça,
j'aurais mis le - à la fin plutôt qu'après le ^, et A-Z au lieu du
flag i : '`[^A-Za-z0-9._-]`'.
OK je te suis


Je suppose bien entendu que ce elseif
retourne une erreur dans le cas où le test réussit.
Oui !


Pour ce qui est des caractères accentués, je ne peux pas te répondre
sans savoir dans quel charset est stocké ton fichier PHP.
Je suis en UTF-8



Merci
Paul


Avatar
Olivier Miakinen

$tmpfile = '"' . $submitfiles['tmp_name'] . '"';
Malheureusement, je n'y arrive pas mieux actuellement...


Warning: getimagesize("/tmp/phpifBlH9") [function.getimagesize]: failed
to open stream: No such file or directory in
/home.2/v/e/u/veu/www/upload.php on line 91


Ah ben oui, si tu as besoin de ce nom de fichier ailleurs que dans
ImageMagick qui semble avoir besoin des guillemets, tu ne dois pas
rajouter les guillemets trop tôt !

$tmpfile = $submitfiles['tmp_name'];
$pourImageMagick = '"' . $tmpfile . '"';

getimagesize($tmpfile);
MachinTrucImageMagick($pourImageMagick);

Et si tu nous montrais un peu plus de ton script ?

Pour ce qui est des caractères accentués, je ne peux pas te répondre
sans savoir dans quel charset est stocké ton fichier PHP.
Je suis en UTF-8



Alors je vais me renseigner un peu plus sur l'utilisation de PCRE en
UTF-8 avant de te répondre.


Avatar
Fulax

In article <459d1abd$0$290$,
P'tit Marcel wrote:

if(preg_match('`[^-a-z0-9._]`i', $_FILES['submitfiles']['name'])) {
die(blablabla);
}
Le masque signifie qu'un caractère au moins ne fait partie :
NI des caractères compris entre a et z (minuscule ou majuscule)
NI des chiffres entre 0 et 9
NI des caractères . _

Oui c'est bien ce qu'il me faut




Pour les regex, il vaut mieux un masque qui reconnait ce que vous
voulez que l'inverse (trouver l'inverse d'un langage régulier n'est
jamais très aisé)

Il te faut donc un nom de fichier qui ne contient que des lettres avec
accents ou non à ce que j'ai lu, des chiffres et les caractères
point, souligné et le tiret

ce qui donne, en inversant les clause if et else :

if (preg_match("/^[-w.]+$/", $_FILES['submitfiles']['name'])) {
// Ici le nom vérifie de façon certaine les conditions requises si
php est dans la configuration français (cf lien 1)
} else die();...

Une alternative si on ne sait pas dans quelle configuration on est,
c'est de tester la ligne suivant :
var_dump(preg_match("/^w$/", "é")); // si on a bien true, c'est que
c'est bon


Sinon, si tu utilises PHP >= 4.4.0 ou 5.1.0 on peut utiliser les
classes Unicode de la libpcre

Dans ce cas, l'ensemble des combinaisons de caractères unicode qui
forment une lettre accentuée ou non, dans n'importe quel alphabet, se
résume en pL et la classe des nombres pN

la regex devient alors /^[-._pLpN]+$/


En espérant avoir pu t'aider


Lien 1 : http://fr.php.net/manual/fr/reference.pcre.pattern.syntax.php


Avatar
Olivier Miakinen

Pour ce qui est des caractères accentués, je ne peux pas te répondre
sans savoir dans quel charset est stocké ton fichier PHP.
Je suis en UTF-8



Alors je vais me renseigner un peu plus sur l'utilisation de PCRE en
UTF-8 avant de te répondre.


Tu as actuellement :
elseif (preg_match('`[^-a-z0-9._]`i', $filename))

Je te proposais :
elseif (preg_match('`[^A-Za-z0-9._-]`', $filename))

Si j'ai bien compris la doc, ceci devrait accepter tout caractère
Unicode compris entre U+00C0 et U+00FF, ce qui inclut la plupart des
caractères accentués utilisés dans certaines langues dont le français,
et aussi quelques autres caractères (× et ÷ par exemple) mais pas les
ligatures ½ et ¼ :
elseif (preg_match('`[^A-Za-z0-9._x{C0}-x{FF}-]`u', $filename))
(bien noter le flag u)

Attention : pour rejeter les séquences UTF-8 mal formées, il vaudrait
peut-être mieux inverser le sens du test, avec un preg_match qui réussit
lorsque la chaîne est correcte, plutôt que l'inverse :
elseif (preg_match('`^[A-Za-z0-9._x{C0}-x{FF}-]+$`u', $filename))

Maintenant, si ta version de PHP est au moins la 4.4.0 ou la 5.1.0, tu
dois pouvoir accepter les lettres par p{L} et les chiffres par p{N}
mais je ne sais pas si c'est possible dans un []. Si oui :
elseif (preg_match('`^[p{L}p{N}._-]+$`u', $filename))

Sinon :
elseif (preg_match('`^(p{L}|p{N}|[._-])+$`u', $filename))



Références :
http://fr3.php.net/manual/fr/reference.pcre.pattern.modifiers.php
http://fr3.php.net/manual/fr/reference.pcre.pattern.syntax.php
http://www.pcre.org/

Cordialement,
--
Olivier Miakinen



Avatar
Olivier Miakinen

Pour les regex, il vaut mieux un masque qui reconnait ce que vous
voulez que l'inverse (trouver l'inverse d'un langage régulier n'est
jamais très aisé)


Oui.

Il te faut donc un nom de fichier qui ne contient que des lettres avec
accents ou non à ce que j'ai lu, des chiffres et les caractères
point, souligné et le tiret


Oui aussi.

ce qui donne, en inversant les clause if et else :

if (preg_match("/^[-w.]+$/", $_FILES['submitfiles']['name'])) {
// Ici le nom vérifie de façon certaine les conditions requises si
php est dans la configuration français (cf lien 1)
} else die();...


Oui, sauf que w trouvera éventuellement les lettres accentuées, mais
seulement si les deux conditions suivantes sont réalisées simultanément.

1) La locale pour preg_match() correspond par exemple au français,
ce qui n'est pas le cas par défaut (locale C), et je ne sais même
pas si on peut la changer dans PHP.

2) Le charset correspondant à cette locale est une table de caractères
mono-byte, or là on est sûr que ce n'est pas le cas (Paul est en
UTF-8).

Donc, w ne peut pas marcher.

Une alternative si on ne sait pas dans quelle configuration on est,
c'est de tester la ligne suivant :
var_dump(preg_match("/^w$/", "é")); // si on a bien true, c'est que
c'est bon


Ce sera forcément false.

Sinon, si tu utilises PHP >= 4.4.0 ou 5.1.0 on peut utiliser les
classes Unicode de la libpcre

Dans ce cas, l'ensemble des combinaisons de caractères unicode qui
forment une lettre accentuée ou non, dans n'importe quel alphabet, se
résume en pL et la classe des nombres pN

la regex devient alors /^[-._pLpN]+$/


Oui.

1 2 3 4 5