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 { ...@@ -593,7 +593,6 @@ class BackendIMAP extends BackendDiff {
unset($mobj); unset($mobj);
unset($mail); unset($mail);
include_once('include/stringstreamwrapper.php');
$attachment = new SyncItemOperationsAttachment(); $attachment = new SyncItemOperationsAttachment();
/* BEGIN fmbiete's contribution r1528, ZP-320 */ /* BEGIN fmbiete's contribution r1528, ZP-320 */
$attachment->data = StringStreamWrapper::Open($mparts[$part]->body); $attachment->data = StringStreamWrapper::Open($mparts[$part]->body);
......
...@@ -140,7 +140,6 @@ class BackendMaildir extends BackendDiff { ...@@ -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')); $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 = new SyncItemOperationsAttachment();
$attachment->data = StringStreamWrapper::Open($message->parts[$part]->body); $attachment->data = StringStreamWrapper::Open($message->parts[$part]->body);
if (isset($message->parts[$part]->ctype_primary) && isset($message->parts[$part]->ctype_secondary)) if (isset($message->parts[$part]->ctype_primary) && isset($message->parts[$part]->ctype_secondary))
......
...@@ -52,6 +52,7 @@ include_once('lib/exceptions/exceptions.php'); ...@@ -52,6 +52,7 @@ include_once('lib/exceptions/exceptions.php');
include_once('lib/utils/utils.php'); include_once('lib/utils/utils.php');
include_once('lib/utils/compat.php'); include_once('lib/utils/compat.php');
include_once('lib/utils/timezoneutil.php'); include_once('lib/utils/timezoneutil.php');
include_once('lib/utils/stringstreamwrapper.php');
include_once('lib/core/zpushdefs.php'); include_once('lib/core/zpushdefs.php');
include_once('lib/core/stateobject.php'); include_once('lib/core/stateobject.php');
include_once('lib/core/interprocessdata.php'); include_once('lib/core/interprocessdata.php');
...@@ -186,8 +187,7 @@ include_once('version.php'); ...@@ -186,8 +187,7 @@ include_once('version.php');
} }
RequestProcessor::Initialize(); RequestProcessor::Initialize();
if(!RequestProcessor::HandleRequest()) RequestProcessor::HandleRequest();
throw new WBXMLException(ZLog::GetWBXMLDebugInfo());
// eventually the RequestProcessor wants to send other headers to the mobile // eventually the RequestProcessor wants to send other headers to the mobile
foreach (RequestProcessor::GetSpecialHeaders() as $header) foreach (RequestProcessor::GetSpecialHeaders() as $header)
...@@ -265,7 +265,7 @@ include_once('version.php'); ...@@ -265,7 +265,7 @@ include_once('version.php');
// This could be a WBXML problem.. try to get the complete request // This could be a WBXML problem.. try to get the complete request
else if ($ex instanceof WBXMLException) { 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 // Try to output some kind of error information. This is only possible if
......
...@@ -55,7 +55,7 @@ class ZPushException extends Exception { ...@@ -55,7 +55,7 @@ class ZPushException extends Exception {
if (!$logLevel) if (!$logLevel)
$logLevel = $this->defaultLogLevel; $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); parent::__construct($message, (int) $code);
} }
......
...@@ -127,8 +127,17 @@ abstract class RequestProcessor { ...@@ -127,8 +127,17 @@ abstract class RequestProcessor {
static public function HandleRequest() { static public function HandleRequest() {
$handler = ZPush::GetRequestHandlerForCommand(Request::GetCommandCode()); $handler = ZPush::GetRequestHandlerForCommand(Request::GetCommandCode());
// TODO handle WBXML exceptions here and print stack // if there is an error decoding wbxml, consume remaining data and include it in the WBXMLException
return $handler->Handle(Request::GetCommandCode()); 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 @@ ...@@ -7,7 +7,7 @@
* *
* Created : 24.11.2011 * 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 * 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, * it under the terms of the GNU Affero General Public License, version 3,
...@@ -92,6 +92,39 @@ class StringStreamWrapper { ...@@ -92,6 +92,39 @@ class StringStreamWrapper {
return $data; 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 * Returns the current position on stream
* *
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
class WBXMLDecoder extends WBXMLDefs { class WBXMLDecoder extends WBXMLDefs {
private $in; private $in;
private $inLog;
private $version; private $version;
private $publicid; private $publicid;
...@@ -75,6 +76,7 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -75,6 +76,7 @@ class WBXMLDecoder extends WBXMLDefs {
if (!defined('WBXML_DEBUG')) define('WBXML_DEBUG', false); if (!defined('WBXML_DEBUG')) define('WBXML_DEBUG', false);
$this->in = $input; $this->in = $input;
$this->inLog = StringStreamWrapper::Open("");
$this->readVersion(); $this->readVersion();
if (isset($this->version) && $this->version != self::VERSION) { if (isset($this->version) && $this->version != self::VERSION) {
...@@ -240,7 +242,30 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -240,7 +242,30 @@ class WBXMLDecoder extends WBXMLDefs {
return $this->isWBXML; 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 * Private WBXMLDecoder stuff
...@@ -568,8 +593,10 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -568,8 +593,10 @@ class WBXMLDecoder extends WBXMLDefs {
// Stream ends prematurely on instable connections and big mails // Stream ends prematurely on instable connections and big mails
if ($data === false || feof($this->in)) 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); 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; $d .= $data;
fwrite($this->inLog, $data);
}
} }
if (strlen($d) >= $len) break; if (strlen($d) >= $len) break;
} }
...@@ -584,8 +611,10 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -584,8 +611,10 @@ class WBXMLDecoder extends WBXMLDefs {
*/ */
private function getByte() { private function getByte() {
$ch = fread($this->in, 1); $ch = fread($this->in, 1);
if(strlen($ch) > 0) if(strlen($ch) > 0) {
fwrite($this->inLog, $ch);
return ord($ch); return ord($ch);
}
else else
return; return;
} }
...@@ -623,8 +652,10 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -623,8 +652,10 @@ class WBXMLDecoder extends WBXMLDefs {
$stringtable = ""; $stringtable = "";
$length = $this->getMBUInt(); $length = $this->getMBUInt();
if($length > 0) if($length > 0) {
$stringtable = fread($this->in, $length); $stringtable = fread($this->in, $length);
fwrite($this->inLog, $stringtable);
}
return $stringtable; return $stringtable;
} }
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
class WBXMLEncoder extends WBXMLDefs { class WBXMLEncoder extends WBXMLDefs {
private $_dtd; private $_dtd;
private $_out; private $_out;
private $_outLog;
private $_tagcp; private $_tagcp;
private $_attrcp; private $_attrcp;
...@@ -67,6 +68,7 @@ class WBXMLEncoder extends WBXMLDefs { ...@@ -67,6 +68,7 @@ class WBXMLEncoder extends WBXMLDefs {
if (!defined('WBXML_DEBUG')) define('WBXML_DEBUG', false); if (!defined('WBXML_DEBUG')) define('WBXML_DEBUG', false);
$this->_out = $output; $this->_out = $output;
$this->_outLog = StringStreamWrapper::Open("");
$this->_tagcp = 0; $this->_tagcp = 0;
$this->_attrcp = 0; $this->_attrcp = 0;
...@@ -157,6 +159,8 @@ class WBXMLEncoder extends WBXMLDefs { ...@@ -157,6 +159,8 @@ class WBXMLEncoder extends WBXMLDefs {
if(count($this->_stack) == 0 && $this->multipart == true) { if(count($this->_stack) == 0 && $this->multipart == true) {
$this->processMultipart(); $this->processMultipart();
} }
if(count($this->_stack) == 0)
$this->writeLog();
} }
} }
...@@ -297,6 +301,7 @@ class WBXMLEncoder extends WBXMLDefs { ...@@ -297,6 +301,7 @@ class WBXMLEncoder extends WBXMLDefs {
*/ */
private function outByte($byte) { private function outByte($byte) {
fwrite($this->_out, chr($byte)); fwrite($this->_out, chr($byte));
fwrite($this->_outLog, chr($byte));
} }
/** /**
...@@ -331,6 +336,8 @@ class WBXMLEncoder extends WBXMLDefs { ...@@ -331,6 +336,8 @@ class WBXMLEncoder extends WBXMLDefs {
private function outTermStr($content) { private function outTermStr($content) {
fwrite($this->_out, $content); fwrite($this->_out, $content);
fwrite($this->_out, chr(0)); fwrite($this->_out, chr(0));
fwrite($this->_outLog, $content);
fwrite($this->_outLog, chr(0));
} }
/** /**
...@@ -496,11 +503,26 @@ class WBXMLEncoder extends WBXMLDefs { ...@@ -496,11 +503,26 @@ class WBXMLEncoder extends WBXMLDefs {
fwrite($this->_out, $data); fwrite($this->_out, $data);
fwrite($this->_out, $buffer); fwrite($this->_out, $buffer);
fwrite($this->_outLog, $data);
fwrite($this->_outLog, $buffer);
foreach($this->bodyparts as $bp) { foreach($this->bodyparts as $bp) {
while (!feof($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);
} }
} }
......
<?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