Completed
Push — master ( 605ecb...157706 )
by cam
06:19
created

filtres_mini.php ➔ protocole_verifier()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 3
nop 2
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
/***************************************************************************\
4
 *  SPIP, Systeme de publication pour l'internet                           *
5
 *                                                                         *
6
 *  Copyright (c) 2001-2018                                                *
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
	if (preg_match(';^((?:[a-z]{3,7}:)?//[^/]+)(/.*?/?)?([^/#?]*)([?][^#]*)?(#.*)?$;S', $url, $regs)) {
88
		$debut = $regs[1];
89
		$dir = !strlen($regs[2]) ? '/' : $regs[2];
90
		$mot = $regs[3];
91
		$get = isset($regs[4]) ? $regs[4] : '';
92
		$hash = isset($regs[5]) ? $regs[5] : '';
93
	}
94
	switch (substr($lien, 0, 1)) {
95
		case '/':
96
			return $debut . resolve_path($lien);
0 ignored issues
show
Bug introduced by
The variable $debut does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
97
		case '#':
98
			return $debut . resolve_path($dir . $mot . $get . $lien);
0 ignored issues
show
Bug introduced by
The variable $dir does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $mot does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $get does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
99
		case '':
100
			return $debut . resolve_path($dir . $mot . $get . $hash);
0 ignored issues
show
Bug introduced by
The variable $hash does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
101
		default:
102
			return $debut . resolve_path($dir . $lien);
103
	}
104
}
105
106
107
/**
108
 * Transforme une URL relative en URL absolue
109
 *
110
 * S'applique sur une balise SPIP d'URL.
111
 *
112
 * @filtre
113
 * @link http://www.spip.net/4127
114
 * @uses suivre_lien()
115
 * @example
116
 *     ```
117
 *     [(#URL_ARTICLE|url_absolue)]
118
 *     [(#CHEMIN{css/theme.css}|url_absolue)]
119
 *     ```
120
 *
121
 * @param string $url URL
122
 * @param string $base URL de base de destination (par défaut ce sera l'URL de notre site)
123
 * @return string Texte ou URL (en absolus)
124
 **/
125
function url_absolue($url, $base = '') {
126
	if (strlen($url = trim($url)) == 0) {
127
		return '';
128
	}
129
	if (!$base) {
130
		$base = url_de_base() . (_DIR_RACINE ? _DIR_RESTREINT_ABS : '');
131
	}
132
133
	return suivre_lien($base, $url);
134
}
135
136
/**
137
 * Supprimer le protocole d'une url absolue
138
 * pour le rendre implicite (URL commencant par "//")
139
 *
140
 * @param string $url_absolue
141
 * @return string
142
 */
143
function protocole_implicite($url_absolue) {
144
	return preg_replace(';^[a-z]{3,7}://;i', '//', $url_absolue);
145
}
146
147
/**
148
 * Verifier qu'une url est absolue et que son protocole est bien parmi une liste autorisee
149
 * @param string $url_absolue
150
 * @param array $protocoles_autorises
151
 * @return bool
152
 */
153
function protocole_verifier($url_absolue, $protocoles_autorises = array('http','https')) {
154
155
	if (preg_match(';^([a-z]{3,7})://;i', '//', $url_absolue, $m)) {
156
		$protocole = $m[1];
0 ignored issues
show
Bug introduced by
The variable $m does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
157
		if (in_array($protocole, $protocoles_autorises)
158
		  or in_array(strtolower($protocole), array_map('strtolower', $protocoles_autorises))) {
159
			return true;
160
		}
161
	}
162
	return false;
163
}
164
165
/**
166
 * Transforme les URLs relatives en URLs absolues
167
 *
168
 * Ne s'applique qu'aux textes contenant des liens
169
 *
170
 * @filtre
171
 * @uses url_absolue()
172
 * @link http://www.spip.net/4126
173
 *
174
 * @param string $texte Texte
175
 * @param string $base URL de base de destination (par défaut ce sera l'URL de notre site)
176
 * @return string Texte avec des URLs absolues
177
 **/
178
function liens_absolus($texte, $base = '') {
179
	if (preg_match_all(',(<(a|link|image|img|script)\s[^<>]*(href|src)=[^<>]*>),imsS', $texte, $liens, PREG_SET_ORDER)) {
180
		if (!function_exists('extraire_attribut')) {
181
			include_spip('inc/filtres');
182
		}
183
		foreach ($liens as $lien) {
184
			foreach (array('href', 'src') as $attr) {
185
				$href = extraire_attribut($lien[0], $attr);
186
				if (strlen($href) > 0) {
187
					if (!preg_match(';^((?:[a-z]{3,7}:)?//);iS', $href)) {
188
						$abs = url_absolue($href, $base);
0 ignored issues
show
Bug introduced by
It seems like $href defined by extraire_attribut($lien[0], $attr) on line 185 can also be of type array; however, url_absolue() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
189
						if (rtrim($href, '/') !== rtrim($abs, '/') and !preg_match('/^#/', $href)) {
190
							$texte_lien = inserer_attribut($lien[0], $attr, $abs);
191
							$texte = str_replace($lien[0], $texte_lien, $texte);
192
						}
193
					}
194
				}
195
			}
196
		}
197
	}
198
199
	return $texte;
200
}
201
202
203
/**
204
 * Transforme une URL ou des liens en URL ou liens absolus
205
 *
206
 * @filtre
207
 * @link http://www.spip.net/4128
208
 * @global mode_abs_url Pour connaître le mode (url ou texte)
209
 *
210
 * @param string $texte Texte ou URL
211
 * @param string $base URL de base de destination (par défaut ce sera l'URL de notre site)
212
 * @return string Texte ou URL (en absolus)
213
 **/
214
function abs_url($texte, $base = '') {
215
	if ($GLOBALS['mode_abs_url'] == 'url') {
216
		return url_absolue($texte, $base);
217
	} else {
218
		return liens_absolus($texte, $base);
219
	}
220
}
221
222
/**
223
 * htmlspecialchars wrapper (PHP >= 5.4 compat issue)
224
 *
225
 * @param string $string
226
 * @param int $flags
0 ignored issues
show
Documentation introduced by
Should the type for parameter $flags not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
227
 * @param string $encoding
228
 * @param bool $double_encode
229
 * @return string
230
 */
231 View Code Duplication
function spip_htmlspecialchars($string, $flags = null, $encoding = 'ISO-8859-1', $double_encode = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
232
	if (is_null($flags)) {
233
		$flags = ENT_COMPAT|ENT_HTML401;
234
	}
235
236
	return htmlspecialchars($string, $flags, $encoding, $double_encode);
237
}
238
239
/**
240
 * htmlentities wrapper (PHP >= 5.4 compat issue)
241
 *
242
 * @param string $string
243
 * @param int $flags
0 ignored issues
show
Documentation introduced by
Should the type for parameter $flags not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
244
 * @param string $encoding
245
 * @param bool $double_encode
246
 * @return string
247
 */
248 View Code Duplication
function spip_htmlentities($string, $flags = null, $encoding = 'ISO-8859-1', $double_encode = true) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
249
	if (is_null($flags)) {
250
		$flags = ENT_COMPAT|ENT_HTML401;
251
	}
252
253
	return htmlentities($string, $flags, $encoding, $double_encode);
254
}
255