From 28490c47e0e549195b7a65b171076d8329c809b0 Mon Sep 17 00:00:00 2001 From: "Committo,Ergo:sum" <esj@rezo.net> Date: Sat, 13 Jan 2007 12:06:27 +0000 Subject: [PATCH] =?UTF-8?q?Am=C3=A9lioration=20de=20[8179]:=20dans=20l'esp?= =?UTF-8?q?ace=20priv=C3=A9=20comme=20dans=20le=20public=20(i.e.=20les=20s?= =?UTF-8?q?quelettes),=20on=20profite=20de=20la=20mise=20en=20cache=20de?= =?UTF-8?q?=20l'analyse=20des=20DTD=20pour=20aller=20y=20chercher=20la=20d?= =?UTF-8?q?efinition=20des=20entites=20html=20et=20ainsi=20contourner=20le?= =?UTF-8?q?=20bug=20de=20SAX=20de=20mani=C3=A8re=20totalement=20fiable.=20?= =?UTF-8?q?En=20cas=20de=20Doctype=20indisponible=20(squelettes=20perso=20?= =?UTF-8?q?ou=20plugin,=20pour=20la=20distrib=20standard=20elle=20y=20est?= =?UTF-8?q?=20toujours)=20on=20continue=20=C3=A0=20utiliser=20html2unicode?= =?UTF-8?q?=20(=C3=A0=20qui=20il=20manque=20les=20entites=20dfinies=20dans?= =?UTF-8?q?=20xhmt=5Fsymbol.ent).=20A=20noter=20que=20SAX=20ne=20consid?= =?UTF-8?q?=C3=A8re=20pas=20comme=20des=20entit=C3=A9s=20les=204=20cas=20p?= =?UTF-8?q?articuliers=20notoires=20(amp=20lt=20gt=20quot)=20lorsqu'ils=20?= =?UTF-8?q?sont=20dans=20un=20attribut;=20c'est=20insuffisant=20mais=20?= =?UTF-8?q?=C3=A7a=20suffit=20=C3=A0=20contourner=20le=20bug=20proprement.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecrire/inc/indenter_xml.php | 4 --- ecrire/inc/sax.php | 60 ++++++++++++++++++++++++++++++++++++- ecrire/inc/valider_xml.php | 44 --------------------------- 3 files changed, 59 insertions(+), 49 deletions(-) diff --git a/ecrire/inc/indenter_xml.php b/ecrire/inc/indenter_xml.php index 2504a48a76..5ba800146f 100644 --- a/ecrire/inc/indenter_xml.php +++ b/ecrire/inc/indenter_xml.php @@ -39,10 +39,6 @@ function defautElement($phraseur, $data) // http://doc.spip.org/@phraserTout 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); return !$this->err ? $this->res : join('<br />', $this->err) . '<br />'; } diff --git a/ecrire/inc/sax.php b/ecrire/inc/sax.php index eba92dd3fd..ba5f5b020c 100644 --- a/ecrire/inc/sax.php +++ b/ecrire/inc/sax.php @@ -14,6 +14,7 @@ if (!defined("_ECRIRE_INC_VERSION")) return; include_spip('inc/filtres'); include_spip('inc/charsets'); +include_spip('xml/interfaces'); // http://doc.spip.org/@xml_debutElement function xml_debutElement($parser, $name, $attrs) @@ -190,7 +191,7 @@ function inc_sax_dist($page, $apply=false) ob_end_clean(); } - $res = $phraseur_xml->phraserTout($xml_parser, $page); + $res = $phraseur_xml->phraserTout($xml_parser, sax_bug($page)); xml_parser_free($xml_parser); @@ -200,4 +201,61 @@ function inc_sax_dist($page, $apply=false) 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); +} + ?> diff --git a/ecrire/inc/valider_xml.php b/ecrire/inc/valider_xml.php index ccd7bedcd9..38bfc22f51 100644 --- a/ecrire/inc/valider_xml.php +++ b/ecrire/inc/valider_xml.php @@ -13,32 +13,6 @@ if (!defined("_ECRIRE_INC_VERSION")) return; 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 function validerElement($phraseur, $name, $attrs) @@ -307,24 +281,6 @@ function defautElement($phraseur, $data) // http://doc.spip.org/@phraserTout 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); $valider_passe2 = charger_fonction('valider_passe2', 'inc'); -- GitLab