Fix stack trace mangling bug! :D

This commit is contained in:
Starbeamrainbowlabs 2018-03-05 22:42:48 +00:00
parent 184097b324
commit 9bd4845ad9
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
3 changed files with 60 additions and 22 deletions

View file

@ -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");
} }

View 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;
}
}

View file

@ -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();
} }