[SPIP] +spip v3.0.17
[lhc/web/clavette_www.git] / www / ecrire / public / sandbox.php
diff --git a/www/ecrire/public/sandbox.php b/www/ecrire/public/sandbox.php
new file mode 100644 (file)
index 0000000..a742c23
--- /dev/null
@@ -0,0 +1,173 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2014                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+
+if (!defined('_ECRIRE_INC_VERSION')) return;
+
+/**
+ * Composer le code d'execution d'un texte
+ * en principe juste un echappement de guillemets
+ * sauf si on veut aussi echapper et interdire les scripts serveurs
+ * dans les squelette
+ *
+ * @param string $texte
+ * @param string $code
+ * @param string $arglist
+ * @param Object $p
+ * @return string
+ */
+function sandbox_composer_texte($texte, &$p){
+       $code = "'".str_replace(array("\\","'"),array("\\\\","\\'"), $texte)."'";
+       return $code;
+}
+
+
+/**
+ * Composer le code d'execution d'un filtre
+ *
+ * @param string $fonc
+ * @param string $code
+ * @param string $arglist
+ * @param Object $p
+ * @return string
+ */
+function sandbox_composer_filtre($fonc, $code, $arglist, &$p){
+       if (isset($GLOBALS['spip_matrice'][$fonc])) {
+               $code = "filtrer('$fonc',$code$arglist)";
+       }
+
+       // le filtre est defini sous forme de fonction ou de methode
+       // par ex. dans inc_texte, inc_filtres ou mes_fonctions
+       elseif ($f = chercher_filtre($fonc)) {
+               // cas particulier : le filtre |set doit acceder a la $Pile
+               // proto: filtre_set(&$Pile, $val, $args...)
+               $refl = new ReflectionFunction($f);
+               $refs = $refl->getParameters();
+               if (isset($refs[0]) AND $refs[0]->name == 'Pile') {
+                       $code = "$f(\$Pile,$code$arglist)";
+               }
+               else {
+                       $code = "$f($code$arglist)";
+               }
+       }
+       // le filtre n'existe pas,
+       // on le notifie
+       else erreur_squelette(array('zbug_erreur_filtre', array('filtre'=>  texte_script($fonc))), $p);
+
+       return $code;
+}
+
+// Calculer un <INCLURE(xx.php)>
+// La constante ci-dessous donne le code general quand il s'agit d'un script.
+define('CODE_INCLURE_SCRIPT', 'if (!($path = %s) OR !is_readable($path))
+       erreur_squelette(array("fichier_introuvable", array("fichier" => "%s")), array(%s));
+else {
+       $contexte_inclus = %s;
+       include $path;
+}
+'
+);
+
+/**
+ * Composer le code d'inclusion PHP
+ *
+ * @param string $fichier
+ * @param Object $p
+ * @param array $_contexte
+ * @return string
+ */
+function sandbox_composer_inclure_php($fichier, &$p, $_contexte){
+       $compil = texte_script(memoriser_contexte_compil($p));
+       // si inexistant, on essaiera a l'execution
+       if ($path = find_in_path($fichier))
+               $path = "\"$path\"";
+       else $path = "find_in_path(\"$fichier\")";
+
+       return sprintf(CODE_INCLURE_SCRIPT, $path, $fichier, $compil, $_contexte);
+}
+
+/**
+ * Composer le code se securisation anti script
+ *
+ * @param string $code
+ * @param Object $p
+ * @return string
+ */
+function sandbox_composer_interdire_scripts($code, &$p){
+       // Securite
+       if ($p->interdire_scripts
+       AND $p->etoile != '**') {
+               if (!preg_match("/^sinon[(](.*),'([^']*)'[)]$/", $code, $r))
+                       $code = "interdire_scripts($code)";
+               else {
+                       $code = interdire_scripts($r[2]);
+                       $code = "sinon(interdire_scripts($r[1]),'$code')";
+               }
+       }
+       return $code;
+}
+
+
+/**
+ * Appliquer des filtres sur un squelette complet
+ * la fonction peut plusieurs tableaux de filtres a partir du 3eme argument
+ * qui seront appliques dans l'ordre
+ *
+ * @param array $skel
+ * @param string $corps
+ * @param array $filtres
+ * @param array ...
+ * @return mixed|string
+ */
+function sandbox_filtrer_squelette($skel, $corps, $filtres){
+       $series_filtres = func_get_args();
+       array_shift($series_filtres);// skel
+       array_shift($series_filtres);// corps
+
+       // proteger les <INCLUDE> et tous les morceaux de php licites
+       if ($skel['process_ins'] == 'php')
+               $corps = preg_replace_callback(',<[?](\s|php|=).*[?]>,UimsS','echapper_php_callback', $corps);
+
+       // recuperer les couples de remplacement
+       $replace = echapper_php_callback();
+
+       foreach($series_filtres as $filtres){
+               if (count($filtres))
+                       foreach ($filtres as $filtre) {
+                               if ($filtre AND $f = chercher_filtre($filtre))
+                                       $corps = $f($corps);
+                       }
+       }
+
+       // restaurer les echappements
+       return str_replace($replace[0],$replace[1],$corps);
+}
+
+
+// http://doc.spip.org/@echapper_php_callback
+function echapper_php_callback($r=null) {
+       static $src = array();
+       static $dst = array();
+
+       // si on recoit un tableau, on est en mode echappement
+       // on enregistre le code a echapper dans dst, et le code echappe dans src
+       if (is_array($r)) {
+               $dst[] = $r[0];
+               return $src[] = '___'.md5($r[0]).'___';
+       }
+
+       // si on recoit pas un tableau, on renvoit les couples de substitution
+       // et on RAZ les remplacements
+       $r = array($src,$dst);
+       $src = $dst = array();
+       return $r;
+}