Fix stack trace mangling bug! :D
This commit is contained in:
parent
184097b324
commit
9bd4845ad9
3 changed files with 60 additions and 22 deletions
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Sandpiper\Actions;
|
namespace Sandpiper\Actions;
|
||||||
|
|
||||||
|
use \DOMDocument; use \DOMElement; use \DOMCDATASection;
|
||||||
|
|
||||||
use \Yosymfony\Toml\Toml;
|
use \Yosymfony\Toml\Toml;
|
||||||
|
|
||||||
use \SBRL\Utilities\SimpleXmlWriter;
|
use \SBRL\Utilities\SimpleXmlWriter;
|
||||||
|
@ -11,7 +13,7 @@ class Report extends \Sandpiper\AbstractAction
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
libxml_disable_entity_loader(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle() {
|
public function handle() {
|
||||||
|
@ -30,7 +32,6 @@ class Report extends \Sandpiper\AbstractAction
|
||||||
|
|
||||||
$place = null;
|
$place = null;
|
||||||
foreach($settings->get("places") as $current_place) {
|
foreach($settings->get("places") as $current_place) {
|
||||||
var_dump($current_place);
|
|
||||||
if($current_place["key"] == $this->param_get("place_id", null)) {
|
if($current_place["key"] == $this->param_get("place_id", null)) {
|
||||||
$place = $current_place;
|
$place = $current_place;
|
||||||
break;
|
break;
|
||||||
|
@ -44,7 +45,7 @@ class Report extends \Sandpiper\AbstractAction
|
||||||
$new_report->version = escape4xml($this->param_get("version", "?"));
|
$new_report->version = escape4xml($this->param_get("version", "?"));
|
||||||
$new_report->summary = escape4xml($this->param_get("summary", "(Unknown error)"));
|
$new_report->summary = escape4xml($this->param_get("summary", "(Unknown error)"));
|
||||||
$new_report->details = escape4xml($this->param_get("details", ""));
|
$new_report->details = escape4xml($this->param_get("details", ""));
|
||||||
$new_report->stack_trace = escape4xml($this->get_post_body());
|
$new_report->stack_trace = $this->get_post_body();
|
||||||
|
|
||||||
$report_dir = ROOT_DIR . "/{$settings->get("data_dir")}/places/" . slugify($place["name"]);
|
$report_dir = ROOT_DIR . "/{$settings->get("data_dir")}/places/" . slugify($place["name"]);
|
||||||
$report_filename = "$report_dir/" . slugify($new_report->summary) . ".xml";
|
$report_filename = "$report_dir/" . slugify($new_report->summary) . ".xml";
|
||||||
|
@ -67,19 +68,27 @@ class Report extends \Sandpiper\AbstractAction
|
||||||
$writer->close();
|
$writer->close();
|
||||||
file_put_contents($report_filename, $writer->render());
|
file_put_contents($report_filename, $writer->render());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We have to use a DOMDocument here because SimpleXML mangled the
|
||||||
|
// whitespace in the stack traces
|
||||||
|
$report_xml = new DOMDocument("1.0", "UTF-8");
|
||||||
|
$report_xml->preserveWhiteSpace = false;
|
||||||
|
$report_xml->formatOutput = true;
|
||||||
|
if(!$report_xml->loadXML(file_get_contents($report_filename), LIBXML_NONET))
|
||||||
|
exit("Error: Invalid XML generated when creating a new report file.\n");
|
||||||
|
|
||||||
|
$report_node = new DOMElement("report");
|
||||||
|
$report_xml->getElementsByTagName("reports")->item(0)->appendChild($report_node);
|
||||||
|
|
||||||
|
$report_node->appendChild(new DOMElement("timestamp", date(DATE_ATOM)));
|
||||||
|
$report_node->appendChild(new DOMElement("version", $new_report->version));
|
||||||
|
$report_node->appendChild(new DOMElement("details", $new_report->details));
|
||||||
|
$stack_trace_node = new DOMElement("stack_trace");
|
||||||
|
$report_node->appendChild($stack_trace_node);
|
||||||
|
$stack_trace_node->appendChild($report_xml->createCDATASection($new_report->stack_trace));
|
||||||
|
|
||||||
$report_xml = simplexml_load_file($report_filename);
|
// NOTE: When uploading with curl to test this, make sure to use --data-binary and not simply -d, as this mangles the newline characters.
|
||||||
|
file_put_contents($report_filename, $report_xml->saveXML());
|
||||||
if($report_xml === false)
|
|
||||||
exit("Error: invalid XML generated when creating a new report file.\n");
|
|
||||||
|
|
||||||
$report_node = $report_xml->reports->addChild("report");
|
|
||||||
$report_node->addChild("timestamp", date(DATE_ATOM));
|
|
||||||
$report_node->addChild("version", $new_report->version);
|
|
||||||
$report_node->addChild("details", $new_report->details);
|
|
||||||
$report_node->addChild("stack_trace", $new_report->stack_trace);
|
|
||||||
|
|
||||||
file_put_contents($report_filename, $report_xml->asXML());
|
|
||||||
|
|
||||||
// Update the place index
|
// Update the place index
|
||||||
$place_index_filename = "$report_dir/index.xml";
|
$place_index_filename = "$report_dir/index.xml";
|
||||||
|
@ -88,13 +97,13 @@ class Report extends \Sandpiper\AbstractAction
|
||||||
$writer = new SimpleXmlWriter();
|
$writer = new SimpleXmlWriter();
|
||||||
$writer->prettyprint = true;
|
$writer->prettyprint = true;
|
||||||
|
|
||||||
$writer->add_xslt(ROOT_DIR . "/theme/place_index.xslt");
|
$writer->add_xslt("/theme/place_index.xslt");
|
||||||
$writer->open("errors");
|
$writer->open("errors");
|
||||||
$writer->close();
|
$writer->close();
|
||||||
file_put_contents($place_index_filename, $writer->render());
|
file_put_contents($place_index_filename, $writer->render());
|
||||||
}
|
}
|
||||||
$index_xml = simplexml_load_file($place_index_filename);
|
$index_xml = simplexml_load_file($place_index_filename);
|
||||||
|
|
||||||
$index_entry = null;
|
$index_entry = null;
|
||||||
foreach($index_xml as $entry) {
|
foreach($index_xml as $entry) {
|
||||||
if($entry->summary->__toString() != $new_report->summary)
|
if($entry->summary->__toString() != $new_report->summary)
|
||||||
|
@ -112,8 +121,10 @@ class Report extends \Sandpiper\AbstractAction
|
||||||
|
|
||||||
$index_entry->report_count = intval($index_entry->report_count) + 1;
|
$index_entry->report_count = intval($index_entry->report_count) + 1;
|
||||||
|
|
||||||
file_put_contents($place_index_filename, $index_xml->asXML());
|
// This is fine because we don't have to worry about the whitespace in the
|
||||||
|
// stack traces here
|
||||||
|
file_put_contents($place_index_filename, simplexml_asxml_pretty($index_xml));
|
||||||
|
|
||||||
http_response_code(200);
|
http_response_code(200);
|
||||||
exit("Report submitted successfully!\n");
|
exit("Report submitted successfully!\n");
|
||||||
}
|
}
|
||||||
|
|
26
utilities/SimpleXmlElementExtended.php
Normal file
26
utilities/SimpleXmlElementExtended.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace External\Utilities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* From https://stackoverflow.com/a/20511976/1460422
|
||||||
|
*/
|
||||||
|
class SimpleXMLElementExtended extends SimpleXMLElement {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a child with $value inside CDATA
|
||||||
|
* @param string $name
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function addChildWithCDATA($name, $value = NULL) {
|
||||||
|
$new_child = $this->addChild($name);
|
||||||
|
|
||||||
|
if ($new_child !== NULL) {
|
||||||
|
$node = dom_import_simplexml($new_child);
|
||||||
|
$no = $node->ownerDocument;
|
||||||
|
$node->appendChild($no->createCDATASection($value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $new_child;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,6 @@
|
||||||
* @return string The slugified string.
|
* @return string The slugified string.
|
||||||
*/
|
*/
|
||||||
function slugify($string, $maxlength = 50) {
|
function slugify($string, $maxlength = 50) {
|
||||||
var_dump($string);
|
|
||||||
return substr(preg_replace([
|
return substr(preg_replace([
|
||||||
'/\s+/',
|
'/\s+/',
|
||||||
'/[^a-z0-9\-_]/'
|
'/[^a-z0-9\-_]/'
|
||||||
|
@ -35,8 +34,10 @@ function escape4xml($string) {
|
||||||
* @return string The pretty-printed XML representation of the provided SimpleXML node.
|
* @return string The pretty-printed XML representation of the provided SimpleXML node.
|
||||||
*/
|
*/
|
||||||
function simplexml_asxml_pretty($simplexml_node) {
|
function simplexml_asxml_pretty($simplexml_node) {
|
||||||
$dom = dom_import_simplexml($simplexml_node);
|
libxml_disable_entity_loader(false);
|
||||||
$dom->preserveWhitespace = false;
|
$dom = new DomDocument;
|
||||||
|
$dom->preserveWhiteSpace = false;
|
||||||
$dom->formatOutput = true;
|
$dom->formatOutput = true;
|
||||||
|
$dom->loadXML($simplexml_node->asXML(), LIBXML_NONET);
|
||||||
return $dom->saveXML();
|
return $dom->saveXML();
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue