[SPIP] ~v3.2.3-->v3.2.4
[lhc/web/www.git] / www / ecrire / inc / filtres_mini.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2019 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 /**
14 * Filtres d'URL et de liens
15 *
16 * @package SPIP\Core\Filtres\Liens
17 **/
18
19 if (!defined('_ECRIRE_INC_VERSION')) {
20 return;
21 }
22
23
24 /**
25 * Nettoyer une URL contenant des `../`
26 *
27 * Inspiré (de loin) par PEAR:NetURL:resolvePath
28 *
29 * @example
30 * ```
31 * resolve_path('/.././/truc/chose/machin/./.././.././hopla/..');
32 * ```
33 *
34 * @param string $url URL
35 * @return string URL nettoyée
36 **/
37 function resolve_path($url) {
38 list($url, $query) = array_pad(explode('?', $url, 2), 2, null);
39 while (preg_match(',/\.?/,', $url, $regs) # supprime // et /./
40 or preg_match(',/[^/]*/\.\./,S', $url, $regs) # supprime /toto/../
41 or preg_match(',^/\.\./,S', $url, $regs) # supprime les /../ du haut
42 ) {
43 $url = str_replace($regs[0], '/', $url);
44 }
45
46 if ($query) {
47 $url .= '?' . $query;
48 }
49
50 return '/' . preg_replace(',^/,S', '', $url);
51 }
52
53
54 /**
55 * Suivre un lien depuis une URL donnée vers une nouvelle URL
56 *
57 * @uses resolve_path()
58 * @example
59 * ```
60 * suivre_lien(
61 * 'http://rezo.net/sous/dir/../ect/ory/fi.html..s#toto',
62 * 'a/../../titi.coco.html/tata#titi');
63 * ```
64 *
65 * @param string $url URL de base
66 * @param string $lien Lien ajouté à l'URL
67 * @return string URL complète.
68 **/
69 function suivre_lien($url, $lien) {
70
71 if (preg_match(',^(mailto|javascript|data|tel|callto|file|ftp):,iS', $lien)) {
72 return $lien;
73 }
74 if (preg_match(';^((?:[a-z]{3,33}:)?//.*?)(/.*)?$;iS', $lien, $r)) {
75 $r = array_pad($r, 3, null);
76
77 return $r[1] . resolve_path($r[2]);
78 }
79
80 # L'url site spip est un lien absolu aussi
81 if (isset($GLOBALS['meta']['adresse_site']) and $lien == $GLOBALS['meta']['adresse_site']) {
82 return $lien;
83 }
84
85 # lien relatif, il faut verifier l'url de base
86 # commencer par virer la chaine de get de l'url de base
87 $dir = '/';
88 if (preg_match(';^((?:[a-z]{3,7}:)?//[^/]+)(/.*?/?)?([^/#?]*)([?][^#]*)?(#.*)?$;S', $url, $regs)) {
89 $debut = $regs[1];
90 $dir = !strlen($regs[2]) ? '/' : $regs[2];
91 $mot = $regs[3];
92 $get = isset($regs[4]) ? $regs[4] : '';
93 $hash = isset($regs[5]) ? $regs[5] : '';
94 }
95 switch (substr($lien, 0, 1)) {
96 case '/':
97 return $debut . resolve_path($lien);
98 case '#':
99 return $debut . resolve_path($dir . $mot . $get . $lien);
100 case '':
101 return $debut . resolve_path($dir . $mot . $get . $hash);
102 default:
103 return $debut . resolve_path($dir . $lien);
104 }
105 }
106
107
108 /**
109 * Transforme une URL relative en URL absolue
110 *
111 * S'applique sur une balise SPIP d'URL.
112 *
113 * @filtre
114 * @link http://www.spip.net/4127
115 * @uses suivre_lien()
116 * @example
117 * ```
118 * [(#URL_ARTICLE|url_absolue)]
119 * [(#CHEMIN{css/theme.css}|url_absolue)]
120 * ```
121 *
122 * @param string $url URL
123 * @param string $base URL de base de destination (par défaut ce sera l'URL de notre site)
124 * @return string Texte ou URL (en absolus)
125 **/
126 function url_absolue($url, $base = '') {
127 if (strlen($url = trim($url)) == 0) {
128 return '';
129 }
130 if (!$base) {
131 $base = url_de_base() . (_DIR_RACINE ? _DIR_RESTREINT_ABS : '');
132 }
133
134 return suivre_lien($base, $url);
135 }
136
137 /**
138 * Supprimer le protocole d'une url absolue
139 * pour le rendre implicite (URL commencant par "//")
140 *
141 * @param string $url_absolue
142 * @return string
143 */
144 function protocole_implicite($url_absolue) {
145 return preg_replace(';^[a-z]{3,7}://;i', '//', $url_absolue);
146 }
147
148 /**
149 * Verifier qu'une url est absolue et que son protocole est bien parmi une liste autorisee
150 * @param string $url_absolue
151 * @param array $protocoles_autorises
152 * @return bool
153 */
154 function protocole_verifier($url_absolue, $protocoles_autorises = array('http','https')) {
155
156 if (preg_match(';^([a-z]{3,7})://;i', $url_absolue, $m)) {
157 $protocole = $m[1];
158 if (in_array($protocole, $protocoles_autorises)
159 or in_array(strtolower($protocole), array_map('strtolower', $protocoles_autorises))) {
160 return true;
161 }
162 }
163 return false;
164 }
165
166 /**
167 * Transforme les URLs relatives en URLs absolues
168 *
169 * Ne s'applique qu'aux textes contenant des liens
170 *
171 * @filtre
172 * @uses url_absolue()
173 * @link http://www.spip.net/4126
174 *
175 * @param string $texte Texte
176 * @param string $base URL de base de destination (par défaut ce sera l'URL de notre site)
177 * @return string Texte avec des URLs absolues
178 **/
179 function liens_absolus($texte, $base = '') {
180 if (preg_match_all(',(<(a|link|image|img|script)\s[^<>]*(href|src)=[^<>]*>),imsS', $texte, $liens, PREG_SET_ORDER)) {
181 if (!function_exists('extraire_attribut')) {
182 include_spip('inc/filtres');
183 }
184 foreach ($liens as $lien) {
185 foreach (array('href', 'src') as $attr) {
186 $href = extraire_attribut($lien[0], $attr);
187 if (strlen($href) > 0) {
188 if (!preg_match(';^((?:[a-z]{3,7}:)?//);iS', $href)) {
189 $abs = url_absolue($href, $base);
190 if (rtrim($href, '/') !== rtrim($abs, '/') and !preg_match('/^#/', $href)) {
191 $texte_lien = inserer_attribut($lien[0], $attr, $abs);
192 $texte = str_replace($lien[0], $texte_lien, $texte);
193 }
194 }
195 }
196 }
197 }
198 }
199
200 return $texte;
201 }
202
203
204 /**
205 * Transforme une URL ou des liens en URL ou liens absolus
206 *
207 * @filtre
208 * @link http://www.spip.net/4128
209 * @global mode_abs_url Pour connaître le mode (url ou texte)
210 *
211 * @param string $texte Texte ou URL
212 * @param string $base URL de base de destination (par défaut ce sera l'URL de notre site)
213 * @return string Texte ou URL (en absolus)
214 **/
215 function abs_url($texte, $base = '') {
216 if ($GLOBALS['mode_abs_url'] == 'url') {
217 return url_absolue($texte, $base);
218 } else {
219 return liens_absolus($texte, $base);
220 }
221 }
222
223 /**
224 * htmlspecialchars wrapper (PHP >= 5.4 compat issue)
225 *
226 * @param string $string
227 * @param int $flags
228 * @param string $encoding
229 * @param bool $double_encode
230 * @return string
231 */
232 function spip_htmlspecialchars($string, $flags = null, $encoding = 'ISO-8859-1', $double_encode = true) {
233 if (is_null($flags)) {
234 $flags = ENT_COMPAT;
235 if (defined('ENT_HTML401')) {
236 $flags |= ENT_HTML401;
237 }
238 }
239
240 return htmlspecialchars($string, $flags, $encoding, $double_encode);
241 }
242
243 /**
244 * htmlentities wrapper (PHP >= 5.4 compat issue)
245 *
246 * @param string $string
247 * @param int $flags
248 * @param string $encoding
249 * @param bool $double_encode
250 * @return string
251 */
252 function spip_htmlentities($string, $flags = null, $encoding = 'ISO-8859-1', $double_encode = true) {
253 if (is_null($flags)) {
254 $flags = ENT_COMPAT;
255 if (defined('ENT_HTML401')) {
256 $flags |= ENT_HTML401;
257 }
258 }
259
260 return htmlentities($string, $flags, $encoding, $double_encode);
261 }