1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/spip_ynh.git synced 2024-09-03 20:25:59 +02:00
spip_ynh/sources/ecrire/public/sandbox.php
2016-01-02 16:34:42 +01:00

177 lines
5 KiB
PHP

<?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...)
if (strpbrk($f, ':')) { // Class::method
$refl = new ReflectionMethod($f);
} else {
$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;
}