Commit bbfe372c authored by sebastian's avatar sebastian

ZP-608 #comment moved StringStreamWrapper to lib/utils, in case of issues...

ZP-608 #comment moved StringStreamWrapper to lib/utils, in case of issues during wbxml decoding, include the wbxml data in the error log for easier debugging, added stand alone wbxml decoding tool

git-svn-id: https://z-push.org/svn/z-push/trunk@1948 b7dd7b3b-3a3c-0410-9da9-bee62a6cc5b5
parent d81adfa4
......@@ -593,7 +593,6 @@ class BackendIMAP extends BackendDiff {
unset($mobj);
unset($mail);
include_once('include/stringstreamwrapper.php');
$attachment = new SyncItemOperationsAttachment();
/* BEGIN fmbiete's contribution r1528, ZP-320 */
$attachment->data = StringStreamWrapper::Open($mparts[$part]->body);
......
......@@ -140,7 +140,6 @@ class BackendMaildir extends BackendDiff {
$message = Mail_mimeDecode::decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'input' => $rfc822, 'crlf' => "\n", 'charset' => 'utf-8'));
include_once('include/stringstreamwrapper.php');
$attachment = new SyncItemOperationsAttachment();
$attachment->data = StringStreamWrapper::Open($message->parts[$part]->body);
if (isset($message->parts[$part]->ctype_primary) && isset($message->parts[$part]->ctype_secondary))
......
......@@ -52,6 +52,7 @@ include_once('lib/exceptions/exceptions.php');
include_once('lib/utils/utils.php');
include_once('lib/utils/compat.php');
include_once('lib/utils/timezoneutil.php');
include_once('lib/utils/stringstreamwrapper.php');
include_once('lib/core/zpushdefs.php');
include_once('lib/core/stateobject.php');
include_once('lib/core/interprocessdata.php');
......@@ -186,8 +187,7 @@ include_once('version.php');
}
RequestProcessor::Initialize();
if(!RequestProcessor::HandleRequest())
throw new WBXMLException(ZLog::GetWBXMLDebugInfo());
RequestProcessor::HandleRequest();
// eventually the RequestProcessor wants to send other headers to the mobile
foreach (RequestProcessor::GetSpecialHeaders() as $header)
......@@ -265,7 +265,7 @@ include_once('version.php');
// This could be a WBXML problem.. try to get the complete request
else if ($ex instanceof WBXMLException) {
ZLog::Write(LOGLEVEL_FATAL, "Request could not be processed correctly due to a WBXMLException. Please report this.");
ZLog::Write(LOGLEVEL_FATAL, "Request could not be processed correctly due to a WBXMLException. Please report this including WBXML debug data logged. Be aware that the debug data could contain confidential information.");
}
// Try to output some kind of error information. This is only possible if
......
......@@ -55,7 +55,7 @@ class ZPushException extends Exception {
if (!$logLevel)
$logLevel = $this->defaultLogLevel;
ZLog::Write($logLevel, get_class($this) .': '. $message . ' - code: '.$code);
ZLog::Write($logLevel, get_class($this) .': '. $message . ' - code: '.$code, false);
parent::__construct($message, (int) $code);
}
......
......@@ -127,8 +127,17 @@ abstract class RequestProcessor {
static public function HandleRequest() {
$handler = ZPush::GetRequestHandlerForCommand(Request::GetCommandCode());
// TODO handle WBXML exceptions here and print stack
return $handler->Handle(Request::GetCommandCode());
// if there is an error decoding wbxml, consume remaining data and include it in the WBXMLException
if (!$handler->Handle(Request::GetCommandCode())) {
self::$decoder->readRemainingData();
$wbxmlLog = self::$decoder->getWBXMLLog();
throw new WBXMLException("Debug data: " . $wbxmlLog);
}
// also log WBXML in happy case
if (self::$decoder && @constant('WBXML_DEBUG') === true) {
ZLog::Write(LOGLEVEL_WBXML, "WBXML-IN : ". self::$decoder->getWBXMLLog(), false);
}
}
/**
......
......@@ -7,7 +7,7 @@
*
* Created : 24.11.2011
*
* Copyright 2007 - 2013 Zarafa Deutschland GmbH
* Copyright 2007 - 2013, 2015 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
......@@ -92,6 +92,39 @@ class StringStreamWrapper {
return $data;
}
/**
* Writes data to the stream.
*
* @param string $data
* @return int
*/
public function stream_write($data){
$l = strlen($data);
$this->stringstream = substr($this->stringstream, 0, $this->position) . $data . substr($this->stringstream, $this->position += $l);
$this->stringlength = strlen($this->stringstream);
return $l;
}
/**
* Stream "seek" functionality.
*
* @param int $offset
* @param int $whence
* @return boolean
*/
public function stream_seek($offset, $whence = SEEK_SET) {
if ($whence == SEEK_CUR) {
$this->position += $offset;
}
else if ($whence == SEEK_END) {
$this->position = $this->stringlength + $offset;
}
else {
$this->position = $offset;
}
return true;
}
/**
* Returns the current position on stream
*
......
......@@ -44,6 +44,7 @@
class WBXMLDecoder extends WBXMLDefs {
private $in;
private $inLog;
private $version;
private $publicid;
......@@ -75,6 +76,7 @@ class WBXMLDecoder extends WBXMLDefs {
if (!defined('WBXML_DEBUG')) define('WBXML_DEBUG', false);
$this->in = $input;
$this->inLog = StringStreamWrapper::Open("");
$this->readVersion();
if (isset($this->version) && $this->version != self::VERSION) {
......@@ -240,7 +242,30 @@ class WBXMLDecoder extends WBXMLDefs {
return $this->isWBXML;
}
/**
* Reads the remaning data from the input stream
*
* @access public
* @return void
*/
public function readRemainingData() {
ZLog::Write(LOGLEVEL_DEBUG, "WBXMLDecoder->readRemainingData() reading remaining data from input stream");
while($this->getElement());
}
/**
* Returns the WBXML data read from the stream
*
* @access public
* @return string - base64 encoded wbxml
*/
public function getWBXMLLog() {
$out = "";
if ($this->inLog) {
$out = base64_encode(stream_get_contents($this->inLog, -1,0));
}
return $out;
}
/**----------------------------------------------------------------------------------------------------------
* Private WBXMLDecoder stuff
......@@ -568,8 +593,10 @@ class WBXMLDecoder extends WBXMLDefs {
// Stream ends prematurely on instable connections and big mails
if ($data === false || feof($this->in))
throw new HTTPReturnCodeException(sprintf("WBXMLDecoder->getOpaque() connection unavailable while trying to read %d bytes from stream. Aborting after %d bytes read.", $len, strlen($d)), HTTP_CODE_500, null, LOGLEVEL_WARN);
else
else {
$d .= $data;
fwrite($this->inLog, $data);
}
}
if (strlen($d) >= $len) break;
}
......@@ -584,8 +611,10 @@ class WBXMLDecoder extends WBXMLDefs {
*/
private function getByte() {
$ch = fread($this->in, 1);
if(strlen($ch) > 0)
if(strlen($ch) > 0) {
fwrite($this->inLog, $ch);
return ord($ch);
}
else
return;
}
......@@ -623,8 +652,10 @@ class WBXMLDecoder extends WBXMLDefs {
$stringtable = "";
$length = $this->getMBUInt();
if($length > 0)
if($length > 0) {
$stringtable = fread($this->in, $length);
fwrite($this->inLog, $stringtable);
}
return $stringtable;
}
......
......@@ -45,6 +45,7 @@
class WBXMLEncoder extends WBXMLDefs {
private $_dtd;
private $_out;
private $_outLog;
private $_tagcp;
private $_attrcp;
......@@ -67,6 +68,7 @@ class WBXMLEncoder extends WBXMLDefs {
if (!defined('WBXML_DEBUG')) define('WBXML_DEBUG', false);
$this->_out = $output;
$this->_outLog = StringStreamWrapper::Open("");
$this->_tagcp = 0;
$this->_attrcp = 0;
......@@ -157,6 +159,8 @@ class WBXMLEncoder extends WBXMLDefs {
if(count($this->_stack) == 0 && $this->multipart == true) {
$this->processMultipart();
}
if(count($this->_stack) == 0)
$this->writeLog();
}
}
......@@ -297,6 +301,7 @@ class WBXMLEncoder extends WBXMLDefs {
*/
private function outByte($byte) {
fwrite($this->_out, chr($byte));
fwrite($this->_outLog, chr($byte));
}
/**
......@@ -331,6 +336,8 @@ class WBXMLEncoder extends WBXMLDefs {
private function outTermStr($content) {
fwrite($this->_out, $content);
fwrite($this->_out, chr(0));
fwrite($this->_outLog, $content);
fwrite($this->_outLog, chr(0));
}
/**
......@@ -496,12 +503,27 @@ class WBXMLEncoder extends WBXMLDefs {
fwrite($this->_out, $data);
fwrite($this->_out, $buffer);
fwrite($this->_outLog, $data);
fwrite($this->_outLog, $buffer);
foreach($this->bodyparts as $bp) {
while (!feof($bp)) {
fwrite($this->_out, fread($bp, 4096));
$out = fread($bp, 4096);
fwrite($this->_out, $out);
fwrite($this->_outLog, $out);
}
}
}
/**
* Writes the sent WBXML data to the log
*
* @access private
* @return void
*/
private function writeLog() {
ZLog::Write(LOGLEVEL_WBXML, "WBXML-OUT: ". base64_encode(stream_get_contents($this->_outLog, -1,0)), false);
}
}
?>
\ No newline at end of file
<?php
/***********************************************
* File : printwbxml.php
* Project : Z-Push
* Descr : decodes and prints wbxml as base64 to stdout
*
* Created : 18.05.2015
*
* Copyright 2015 Zarafa Deutschland GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation with the following additional
* term according to sec. 7:
*
* According to sec. 7 of the GNU Affero General Public License, version 3,
* the terms of the AGPL are supplemented with the following terms:
*
* "Zarafa" is a registered trademark of Zarafa B.V.
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
* The licensing of the Program under the AGPL does not imply a trademark license.
* Therefore any rights, title and interest in our trademarks remain entirely with us.
*
* However, if you propagate an unmodified version of the Program you are
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
* Furthermore you may use our trademarks where it is necessary to indicate
* the intended purpose of a product or service provided you use it in accordance
* with honest practices in industrial or commercial matters.
* If you want to propagate modified versions of the Program under the name "Z-Push",
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Consult LICENSE file for details
************************************************/
if (count($argv) < 2) {
die("\tUsage: printwbmxl.php WBXML-INPUT-HERE\n\n");
}
$wbxml64 = $argv[1];
// include the stuff we need
include_once('../../src/lib/utils/stringstreamwrapper.php');
include_once('../../src/lib/wbxml/wbxmldefs.php');
include_once('../../src/lib/wbxml/wbxmldecoder.php');
include_once('../../src/lib/wbxml/wbxmlencoder.php');
// minimal definitions & log to stdout overwrite
define('WBXML_DEBUG', true);
define("LOGLEVEL_WBXML", "wbxml");
define("LOGLEVEL_DEBUG", "debug");
class ZLog {
static public function Write($level, $msg, $truncate = false) {
// we only care about the wbxml
if ($level == "wbxml") {
if (substr($msg,0,1) == "I") {
echo substr($msg,1) . "\n";
}
else {
echo $msg . "\n";
}
}
}
}
// setup
$wxbml = StringStreamWrapper::Open($wbxml64);
$base64filter = stream_filter_append($wxbml, 'convert.base64-decode');
$decoder = new WBXMLDecoder($wxbml);
if (! $decoder->IsWBXML()) {
die("input is not WBXML as base64\n\n");
}
echo "\n";
// read everything and log it
$decoder->readRemainingData();
echo "\n";
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment