Skip to content
Extraits de code Groupes Projets
Valider 28490c47 rédigé par esj's avatar esj
Parcourir les fichiers

Amélioration de [8179]: dans l'espace privé comme dans le public (i.e. les...

Amélioration de [8179]: dans l'espace privé comme dans le public (i.e. les squelettes), on profite de la mise en cache de l'analyse des DTD pour aller y chercher la definition des entites html et ainsi contourner le bug de SAX de manière totalement fiable. En cas de Doctype indisponible (squelettes perso ou plugin, pour la distrib standard elle y est toujours) on continue à utiliser html2unicode (à qui il manque les entites dfinies dans xhmt_symbol.ent). A noter que SAX ne considère pas comme des entités les 4 cas particuliers notoires (amp lt gt quot) lorsqu'ils sont dans un attribut; c'est insuffisant mais ça suffit à contourner le bug proprement.
parent 195c1453
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -39,10 +39,6 @@ function defautElement($phraseur, $data) ...@@ -39,10 +39,6 @@ function defautElement($phraseur, $data)
// http://doc.spip.org/@phraserTout // http://doc.spip.org/@phraserTout
function phraserTout($phraseur, $data) function phraserTout($phraseur, $data)
{ {
// bug de SAX qui ne dit pas si une Entite est dans un attribut ou non
// ==> eliminer toutes les entites
$data = unicode2charset(html2unicode($data, true));
xml_parsestring($phraseur, $data); xml_parsestring($phraseur, $data);
return !$this->err ? $this->res : join('<br />', $this->err) . '<br />'; return !$this->err ? $this->res : join('<br />', $this->err) . '<br />';
} }
......
...@@ -14,6 +14,7 @@ if (!defined("_ECRIRE_INC_VERSION")) return; ...@@ -14,6 +14,7 @@ if (!defined("_ECRIRE_INC_VERSION")) return;
include_spip('inc/filtres'); include_spip('inc/filtres');
include_spip('inc/charsets'); include_spip('inc/charsets');
include_spip('xml/interfaces');
// http://doc.spip.org/@xml_debutElement // http://doc.spip.org/@xml_debutElement
function xml_debutElement($parser, $name, $attrs) function xml_debutElement($parser, $name, $attrs)
...@@ -190,7 +191,7 @@ function inc_sax_dist($page, $apply=false) ...@@ -190,7 +191,7 @@ function inc_sax_dist($page, $apply=false)
ob_end_clean(); ob_end_clean();
} }
$res = $phraseur_xml->phraserTout($xml_parser, $page); $res = $phraseur_xml->phraserTout($xml_parser, sax_bug($page));
xml_parser_free($xml_parser); xml_parser_free($xml_parser);
...@@ -200,4 +201,61 @@ function inc_sax_dist($page, $apply=false) ...@@ -200,4 +201,61 @@ function inc_sax_dist($page, $apply=false)
return $page; return $page;
} }
// SAX ne dit pas si une Entite est dans un attribut ou non.
// Les eliminer toutes sinon celles des attributs apparaissent en zone texte!
// Celles fondamentales pour la lecture (lt gt quot amp) sont conservees
// (d'ailleurs SAX ne les considere pas comme des entites dans un attribut)
// Si la DTD est dispo, on va chercher les entites dedans
// sinon on se rabat sur ce qu'en connait SPIP en standard.
function sax_bug($data)
{
$r = analyser_doctype($data);
if (!$r)
$data = html2unicode($data, true);
else {
list ($topelement, $avail, $grammaire, $rotlvl) = $r;
$file = _DIR_DTD . preg_replace('/[^\w.]/','_', $rotlvl) . '.gz';
if (lire_fichier($file, $r))
$this->dtc = unserialize($r);
else {
include_spip('xml/analyser_dtd');
$this->dtc = charger_dtd($grammaire, $avail);
ecrire_fichier($file, serialize($this->dtc));
}
$trans = array();
foreach($this->dtc->entites as $k => $v)
if (!strpos(" amp lt gt quot ", $k))
$trans["&$k;"] = $v;
$data = strtr($data, $trans);
}
return unicode2charset($data);
}
// http://doc.spip.org/@analyser_doctype
function analyser_doctype($data)
{
if (!preg_match(_REGEXP_DOCTYPE, $data, $r))
return array();
list(,,$topelement, $avail,$suite) = $r;
if (!preg_match('/^"([^"]*)"\s*(.*)$/', $suite, $r))
if (!preg_match("/^'([^']*)'\s*(.*)$/", $suite, $r))
return array();
list(,$rotlvl, $suite) = $r;
if (!$suite) {
$grammaire = $rotlvl;
$rotlvl = '';
} else {
if (!preg_match('/^"([^"]*)"\s*$/', $suite, $r))
if (!preg_match("/^'([^']*)'\s*$/", $suite, $r))
return array();
$grammaire = $r[1];
}
return array($topelement, $avail, $grammaire, $rotlvl);
}
?> ?>
...@@ -13,32 +13,6 @@ ...@@ -13,32 +13,6 @@
if (!defined("_ECRIRE_INC_VERSION")) return; if (!defined("_ECRIRE_INC_VERSION")) return;
include_spip('inc/sax'); include_spip('inc/sax');
include_spip('xml/interfaces');
// http://doc.spip.org/@analyser_doctype
function analyser_doctype($data)
{
if (!preg_match(_REGEXP_DOCTYPE, $data, $r))
return array();
list(,,$topelement, $avail,$suite) = $r;
if (!preg_match('/^"([^"]*)"\s*(.*)$/', $suite, $r))
if (!preg_match("/^'([^']*)'\s*(.*)$/", $suite, $r))
return array();
list(,$rotlvl, $suite) = $r;
if (!$suite) {
$grammaire = $rotlvl;
$rotlvl = '';
} else {
if (!preg_match('/^"([^"]*)"\s*$/', $suite, $r))
if (!preg_match("/^'([^']*)'\s*$/", $suite, $r))
return array();
$grammaire = $r[1];
}
return array($topelement, $avail, $grammaire, $rotlvl);
}
// http://doc.spip.org/@validerElement // http://doc.spip.org/@validerElement
function validerElement($phraseur, $name, $attrs) function validerElement($phraseur, $name, $attrs)
...@@ -307,24 +281,6 @@ function defautElement($phraseur, $data) ...@@ -307,24 +281,6 @@ function defautElement($phraseur, $data)
// http://doc.spip.org/@phraserTout // http://doc.spip.org/@phraserTout
function phraserTout($phraseur, $data) function phraserTout($phraseur, $data)
{ {
$r = analyser_doctype($data);
if ($r) {
list ($topelement, $avail, $grammaire, $rotlvl) = $r;
$file = _DIR_DTD . preg_replace('/[^\w.]/','_', $rotlvl) . '.gz';
if (lire_fichier($file, $r))
$this->dtc = unserialize($r);
else {
include_spip('xml/analyser_dtd');
$this->dtc = charger_dtd($grammaire, $avail);
ecrire_fichier($file, serialize($this->dtc));
}
}
// bug de SAX qui ne dit pas si une Entite est dans un attribut ou non
// ==> eliminer toutes les entites
$data = unicode2charset(html2unicode($data, true));
xml_parsestring($phraseur, $data); xml_parsestring($phraseur, $data);
$valider_passe2 = charger_fonction('valider_passe2', 'inc'); $valider_passe2 = charger_fonction('valider_passe2', 'inc');
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter