|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/***************************************************************************\ |
|
4
|
|
|
* SPIP, Système de publication pour l'internet * |
|
5
|
|
|
* * |
|
6
|
|
|
* Copyright © avec tendresse depuis 2001 * |
|
7
|
|
|
* Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James * |
|
8
|
|
|
* * |
|
9
|
|
|
* Ce programme est un logiciel libre distribué sous licence GNU/GPL. * |
|
10
|
|
|
* Pour plus de détails voir le fichier COPYING.txt ou l'aide en ligne. * |
|
11
|
|
|
\***************************************************************************/ |
|
12
|
|
|
|
|
13
|
|
|
/** |
|
14
|
|
|
* Gestion des actions sécurisées |
|
15
|
|
|
* |
|
16
|
|
|
* @package SPIP\Core\Actions |
|
17
|
|
|
**/ |
|
18
|
|
|
|
|
19
|
|
|
if (!defined('_ECRIRE_INC_VERSION')) { |
|
20
|
|
|
return; |
|
21
|
|
|
} |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* Génère ou vérifie une action sécurisée |
|
25
|
|
|
* |
|
26
|
|
|
* Interface d'appel: |
|
27
|
|
|
* |
|
28
|
|
|
* - au moins un argument: retourne une URL ou un formulaire securisés |
|
29
|
|
|
* - sans argument : vérifie la sécurité et retourne `_request('arg')`, ou exit. |
|
30
|
|
|
* |
|
31
|
|
|
* @uses securiser_action_auteur() Pour produire l'URL ou le formulaire |
|
32
|
|
|
* @example |
|
33
|
|
|
* Tester une action reçue et obtenir son argument : |
|
34
|
|
|
* ``` |
|
35
|
|
|
* $securiser_action = charger_fonction('securiser_action'); |
|
36
|
|
|
* $arg = $securiser_action(); |
|
37
|
|
|
* ``` |
|
38
|
|
|
* |
|
39
|
|
|
* @param string $action |
|
40
|
|
|
* @param string $arg |
|
41
|
|
|
* @param string $redirect |
|
42
|
|
|
* @param bool|int|string $mode |
|
43
|
|
|
* - -1 : renvoyer action, arg et hash sous forme de array() |
|
44
|
|
|
* - true ou false : renvoyer une url, avec & (false) ou & (true) |
|
45
|
|
|
* - string : renvoyer un formulaire |
|
46
|
|
|
* @param string|int $att |
|
47
|
|
|
* id_auteur pour lequel generer l'action en mode url ou array() |
|
48
|
|
|
* atributs du formulaire en mode formulaire |
|
49
|
|
|
* @param bool $public |
|
50
|
|
|
* @return array|string |
|
51
|
|
|
*/ |
|
52
|
|
|
function inc_securiser_action_dist($action = '', $arg = '', $redirect = "", $mode = false, $att = '', $public = false) { |
|
53
|
|
|
if ($action) { |
|
54
|
|
|
return securiser_action_auteur($action, $arg, $redirect, $mode, $att, $public); |
|
55
|
|
|
} else { |
|
56
|
|
|
$arg = _request('arg'); |
|
57
|
|
|
$hash = _request('hash'); |
|
58
|
|
|
$action = _request('action') ? _request('action') : _request('formulaire_action'); |
|
59
|
|
|
if ($a = verifier_action_auteur("$action-$arg", $hash)) { |
|
|
|
|
|
|
60
|
|
|
return $arg; |
|
61
|
|
|
} |
|
62
|
|
|
include_spip('inc/minipres'); |
|
63
|
|
|
echo minipres(); |
|
64
|
|
|
exit; |
|
65
|
|
|
} |
|
66
|
|
|
} |
|
67
|
|
|
|
|
68
|
|
|
/** |
|
69
|
|
|
* Confirmer avant suppression si on arrive par un bouton action |
|
70
|
|
|
* a appeler dans la fonction action avant toute action destructrice |
|
71
|
|
|
* |
|
72
|
|
|
* demander_confirmation_avant_action("Supprimer l'article xxxx", "Oui je veux le supprimer"); |
|
73
|
|
|
* |
|
74
|
|
|
* L'action affiche le formulaire de demande de confirmation sans rendre la main au premier appel, |
|
75
|
|
|
* si l'utilisateur clique, cela relance l'action avec un confirm et quand on repasse ici, la fonction ne fera rien et l'action se finira normalement |
|
76
|
|
|
* |
|
77
|
|
|
* @param string $titre |
|
78
|
|
|
* @param string $titre_bouton |
|
79
|
|
|
* @param string|null $url_action |
|
80
|
|
|
* @return bool |
|
|
|
|
|
|
81
|
|
|
*/ |
|
82
|
|
|
function demander_confirmation_avant_action($titre, $titre_bouton, $url_action=null) { |
|
83
|
|
|
|
|
84
|
|
|
if (!$url_action) { |
|
|
|
|
|
|
85
|
|
|
$url_action = self(); |
|
86
|
|
|
$action = _request('action'); |
|
87
|
|
|
$url_action = parametre_url($url_action, 'action', $action, '&'); |
|
88
|
|
|
} |
|
89
|
|
|
else { |
|
90
|
|
|
$action = parametre_url($url_action, 'action'); |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
$arg = parametre_url($url_action, 'arg'); |
|
94
|
|
|
$confirm = md5("$action:$arg:".realpath(__FILE__)); |
|
95
|
|
|
if (_request('confirm_action') === $confirm) { |
|
96
|
|
|
return true; |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
$url_confirm = parametre_url($url_action, "confirm_action", $confirm, '&'); |
|
100
|
|
|
include_spip("inc/filtres"); |
|
101
|
|
|
$bouton_action = bouton_action($titre_bouton, $url_confirm); |
|
|
|
|
|
|
102
|
|
|
$corps = "<div style='text-align:center;'>$bouton_action</div>"; |
|
103
|
|
|
|
|
104
|
|
|
include_spip("inc/minipres"); |
|
105
|
|
|
echo minipres($titre,$corps); |
|
106
|
|
|
exit; |
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
|
|
/** |
|
110
|
|
|
* Retourne une URL ou un formulaire sécurisés |
|
111
|
|
|
* |
|
112
|
|
|
* @note |
|
113
|
|
|
* Attention: PHP applique urldecode sur $_GET mais pas sur $_POST |
|
114
|
|
|
* cf http://fr.php.net/urldecode#48481 |
|
115
|
|
|
* https://code.spip.net/@securiser_action_auteur |
|
116
|
|
|
* |
|
117
|
|
|
* @uses calculer_action_auteur() |
|
118
|
|
|
* @uses generer_form_action() |
|
119
|
|
|
* |
|
120
|
|
|
* @param string $action |
|
121
|
|
|
* @param string $arg |
|
122
|
|
|
* @param string $redirect |
|
123
|
|
|
* @param bool|int|string $mode |
|
124
|
|
|
* - -1 : renvoyer action, arg et hash sous forme de array() |
|
125
|
|
|
* - true ou false : renvoyer une url, avec & (false) ou & (true) |
|
126
|
|
|
* - string : renvoyer un formulaire |
|
127
|
|
|
* @param string|int $att |
|
128
|
|
|
* - id_auteur pour lequel générer l'action en mode URL ou array() |
|
129
|
|
|
* - atributs du formulaire en mode formulaire |
|
130
|
|
|
* @param bool $public |
|
131
|
|
|
* @return array|string |
|
|
|
|
|
|
132
|
|
|
* - string URL, si $mode = true ou false, |
|
133
|
|
|
* - string code HTML du formulaire, si $mode texte, |
|
134
|
|
|
* - array Tableau (action=>x, arg=>x, hash=>x) si $mode=-1. |
|
135
|
|
|
*/ |
|
136
|
|
|
function securiser_action_auteur($action, $arg, $redirect = "", $mode = false, $att = '', $public = false) { |
|
137
|
|
|
|
|
138
|
|
|
// mode URL ou array |
|
139
|
|
|
if (!is_string($mode)) { |
|
140
|
|
|
$hash = calculer_action_auteur("$action-$arg", is_numeric($att) ? $att : null); |
|
141
|
|
|
|
|
142
|
|
|
$r = rawurlencode($redirect); |
|
143
|
|
|
if ($mode === -1) { |
|
144
|
|
|
return array('action' => $action, 'arg' => $arg, 'hash' => $hash); |
|
145
|
|
|
} else { |
|
146
|
|
|
return generer_url_action($action, "arg=" . rawurlencode($arg) . "&hash=$hash" . (!$r ? '' : "&redirect=$r"), |
|
147
|
|
|
$mode, $public); |
|
|
|
|
|
|
148
|
|
|
} |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
// mode formulaire |
|
152
|
|
|
$hash = calculer_action_auteur("$action-$arg"); |
|
153
|
|
|
$att .= " style='margin: 0px; border: 0px'"; |
|
154
|
|
|
if ($redirect) { |
|
155
|
|
|
$redirect = "\n\t\t<input name='redirect' type='hidden' value='" . str_replace("'", ''', $redirect) . "' />"; |
|
156
|
|
|
} |
|
157
|
|
|
$mode .= $redirect . " |
|
158
|
|
|
<input name='hash' type='hidden' value='$hash' /> |
|
159
|
|
|
<input name='arg' type='hidden' value='$arg' />"; |
|
160
|
|
|
|
|
161
|
|
|
return generer_form_action($action, $mode, $att, $public); |
|
162
|
|
|
} |
|
163
|
|
|
|
|
164
|
|
|
/** |
|
165
|
|
|
* Caracteriser un auteur : l'auteur loge si $id_auteur=null |
|
166
|
|
|
* |
|
167
|
|
|
* @param int|null $id_auteur |
|
168
|
|
|
* @return array |
|
169
|
|
|
*/ |
|
170
|
|
|
function caracteriser_auteur($id_auteur = null) { |
|
171
|
|
|
static $caracterisation = array(); |
|
172
|
|
|
|
|
173
|
|
|
if (is_null($id_auteur) and !isset($GLOBALS['visiteur_session']['id_auteur'])) { |
|
174
|
|
|
// si l'auteur courant n'est pas connu alors qu'il peut demander une action |
|
175
|
|
|
// c'est une connexion par php_auth ou 1 instal, on se rabat sur le cookie. |
|
176
|
|
|
// S'il n'avait pas le droit de realiser cette action, le hash sera faux. |
|
177
|
|
|
if (isset($_COOKIE['spip_session']) |
|
178
|
|
|
and (preg_match('/^(\d+)/', $_COOKIE['spip_session'], $r)) |
|
179
|
|
|
) { |
|
180
|
|
|
return array($r[1], ''); |
|
181
|
|
|
// Necessaire aux forums anonymes. |
|
182
|
|
|
// Pour le reste, ca echouera. |
|
183
|
|
|
} else { |
|
184
|
|
|
return array('0', ''); |
|
185
|
|
|
} |
|
186
|
|
|
} |
|
187
|
|
|
// Eviter l'acces SQL si le pass est connu de PHP |
|
188
|
|
|
if (is_null($id_auteur)) { |
|
189
|
|
|
$id_auteur = isset($GLOBALS['visiteur_session']['id_auteur']) ? $GLOBALS['visiteur_session']['id_auteur'] : 0; |
|
190
|
|
View Code Duplication |
if (isset($GLOBALS['visiteur_session']['pass']) and $GLOBALS['visiteur_session']['pass']) { |
|
|
|
|
|
|
191
|
|
|
return $caracterisation[$id_auteur] = array($id_auteur, $GLOBALS['visiteur_session']['pass']); |
|
192
|
|
|
} |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
if (isset($caracterisation[$id_auteur])) { |
|
196
|
|
|
return $caracterisation[$id_auteur]; |
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
if ($id_auteur) { |
|
200
|
|
|
include_spip('base/abstract_sql'); |
|
201
|
|
|
$t = sql_fetsel("id_auteur, pass", "spip_auteurs", "id_auteur=$id_auteur"); |
|
202
|
|
|
if ($t) { |
|
|
|
|
|
|
203
|
|
|
return $caracterisation[$id_auteur] = array($t['id_auteur'], $t['pass']); |
|
204
|
|
|
} |
|
205
|
|
|
include_spip('inc/minipres'); |
|
206
|
|
|
echo minipres(); |
|
207
|
|
|
exit; |
|
208
|
|
|
} // Visiteur anonyme, pour ls forums par exemple |
|
209
|
|
|
else { |
|
210
|
|
|
return array('0', ''); |
|
211
|
|
|
} |
|
212
|
|
|
} |
|
213
|
|
|
|
|
214
|
|
|
/** |
|
215
|
|
|
* Calcule une cle securisee pour une action et un auteur donnes |
|
216
|
|
|
* utilisee pour generer des urls personelles pour executer une action qui modifie la base |
|
217
|
|
|
* et verifier la legitimite de l'appel a l'action |
|
218
|
|
|
* |
|
219
|
|
|
* @param string $action |
|
220
|
|
|
* @param int $id_auteur |
|
221
|
|
|
* @param string $pass |
|
222
|
|
|
* @param string $alea |
|
223
|
|
|
* @return string |
|
|
|
|
|
|
224
|
|
|
*/ |
|
225
|
|
|
function _action_auteur($action, $id_auteur, $pass, $alea) { |
|
226
|
|
|
static $sha = array(); |
|
227
|
|
|
if (!isset($sha[$id_auteur . $pass . $alea])) { |
|
228
|
|
|
if (!isset($GLOBALS['meta'][$alea])) { |
|
229
|
|
|
if (!$exec = _request('exec') or !autoriser_sans_cookie($exec)){ |
|
230
|
|
|
include_spip('inc/acces'); |
|
231
|
|
|
charger_aleas(); |
|
232
|
|
|
if (empty($GLOBALS['meta'][$alea])){ |
|
233
|
|
|
include_spip('inc/minipres'); |
|
234
|
|
|
echo minipres(); |
|
235
|
|
|
spip_log("$alea indisponible"); |
|
236
|
|
|
exit; |
|
237
|
|
|
} |
|
238
|
|
|
} |
|
239
|
|
|
} |
|
240
|
|
|
include_spip('auth/sha256.inc'); |
|
241
|
|
|
$sha[$id_auteur . $pass . $alea] = spip_sha256($id_auteur . $pass . @$GLOBALS['meta'][$alea]); |
|
242
|
|
|
} |
|
243
|
|
|
if (function_exists('sha1')) { |
|
244
|
|
|
return sha1($action . $sha[$id_auteur . $pass . $alea]); |
|
245
|
|
|
} else { |
|
246
|
|
|
return md5($action . $sha[$id_auteur . $pass . $alea]); |
|
247
|
|
|
} |
|
248
|
|
|
} |
|
249
|
|
|
|
|
250
|
|
|
/** |
|
251
|
|
|
* Calculer le hash qui signe une action pour un auteur |
|
252
|
|
|
* |
|
253
|
|
|
* @param string $action |
|
254
|
|
|
* @param int|null $id_auteur |
|
255
|
|
|
* @return string |
|
|
|
|
|
|
256
|
|
|
*/ |
|
257
|
|
|
function calculer_action_auteur($action, $id_auteur = null) { |
|
258
|
|
|
list($id_auteur, $pass) = caracteriser_auteur($id_auteur); |
|
259
|
|
|
|
|
260
|
|
|
return _action_auteur($action, $id_auteur, $pass, 'alea_ephemere'); |
|
261
|
|
|
} |
|
262
|
|
|
|
|
263
|
|
|
|
|
264
|
|
|
/** |
|
265
|
|
|
* Verifier le hash de signature d'une action |
|
266
|
|
|
* toujours exclusivement pour l'auteur en cours |
|
267
|
|
|
* |
|
268
|
|
|
* @param $action |
|
269
|
|
|
* @param $hash |
|
270
|
|
|
* @return bool |
|
271
|
|
|
*/ |
|
272
|
|
|
function verifier_action_auteur($action, $hash) { |
|
273
|
|
|
list($id_auteur, $pass) = caracteriser_auteur(); |
|
274
|
|
|
if ($hash == _action_auteur($action, $id_auteur, $pass, 'alea_ephemere')) { |
|
275
|
|
|
return true; |
|
276
|
|
|
} |
|
277
|
|
|
if ($hash == _action_auteur($action, $id_auteur, $pass, 'alea_ephemere_ancien')) { |
|
|
|
|
|
|
278
|
|
|
return true; |
|
279
|
|
|
} |
|
280
|
|
|
|
|
281
|
|
|
return false; |
|
282
|
|
|
} |
|
283
|
|
|
|
|
284
|
|
|
// |
|
285
|
|
|
// Des fonctions independantes du visiteur, qui permettent de controler |
|
286
|
|
|
// par exemple que l'URL d'un document a la bonne cle de lecture |
|
287
|
|
|
// |
|
288
|
|
|
|
|
289
|
|
|
/** |
|
290
|
|
|
* Renvoyer le secret du site, et le generer si il n'existe pas encore |
|
291
|
|
|
* Le secret du site doit rester aussi secret que possible, et est eternel |
|
292
|
|
|
* On ne doit pas l'exporter |
|
293
|
|
|
* |
|
294
|
|
|
* @return string |
|
295
|
|
|
*/ |
|
296
|
|
|
function secret_du_site() { |
|
297
|
|
|
if (!isset($GLOBALS['meta']['secret_du_site'])) { |
|
298
|
|
|
include_spip('base/abstract_sql'); |
|
299
|
|
|
$GLOBALS['meta']['secret_du_site'] = sql_getfetsel('valeur', 'spip_meta', "nom='secret_du_site'"); |
|
300
|
|
|
} |
|
301
|
|
|
if (!isset($GLOBALS['meta']['secret_du_site']) |
|
302
|
|
|
or (strlen($GLOBALS['meta']['secret_du_site']) < 64) |
|
303
|
|
|
) { |
|
304
|
|
|
include_spip('inc/acces'); |
|
305
|
|
|
include_spip('auth/sha256.inc'); |
|
306
|
|
|
ecrire_meta('secret_du_site', |
|
307
|
|
|
spip_sha256( |
|
308
|
|
|
$_SERVER["DOCUMENT_ROOT"] |
|
309
|
|
|
. (isset($_SERVER['SERVER_SIGNATURE']) ? $_SERVER["SERVER_SIGNATURE"] : "") |
|
310
|
|
|
. creer_uniqid() |
|
311
|
|
|
), 'non'); |
|
312
|
|
|
lire_metas(); // au cas ou ecrire_meta() ne fonctionne pas |
|
313
|
|
|
} |
|
314
|
|
|
|
|
315
|
|
|
return $GLOBALS['meta']['secret_du_site']; |
|
316
|
|
|
} |
|
317
|
|
|
|
|
318
|
|
|
/** |
|
319
|
|
|
* Calculer une signature valable pour une action et pour le site |
|
320
|
|
|
* |
|
321
|
|
|
* @param string $action |
|
322
|
|
|
* @return string |
|
323
|
|
|
*/ |
|
324
|
|
|
function calculer_cle_action($action) { |
|
325
|
|
|
if (function_exists('sha1')) { |
|
326
|
|
|
return sha1($action . secret_du_site()); |
|
327
|
|
|
} else { |
|
328
|
|
|
return md5($action . secret_du_site()); |
|
329
|
|
|
} |
|
330
|
|
|
} |
|
331
|
|
|
|
|
332
|
|
|
/** |
|
333
|
|
|
* Verifier la cle de signature d'une action valable pour le site |
|
334
|
|
|
* |
|
335
|
|
|
* @param string $action |
|
336
|
|
|
* @param string $cle |
|
337
|
|
|
* @return bool |
|
338
|
|
|
*/ |
|
339
|
|
|
function verifier_cle_action($action, $cle) { |
|
340
|
|
|
return ($cle == calculer_cle_action($action)); |
|
341
|
|
|
} |
|
342
|
|
|
|
|
343
|
|
|
|
|
344
|
|
|
/** |
|
345
|
|
|
* Calculer le token de prévisu |
|
346
|
|
|
* |
|
347
|
|
|
* Il permettra de transmettre une URL publique d’un élément non encore publié, |
|
348
|
|
|
* pour qu’une personne tierce le relise. Valable quelques temps. |
|
349
|
|
|
* |
|
350
|
|
|
* @see verifier_token_previsu() |
|
351
|
|
|
* @param string $url Url à autoriser en prévisu |
|
352
|
|
|
* @param int|null id_auteur qui génère le token de prévisu. Null utilisera auteur courant. |
|
353
|
|
|
* @param string $alea Nom de l’alea à utiliser |
|
354
|
|
|
* @return string Token, de la forme "{id}*{hash}" |
|
355
|
|
|
*/ |
|
356
|
|
|
function calculer_token_previsu($url, $id_auteur = null, $alea = 'alea_ephemere') { |
|
357
|
|
|
if (is_null($id_auteur)) { |
|
358
|
|
|
if (!empty($GLOBALS['visiteur_session']['id_auteur'])) { |
|
359
|
|
|
$id_auteur = $GLOBALS['visiteur_session']['id_auteur']; |
|
360
|
|
|
} |
|
361
|
|
|
} |
|
362
|
|
|
if (!$id_auteur = intval($id_auteur)) { |
|
363
|
|
|
return ""; |
|
364
|
|
|
} |
|
365
|
|
|
// On nettoie l’URL de tous les var_. |
|
366
|
|
|
$url = nettoyer_uri_var($url); |
|
367
|
|
|
|
|
368
|
|
|
$token = _action_auteur('previsualiser-' . $url, $id_auteur, null, $alea); |
|
369
|
|
|
return "$id_auteur-$token"; |
|
370
|
|
|
} |
|
371
|
|
|
|
|
372
|
|
|
|
|
373
|
|
|
/** |
|
374
|
|
|
* Vérifie un token de prévisu |
|
375
|
|
|
* |
|
376
|
|
|
* Découpe le token pour avoir l’id_auteur, |
|
377
|
|
|
* Retrouve à partir de l’url un objet/id_objet en cours de parcours |
|
378
|
|
|
* Recrée un token pour l’auteur et l’objet trouvé et le compare au token. |
|
379
|
|
|
* |
|
380
|
|
|
* @see calculer_token_previsu() |
|
381
|
|
|
* @param string $token Token, de la forme '{id}*{hash}' |
|
382
|
|
|
* @return false|array |
|
|
|
|
|
|
383
|
|
|
* - `False` si echec, |
|
384
|
|
|
* + Tableau (id auteur, type d’objet, id_objet) sinon. |
|
385
|
|
|
*/ |
|
386
|
|
|
function verifier_token_previsu($token) { |
|
387
|
|
|
// retrouver auteur / hash |
|
388
|
|
|
$e = explode('-', $token, 2); |
|
389
|
|
|
if (count($e) == 2 and is_numeric(reset($e))) { |
|
390
|
|
|
$id_auteur = intval(reset($e)); |
|
391
|
|
|
} else { |
|
392
|
|
|
return false; |
|
393
|
|
|
} |
|
394
|
|
|
|
|
395
|
|
|
// calculer le type et id de l’url actuelle |
|
396
|
|
|
include_spip('inc/urls'); |
|
397
|
|
|
include_spip('inc/filtres_mini'); |
|
398
|
|
|
$url = url_absolue(self()); |
|
399
|
|
|
|
|
400
|
|
|
// verifier le token |
|
401
|
|
|
$_token = calculer_token_previsu($url, $id_auteur, 'alea_ephemere'); |
|
402
|
|
|
if (!$_token or $token !== $_token) { |
|
403
|
|
|
$_token = calculer_token_previsu($url, $id_auteur, 'alea_ephemere_ancien'); |
|
404
|
|
|
if (!$_token or $token !== $_token) { |
|
405
|
|
|
return false; |
|
406
|
|
|
} |
|
407
|
|
|
} |
|
408
|
|
|
|
|
409
|
|
|
return array( |
|
410
|
|
|
'id_auteur' => $id_auteur, |
|
411
|
|
|
); |
|
412
|
|
|
} |
|
413
|
|
|
|
|
414
|
|
|
/** |
|
415
|
|
|
* Décrire un token de prévisu en session |
|
416
|
|
|
* @uses verifier_token_previsu() |
|
417
|
|
|
* @return bool|array |
|
|
|
|
|
|
418
|
|
|
*/ |
|
419
|
|
|
function decrire_token_previsu() { |
|
420
|
|
|
static $desc = null; |
|
421
|
|
|
if (is_null($desc)) { |
|
422
|
|
|
if ($token = _request('var_previewtoken')) { |
|
423
|
|
|
$desc = verifier_token_previsu($token); |
|
424
|
|
|
} else { |
|
425
|
|
|
$desc = false; |
|
426
|
|
|
} |
|
427
|
|
|
} |
|
428
|
|
|
return $desc; |
|
429
|
|
|
} |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.