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
Olivier Miakinen

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


Oui.


Euh... non.

C'est /^[-._pLpN]+$/u


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

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 !


Oui effectivement !
Je n'ai plus modifié que le "name" car que je me suis rendu compte que
le "tmp_name" était généré automatiquement et n'avait à priori pas de
rapport avec le nom du fichier saisi dans le champ input... donc à
priori pas de pb de ce côté-là.

J'ai réessayé les différentes solutions évoquées :

:
- le fichier n'est pas resizé.
- les variables passées ensuite dans l'URL PHP n'aiment pas du tout ces
caractères (apostrophes...) : les noms de fichier sont tronqués après le
antislash placés automatiquement devant les apostrophes...

:-((

Je crois qu'il faut vraiment faire la modification du nom de fichier..


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


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



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


Plutôt qu'un masque qui m'oblige ensuite à demander à l'utilisateur de
renommer son fichier, je préfère le renommer directement :



$submitfiles = $_FILES["submitfiles"];

function getRewriteString($sString) {
$string = htmlentities(strtolower($sString));
$string =
preg_replace('#&([a-z])(?:acute|grave|uml|circ|ring|slash|zlig|cedil|tild
e);#i', "$1", $string);
//$string =
preg_replace("/&(.)(acute|cedil|circ|ring|tilde|uml);/", "$1", $string);
$string = preg_replace("/([^a-z0-9]+)/", ".",
html_entity_decode($string));
$string = trim($string, "");
return $string;
}

$tmpfile = $submitfiles['tmp_name'];
$photo = getRewriteString($submitfiles['name']);


Là il se passe 2 choses :

- aucune des 2 preg_replace qui devraient remplacer les caractères
accentués par leur équivalent non-accentué ne fonctionne...
Je ne sais pas pourquoi.

- je peux me retrouver avec plusieurs point dans le nom de fichier
exemple : .img.e.jpg
Euh ça pose un problème ça ?


Merci
Paul



Avatar
Olivier Miakinen

$submitfiles = $_FILES["submitfiles"];

function getRewriteString($sString) {
$string = htmlentities(strtolower($sString));


Attention : htmlentities() est en Latin1 par défaut, tandis que
strtolower(), par défaut, ne traite que les caractères ASCII.
Aucun des deux ne peut fonctionner tel quel en UTF-8.

$string = preg_replace('#&([a-z])(?:acute|grave|uml|circ|ring|slash|zlig|cedil|tilde);#i', "$1", $string);


Rigolo. Je n'y aurais pas pensé !

//$string = preg_replace("/&(.)(acute|cedil|circ|ring|tilde|uml);/", "$1", $string);
$string = preg_replace("/([^a-z0-9]+)/", ".", html_entity_decode($string));


Là encore le charset par défaut pour html_entity_decode() est Latin1 et
pas UTF-8.

$string = trim($string, "");


Euh... il n'y a pas un paramètre en trop, ou des caractères manquants
dans le paramètre ? Là tu dis que tu veux supprimer des caractères en
début et fin de ligne, mais en fait il n'y a aucun caractère que tu veux
supprimer (puisque la liste est vide).

- aucune des 2 preg_replace qui devraient remplacer les caractères
accentués par leur équivalent non-accentué ne fonctionne...
Je ne sais pas pourquoi.


Tu es sûr que ce sont les preg_replace() qui ne fonctionnent pas ? Ce ne
seraient pas plutôt strtolower(), htmlentities(), html_entity_decode()
et trim() ?

- je peux me retrouver avec plusieurs point dans le nom de fichier
exemple : .img.e.jpg
Euh ça pose un problème ça ?


Si tu n'es pas en MS-DOS avec le format « 8 caractères + point + 3
caractères », ça ne devrait pas poser de problème. ;-)

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


$submitfiles = $_FILES["submitfiles"];

function getRewriteString($sString) {
$string = htmlentities(strtolower($sString));


Attention : htmlentities() est en Latin1 par défaut, tandis que
strtolower(), par défaut, ne traite que les caractères ASCII.
Aucun des deux ne peut fonctionner tel quel en UTF-8.


Pourtant toutes mes caps sont changées en minuscules...

$string =
preg_replace('#&([a-z])(?:acute|grave|uml|circ|ring|slash|zlig|cedil|t
ilde);#i', "$1", $string);


Rigolo. Je n'y aurais pas pensé !
Oui mais ça ne fonctionne pas chez moi

:-(

//$string = preg_replace("/&(.)(acute|cedil|circ|ring|tilde|uml);/",
"$1", $string);
Celle-ci non plus...



Ces 2 preg_replace liées aux caractères accentués ne fonctionnent pas...
Pourquoi ?
Comme faire fonctionner ça ?

Et en fait les éèà et autres seront remplacés par un . par la
preg_replace suivante :

$string = preg_replace("/([^a-z0-9]+)/", ".",
Celle-ci fonctionne bien donc



html_entity_decode($string));
Là encore le charset par défaut pour html_entity_decode() est Latin1 et

pas UTF-8.

$string = trim($string, "");
Euh... il n'y a pas un paramètre en trop, ou des caractères manquants

dans le paramètre ? L tu dis que tu veux supprimer des caractères en
début et fin de ligne, mais en fait il n'y a aucun caractère que tu veux
supprimer (puisque la liste est vide).


Si je comprends bien ce qui est dit là
<http://fr2.php.net/manual/fr/function.trim.php>
trim() retourne la chane str, après avoir supprimé les caractères
invisibles en début et fin de chane. Si le second paramètre charlist est
omis, trim() supprimera les caractères suivants :
" " (ASCII 32 (0x20)), un espace ordinaire.
"t" (ASCII 9 (0x09)), une tabulation.
"n" (ASCII 10 (0x0A)), une nouvelle ligne (line feed).
"r" (ASCII 13 (0x0D)), un retour chariot (carriage return).
"" (ASCII 0 (0x00)), le caractère NUL.
"x0B" (ASCII 11 (0x0B)), une tabulation verticale.

S'il y en a, ils sont remplacés par rien, ""


- aucune des 2 preg_replace qui devraient remplacer les caractères
accentués par leur équivalent non-accentué ne fonctionne...
Je ne sais pas pourquoi.


Tu es sûr que ce sont les preg_replace() qui ne fonctionnent pas ? Ce ne
seraient pas plutôt strtolower(), htmlentities(), html_entity_decode()
et trim() ?
Ben oui


- je peux me retrouver avec plusieurs point dans le nom de fichier
exemple : .img.e.jpg
Euh ça pose un problème ça ?


Si tu n'es pas en MS-DOS avec le format « 8 caractères + point + 3
caractères », ça ne devrait pas poser de problème. ;-)
Ouf j'ai au moins cette solution en attendant mieux !

:-)


Avatar
Olivier Miakinen

Attention : htmlentities() est en Latin1 par défaut, tandis que
strtolower(), par défaut, ne traite que les caractères ASCII.
Aucun des deux ne peut fonctionner tel quel en UTF-8.


Pourtant toutes mes caps sont changées en minuscules...


Tu es sûr que ton fichier est en UTF-8 ?

Et en fait les éèà et autres seront remplacés par un . par la
preg_replace suivante :

$string = preg_replace("/([^a-z0-9]+)/", ".",




Un seul « . » par caractère accentué ?!? Tu es sûr que ton fichier est
en UTF-8 ?

$string = trim($string, "");
Euh... il n'y a pas un paramètre en trop, ou des caractères manquants

dans le paramètre ? L tu dis que tu veux supprimer des caractères en
début et fin de ligne, mais en fait il n'y a aucun caractère que tu veux
supprimer (puisque la liste est vide).


Si je comprends bien ce qui est dit là
<http://fr2.php.net/manual/fr/function.trim.php>
trim() retourne la chane str, après avoir supprimé les caractères
invisibles en début et fin de chane.


Hum. « invisible » est une traduction bien curieuse pour « whitespace ».

Si le second paramètre charlist est omis [...]


Voilà. Si le second paramètre est omis, l'appel ressemblera à :
$string = trim($string);

$string = trim($string, "");
Ici, le second paramètre est fourni, et sa valeur est une chaîne vide.
Elle ne contient donc aucun des caractères « whitespace » (espace, TAB,
CR, LF, NUL et VT).

Tu es sûr que ce sont les preg_replace() qui ne fonctionnent pas ? Ce ne
seraient pas plutôt strtolower(), htmlentities(), html_entity_decode()
et trim() ?
Ben oui



Alors tu n'es pas en UTF-8, mais peut-être en Latin1 ou en cp1252.



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

Et en fait les éèà et autres seront remplacés par un . par la
preg_replace suivante :

$string = preg_replace("/([^a-z0-9]+)/", ".",




Un seul « . » par caractère accentué ?!?


Non un seul " . " par série consécutive de caractères accentués.

IMéàoerORG_ ' A<>A" eéé .JPG
devient
.im.oerorg.a.a.e.jpg


Tu es sûr que ton fichier est
en UTF-8 ?
Ben à priori oui :

<meta http-equiv="content-type" content="text/html; charset=utf-8">
Comment s'en assurer autrement ?


Si je comprends bien ce qui est dit là
<http://fr2.php.net/manual/fr/function.trim.php>
trim() retourne la chane str, après avoir supprimé les caractères
invisibles en début et fin de chane.


Hum. « invisible » est une traduction bien curieuse pour « whitespace ».


;-)

Si le second paramètre charlist est omis [...]


Voilà. Si le second paramètre est omis, l'appel ressemblera à :
$string = trim($string);

$string = trim($string, "");
Ici, le second paramètre est fourni, et sa valeur est une chaîne vide.
Elle ne contient donc aucun des caractères « whitespace » (espace, TAB,
CR, LF, NUL et VT).


OK. Autant pour moi.


Tu es sûr que ce sont les preg_replace() qui ne fonctionnent pas ? Ce ne
seraient pas plutôt strtolower(), htmlentities(), html_entity_decode()
et trim() ?
Ben oui



Alors tu n'es pas en UTF-8, mais peut-être en Latin1 ou en cp1252.


A l'insu de mon plein gré alors !...
Comment vérifier ça ?




Avatar
Olivier Miakinen

Tu es sûr que ton fichier est
en UTF-8 ?
Ben à priori oui :

<meta http-equiv="content-type" content="text/html; charset=utf-8">


Beuah !

Essaye plutôt :
<?php
header("Content-Type", "text/html; charset=utf-8");
?>

Comment s'en assurer autrement ?


File > Save as... > Format
- ISO-8859-1
- Latin 1
- EBCDIC
- UTF-8
- UTF-16 BE
- Unicode
- Windows Western
- Shift_JIS
- ... autre ?

Et puis si tu avais une URL pour tester ce serait bien.

Alors tu n'es pas en UTF-8, mais peut-être en Latin1 ou en cp1252.


A l'insu de mon plein gré alors !...
Comment vérifier ça ?


Cf. supra.


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


Tu es sûr que ton fichier est
en UTF-8 ?
Ben à priori oui :

<meta http-equiv="content-type" content="text/html; charset=utf-8">


Beuah !


Bon...


Essaye plutôt :
<?php
header("Content-Type", "text/html; charset=utf-8");
?>


Aïe... j'ai mis ce code entre les <head></head> à la place du (pouah...)
:
<meta http-equiv="content-type" content="text/html; charset=utf-8">

et j'obtiens :

Internal Server Error
The server encountered an internal error or misconfiguration and was
unable to complete your request.

C'est grave docteur ?

Comment s'en assurer autrement ?


File > Save as... > Format
- ISO-8859-1
- Latin 1
- EBCDIC
- UTF-8
- UTF-16 BE
- Unicode
- Windows Western
- Shift_JIS
- ... autre ?


BBEdit me le signale en UTF8 no-BOM


Et puis si tu avais une URL pour tester ce serait bien.


OK je te fais ça plus tard si on continue à être bloqués...


Merci
Paul



Avatar
Olivier Miakinen

Essaye plutôt :
<?php
header("Content-Type", "text/html; charset=utf-8");
?>


Aïe... j'ai mis ce code entre les <head></head> à la place du (pouah...)
:
<meta http-equiv="content-type" content="text/html; charset=utf-8">

et j'obtiens :

Internal Server Error


J'aurais dû vérifier avant d'envoyer, mais j'étais un peu en retard.
En réalité c'était :
header("Content-Type: text/html; charset=UTF-8");

Cela dit, comme il s'agit d'envoyer l'information dans les entêtes HTTP
plutôt que dans la page HTML, cette instruction est à mettre en *tout
premier*, avant que le moindre octet ait pu être transmis.
Voir <http://faqfclphp.free.fr/#rub2.12>.

BBEdit me le signale en UTF8 no-BOM


Ça c'est parfait. Je suis convaincu maintenant que c'est bien de
l'UTF-8, même s'il vaut mieux l'annoncer dans les entêtes HTTP comme
je le disais plutôt que dans un élément meta. Note que tu peux toujours
faire les deux, afin qu'un visiteur puisse sauver la page sur son disque
dur et le retrouver en UTF-8 à la relecture.

Je vais revenir sur ton article précédent maintenant.


Avatar
Olivier Miakinen
Je reviens donc sur cet article.


$string = htmlentities(strtolower($sString));


Attention : htmlentities() est en Latin1 par défaut, tandis que
strtolower(), par défaut, ne traite que les caractères ASCII.
Aucun des deux ne peut fonctionner tel quel en UTF-8.


Pourtant toutes mes caps sont changées en minuscules...


J'ai d'abord pris ta réponse comme une preuve que tu ne pouvais pas être
en UTF-8, mais je n'ai pas pensé que quand tu disais « toutes mes caps »
il n'y avait peut-être pas de minuscules accentuées dedans.

Veux-tu faire un essai ? Tu sépares cette instruction en deux, et tu
affiches le résultat d'abord du strtolower() puis du htmlentities(),
avec les noms de fichiers suivants :
UnB½uf.jpg
Un¼uf.jpg
ÇaCoûteZéro¤Pièce.jpg

$string =
preg_replace('#&([a-z])(?:acute|grave|uml|circ|ring|slash|zlig|cedil|t
ilde);#i', "$1", $string);




Tu peux aussi continuer et afficher le résultat de ce preg_replace et du
suivant.

Et en fait les éèà et autres seront remplacés par un . par la
preg_replace suivante :

$string = preg_replace("/([^a-z0-9]+)/", ".",
Celle-ci fonctionne bien donc




Je n'avais pas vu le « + » qui explique qu'une série de caractères
accentués deviennent un seul point. Je te propose pour le test de
supprimer ce « + » : si ce que je crois est exact, tu devrais obtenir :
unb..uf.jpg
un..uf.jpg
..aco..tez..ro...pi..ce.jpg
(trois points pour l'¤, deux pour chacun des autres caractères accentués)



1 2 3 4 5