[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / plugins / verifier / verifier / fichiers.php
1 <?php
2
3 // Sécurité
4 if (!defined("_ECRIRE_INC_VERSION")) {
5 return;
6 }
7
8 /**
9 * Vérifier une saisie d'envoi de fichiers
10 *
11 * @param array|bool $valeur
12 * Le sous tableau de $_FILES à vérifier, $_FILES['logo'] par exemple
13 * Doit être un champ avec un ou plusieurs upload
14 * Si bool égal à true, cela signifie que le fichier avait déjà été vérifié, et qu'il est inutile de refaire la vérification.
15 * @param array $options
16 * Options à vérifier :
17 * - mime au choix 'pas_de_verification', 'image_web','tout_mime','specifique'
18 * - mime_specifique (si l'option 'mime_specifique' est choisi ci-dessus)
19 * - taille_max (en Kio)
20 * - dimension_max, tableau contenant les dimension max:
21 * - largeur (en px)
22 * - hauteur (en px)
23 * - autoriser_rotation : booléen à mettre à true (ou bien string égale à 'on') si on autorise une image qui tiendrait dans ces dimensions si on faisait une rotation de 90°
24 * - on peut remplacer ce tableau par des strings directement dans $options:
25 * - largeur_max
26 * - hauteur_max
27 * - autoriser_rotation
28 * @param array|string &$erreurs_par_fichier
29 * Si on vérifier un upload multiple, un tableau, passé par référence, qui contient le détail des erreurs fichier de $_FILES['fichier'] par fichier
30 * Si on vérifie un upload unique, une chaîne qui contiendra l'erreur du fichier.
31 * @return string
32 **/
33 function verifier_fichiers_dist($valeur, $options, &$erreurs_par_fichier) {
34 if (!is_array($valeur['tmp_name'])){//si on reçoit une info de type fichier unique, on bascule comme si on était fichier multiple
35
36 if ($valeur === True) { // Si on n'a rien à vérifier
37 return array();
38 };
39
40 $old_valeur = $valeur;
41 $valeur = array();
42 foreach ($old_valeur as $propriete=>$val){
43 $valeur[$propriete][0] = $val;
44 }
45 }
46
47 // normalisation de $options
48 if (isset($options['largeur_max']) and !isset($options['dimension_max']['largeur'])) {
49 if (!isset($options['dimension_max'])) {
50 $options['dimension_max'] = array();
51 }
52 $options['dimension_max']['largeur'] = $options['largeur_max'];
53 unset($options['largeur_max']);
54 }
55 if (isset($options['hauteur_max']) and !isset($options['dimension_max']['hauteur'])) {
56 if (!isset($options['dimension_max'])) {
57 $options['dimension_max'] = array();
58 }
59 $options['dimension_max']['hauteur'] = $options['hauteur_max'];
60 unset($options['hauteur_max']);
61 }
62 if (isset($options['dimension_autoriser_rotation']) and !isset($options['dimension_max']['autoriser_rotation'])) {
63 if (!isset($options['dimension_max'])) {
64 $options['dimension_max'] = array();
65 }
66 $options['dimension_max']['autoriser_rotation'] = $options['dimension_autoriser_rotation'];
67 unset($options['dimension_autoriser_rotation']);
68 }
69 if (isset($options['dimension_max']['autoriser_rotation']) and $options['dimension_max']['autoriser_rotation'] == 'on') {
70 $options['dimension_max']['autoriser_rotation'] = True;
71 }
72 // Vérification proprement dite
73 foreach ($valeur['tmp_name'] as $cle=>$tmp_name){//On parcourt tous les fichiers
74 if ($valeur['error'][$cle] != 0 and $valeur['error'][$cle] !=4) {//On vérifie uniquement les fichiers bien expediés, si mal expedié, on indique une erreur générique. Si pas expediés, on indique rien
75 $erreur = _T("verifier:erreur_php_file_".$valeur['error'][$cle], array('name'=>$valeur['name'][$cle]));
76 if (!is_array($erreurs_par_fichier)) {
77 $erreurs_par_fichier = $erreur;
78 return $erreur;
79 } else {
80 $erreurs_par_fichier[$cle] = "- $erreur";
81 }
82 continue;
83 }
84 if ($valeur['error'][$cle] == 4) {
85 continue;
86 }
87 foreach (array('mime','taille','dimension_max') as $verification){ // On va vérifier d'hivers choses, dans un certain ordre, en confiant cela à des fonctions homonymes
88 $fonction_verification = "verifier_fichier_$verification";
89 if ($erreur = $fonction_verification($valeur,$cle,$options)) {
90 if (!is_array($erreurs_par_fichier)) {
91 $erreurs_par_fichier = $erreur;
92 return $erreur;
93 } else{
94 $erreurs_par_fichier[$cle] = "- $erreur";
95 }
96 }
97 }
98 }
99 if (!empty($erreurs_par_fichier)){
100 return implode($erreurs_par_fichier,"<br />");
101 }
102 return '';
103 }
104
105 /**
106 * Vérifier le mime type d'une saisie d'envoi de fichiers
107 *
108 * @param array $valeur
109 * Le sous tableau de $_FILES à vérifier, $_FILES['logo'] par exemple
110 * Doit être un champ plusieurs uploads
111 * @param int $cle
112 * La clé du tableau qu'on vérifie
113 * @param array $options
114 * Les options tels que passés à verifier_fichiers()
115 * @return string
116 **/
117 function verifier_fichier_mime($valeur,$cle,$options){
118 if ($options['mime'] == 'pas_de_verification') {
119 return '';
120 }
121
122 // Récuperer les infos mime + extension
123 $mime_type = $valeur['type'][$cle];
124 $extension = pathinfo($valeur['name'][$cle],PATHINFO_EXTENSION);
125
126 // Appliquer les alias de type_mime
127 include_spip('base/typedoc');
128 while (isset($GLOBALS['mime_alias'][$mime_type])) {
129 $mime_type = $GLOBALS['mime_alias'][$mime_type];
130 }
131
132 // Voir si les mime_type fournit par le serveur sont significatifs ou non
133 $mime_insignifiant = False;
134 if (in_array($valeur['type'][$cle], array('text/plain', '', 'application/octet-stream'))) { // si mime-type insignifiant, on se base uniquement sur l'extension (comme par exemple dans recuperer_infos_distantes())
135 $mime_insignifiant = True;
136 }
137
138 if ($options['mime'] == 'specifique'){
139 if (!$mime_insignifiant) {
140 if (!in_array($mime_type,$options['mime_specifique'])){
141 return _T('verifier:erreur_type_non_autorise',array('name'=>$valeur['name'][$cle]));
142 }
143 }
144 $res = sql_select('mime_type','spip_types_documents', sql_in('mime_type',$options['mime_specifique']).' and extension='.sql_quote($extension));
145 if (sql_count($res) == 0) {
146 return _T('verifier:erreur_type_non_autorise',array('name'=>$valeur['name'][$cle]));
147 }
148 } elseif ($options['mime'] == 'tout_mime') {
149 if (!$mime_insignifiant) {
150 $res = sql_select('mime_type','spip_types_documents','mime_type='.sql_quote($mime_type).' and extension='.sql_quote($extension));
151 } else {
152 $res = sql_select('mime_type','spip_types_documents','extension='.sql_quote($extension));
153 }
154 if (sql_count($res) == 0) {
155 return _T('verifier:erreur_type_non_autorise',array('name'=>$valeur['name'][$cle]));
156 }
157 } elseif ($options['mime'] == 'image_web') {
158 if (!in_array($mime_type,array('image/gif','image/jpeg','image/png'))) {
159 return _T('verifier:erreur_type_image',array('name'=>$valeur['name'][$cle]));
160 }
161 }
162 return '';
163 }
164
165
166 /**
167 * Vérifier la taille d'une saisie d'envoi de fichiers
168 *
169 * La taille est vérifiée en fonction du paramètre passé en option, sinon en fonction d'une constante:
170 * - _IMG_MAX_SIZE si jpg/png/gif
171 * - _DOC_MAX_SIZE si pas jpg/png/gif ou si _IMG_MAX_SIZE n'est pas définie
172 *
173 * @param array $valeur
174 * Le sous tableau de `$_FILES` à vérifier, `$_FILES['logo']` par exemple
175 * Doit être un champ plusieurs uploads
176 * @param int $cle
177 * La clé du tableau qu'on vérifie
178 * @param array $options
179 * Les options tels que passés à verifier_fichiers()
180 * @return string
181 **/
182 function verifier_fichier_taille($valeur,$cle,$options){
183 $taille = $valeur['size'][$cle];
184 $mime = $valeur['type'][$cle];
185
186 // On commence par déterminer la taille max
187 if (isset($options['taille_max'])) {
188 $taille_max = $options['taille_max'];
189 } elseif (in_array($mime, array('image/gif','image/jpeg','image/png')) and defined('_IMG_MAX_SIZE')) {
190 $taille_max = _IMG_MAX_SIZE;
191 } elseif (defined('_DOC_MAX_SIZE')) {
192 $taille_max = _DOC_MAX_SIZE;
193 } else {
194 $taille_max = 0; // pas de taille max.
195 }
196
197 $taille_max = intval($taille_max); // précaution
198
199 //Si la taille max est déterminée, on vérifie que le fichier ne dépasse pas cette taille
200 if ($taille_max) {
201 $taille_max = 1024 * $taille_max; // passage de l'expression en kibioctets à une expression en octets
202 if ($taille > $taille_max) {
203 return _T('verifier:erreur_taille_fichier', array(
204 'name' => $valeur['name'][$cle],
205 'taille_max' => taille_en_octets($taille_max),
206 'taille' => taille_en_octets($taille)
207 ));
208 }
209 }
210 return '';
211 }
212
213 /**
214 * Vérifier la dimension d'une saisie d'envoi de fichiers
215 *
216 * Les dimensions sont vérifiées en fonction du paramètre passé en option, sinon en fonction des constantes:
217 * - _IMG_MAX_WIDTH
218 * - _IMG_MAX_HEIGHT
219 *
220 * On suppose que le type mime a été vérifié auparavent
221 * @param array $valeur
222 * Le sous tableau de $_FILES à vérifier, $_FILES['logo'] par exemple
223 * Doit être un champ plusieurs uploads
224 * @param int $cle
225 * La clé du tableau qu'on vérifie
226 * @param array $options
227 * Les options tels que passés à verifier_fichiers()
228 * @return string
229 **/
230 function verifier_fichier_dimension_max($valeur, $cle, $options) {
231 // On commence par récupérer les dimension de l'image
232 include_spip('inc/filtres');
233 $imagesize = @getimagesize($valeur['tmp_name'][$cle]);
234
235 // Puis les infos sur ce qu'on autorise
236 $largeur_max = (isset($options['dimension_max']['largeur']) ? $options['dimension_max']['largeur'] : (defined('_IMG_MAX_WIDTH') ? _IMG_MAX_WIDTH : 0));
237 $hauteur_max = (isset($options['dimension_max']['hauteur']) ? $options['dimension_max']['hauteur'] : (defined('_IMG_MAX_HEIGHT') ? _IMG_MAX_HEIGHT : 0));
238 $autoriser_rotation = (isset($options['dimension_max']['autoriser_rotation'])) ? $options['dimension_max']['autoriser_rotation'] : false;
239
240 // Et on teste, si on a ce qui est nécessaire pour tester
241 if ($imagesize and ($hauteur_max or $largeur_max)) {
242 if ($autoriser_rotation) { // dans le cas où on autorise une rotation
243 if (
244 ($imagesize[0] > $largeur_max or $imagesize[1] > $hauteur_max)
245 and
246 ($imagesize[1] > $largeur_max or $imagesize[0] > $hauteur_max)
247 ) {
248 return _T('verifier:erreur_dimension_image', array(
249 'name' => $valeur['name'][$cle],
250 'taille_max' => $largeur_max . '&nbsp;px * ' . $hauteur_max . '&nbsp;px',
251 'taille' => $imagesize[0] . '&nbsp;px * ' . $imagesize[1] . '&nbsp;px'
252 )
253 );
254 }
255 } else { // dans le cas où on autorise pas la rotation
256 if ($imagesize[0] > $largeur_max or $imagesize[1] > $hauteur_max) {
257 return _T('verifier:erreur_dimension_image', array(
258 'name' => $valeur['name'][$cle],
259 'taille_max' => $largeur_max . '&nbsp;px * ' . $hauteur_max . '&nbsp;px',
260 'taille' => $imagesize[0] . '&nbsp;px * ' . $imagesize[1] . '&nbsp;px'
261 )
262 );
263 }
264 }
265 }
266 }