It will show how external entities point to the processor to contain and parse other documents, how to handle PIs, and the trustworthiness of a code that contains PIs.
The XML documents (Xmltest.xml and Xmltest2.xml) that can be used by the example are listed after the example.
External entity Example
<?php
$file = "Xmltest.xml";
function Trustedfile ($file) {
Only trust the local files owned by ourselves
if (!eregi ("^ (a-z]+)://", $file)
&& Fileowner ($file) = = Getmyuid ()) {
return true;
}
return false;
}
function startelement ($parser, $name, $attribs) {
Print "<<font color=\" #0000cc \ "> $name </font>";
if (sizeof ($attribs)) {
while (the list ($k, $v) = each ($attribs)) {
Print "<font color=\" #009900 \ "> $k </font>=\" <font
Color=\ "#990000 \" > $v </font>\ "";
}
}
print ">";
}
function EndElement ($parser, $name) {
Print "</<font color=\" #0000cc \ "> $name </font>>";
}
function Characterdata ($parser, $data) {
Print "<b> $data </b>";
}
function Pihandler ($parser, $target, $data) {
Switch (Strtolower ($target)) {
Case "PHP":
Global $parser _file;
If the parsed document is ' trusted ', we say it is safe
To execute PHP code inside it. If not, display the code
instead.
if (Trustedfile ($parser _file[$parser])) {
eval ($data);
} else {
printf ("Untrusted PHP Code: <i>%s</i>",
Htmlspecialchars ($data));
}
Break
}
}
function DefaultHandler ($parser, $data) {
if (substr ($data, 0, 1) = = "&" && substr ($data,-1, 1) = = ";") {
printf (' <font color= "#aa00aa" >%s</font> ",
Htmlspecialchars ($data));
} else {
printf (' <font size= "-1" >%s</font> ",
Htmlspecialchars ($data));
}
}
function Externalentityrefhandler ($parser, $openEntityNames, $base, $systemId,
$PUBLICID) {
if ($systemId) {
if (!list ($parser, $fp) = New_xml_parser ($systemId)) {
printf ("Could not open entity%s at%s\n", $openEntityNames,
$SYSTEMID);
return false;
}
while ($data = Fread ($fp, 4096)) {
if (!xml_parse ($parser, $data, feof ($fp)) {
printf ("XML error:%s at line%d while parsing entity%s\n")
Xml_error_string (Xml_get_error_code ($parser)),
Xml_get_current_line_number ($parser), $openEntityNames);
Xml_parser_free ($parser);
return false;
}
}
Xml_parser_free ($parser);
return true;
}
return false;
}
function New_xml_parser ($file) {
Global $parser _file;
$xml _parser = Xml_parser_create ();
xml_parser_set_option ($xml _parser, xml_option_case_folding, 1);
Xml_set_element_handler ($xml _parser, "startelement", "endelement");
Xml_set_character_data_handler ($xml _parser, "Characterdata");
Xml_set_processing_instruction_handler ($xml _parser, "Pihandler");
Xml_set_default_handler ($xml _parser, "DefaultHandler");
Xml_set_external_entity_ref_handler ($xml _parser, "Externalentityrefhandler");
if (!) ( $fp = @fopen ($file, "R")) {
return false;
}
if (!is_array ($parser _file)) {
Settype ($ Parser_file, "array");
}
$parser _file[$xml _parser] = $file;
return Array ($xml _parser, $fp);
}
if (!) ( List ($xml _parser, $fp) = New_xml_parser ($file))) {
Die ("Could not open XML input");
}
print "<pre>";
while ($data = Fread ($fp, 4096)) {
if (!xml_parse ($xml _parser, $data, feof ($fp)) {
Die (sprintf ("XML error:%s at line%d\n")
Xml_error_string (Xml_get_error_code ($xml _parser)),
Xml_get_current_line_number ($xml _parser)));
}
}
print "</pre>";
Print "Parse complete\n";
Xml_parser_free ($xml _parser);
?>
Xmltest.xml
<?xml version= ' 1.0 '?>
<! DOCTYPE Chapter SYSTEM "/JUST/A/TEST.DTD" [
<! ENTITY plainentity "FOO ENTITY" >
<! ENTITY systementity SYSTEM "Xmltest2.xml" >
]>
<chapter>
<title>title &plainEntity;</TITLE>
<para>
<informaltable>
<tgroup cols= "3" >
<tbody>
<row><entry>a1</entry><entry morerows= "1" >b1</entry><entry>c1</entry> </row>
<row><entry>a2</entry><entry>c2</entry></row>
<row><entry>a3</entry><entry>b3</entry><entry>c3</entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
&systemEntity;
<section id= "About" >
<title>about this document</title>
<para>
<!--This is a comment-->
<?php print ' hi! This is PHP version '. phpversion ();?>
</para>
</section>
</chapter>
The following documents will be called by the Xmltest.xml file: Xmltest2.xml
<?xml version= "1.0"?>
<! DOCTYPE Foo [
<! ENTITY testent "Test ENTITY" >
]>
<foo>
<element attrib= "Value"/>
&testEnt;
<?php print "This are some more PHP code being executed."; ?>
</foo>