Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 16 additions & 24 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true">

<testsuites>
<testsuite name="Project Test Suite">
<directory>test</directory>
</testsuite>
</testsuites>

<filter>
<whitelist>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>

<php>
<env name="APP_ENV" value="testing"/>
</php>
</phpunit>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false" displayDetailsOnTestsThatTriggerWarnings="true">
<coverage/>
<testsuites>
<testsuite name="Project Test Suite">
<directory>test</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_ENV" value="testing"/>
</php>
<source>
<include>
<directory suffix=".php">src/</directory>
</include>
</source>
</phpunit>
28 changes: 15 additions & 13 deletions src/TNEFDecoder/TNEFAttachment.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,17 @@ function getBodyElements()
return $this->body;
}

function decodeTnef(&$buffer)
function decodeTnef($data)
{
$buffer = new TNEFBuffer($data);

$tnef_signature = tnef_geti32($buffer);
if ($tnef_signature == TNEF_SIGNATURE) {
$tnef_key = tnef_geti16($buffer);
if ($this->debug)
tnef_log(sprintf("Signature: 0x%08x\nKey: 0x%04x\n", $tnef_signature, $tnef_key));

while (strlen($buffer) > 0) {
while ($buffer->getRemainingBytes() > 0) {
$lvl_type = tnef_geti8($buffer);

switch ($lvl_type) {
Expand All @@ -133,7 +135,7 @@ function decodeTnef(&$buffer)

default:
if ($this->debug) {
$len = strlen($buffer);
$len = $buffer->getRemainingBytes();
if ($len > 0)
tnef_log("Invalid file format! Unknown Level $lvl_type. Rest=$len");
}
Expand All @@ -155,7 +157,7 @@ function decodeTnef(&$buffer)
$this->files[$i]->setMessageCodePage($code_page);
}

function tnef_decode_attribute(&$buffer)
function tnef_decode_attribute(TNEFBuffer $buffer)
{
$attribute = tnef_geti32($buffer); // attribute if
$length = tnef_geti32($buffer); // length
Expand All @@ -180,13 +182,13 @@ function tnef_decode_attribute(&$buffer)
case TNEF_AMAPIATTRS:
if ($this->debug)
tnef_log("mapi attrs");
$this->extract_mapi_attrs($value);
$this->extract_mapi_attrs(new TNEFBuffer($value));
break;

case TNEF_AMAPIPROPS:
if ($this->debug)
tnef_log("mapi props");
$this->extract_mapi_attrs($value);
$this->extract_mapi_attrs(new TNEFBuffer($value));
break;

case TNEF_AMCLASS:
Expand All @@ -208,14 +210,14 @@ function tnef_decode_attribute(&$buffer)
}
}

function extract_mapi_attrs(&$buffer)
function extract_mapi_attrs(TNEFBuffer $buffer)
{

$number = tnef_geti32($buffer); // number of attributes
$props = 0;
$ended = 0;

while ((strlen($buffer) > 0) && ($props < $number) && (!$ended))
while (($buffer->getRemainingBytes() > 0) && ($props < $number) && (!$ended))
{
$props++;
$value = '';
Expand All @@ -225,7 +227,7 @@ function extract_mapi_attrs(&$buffer)
$num_multivalues = 1;
$attr_type = tnef_geti16($buffer);
$attr_name = tnef_geti16($buffer);

if (($attr_type & TNEF_MAPI_MV_FLAG) != 0)
{
if ($this->debug)
Expand Down Expand Up @@ -346,7 +348,7 @@ function extract_mapi_attrs(&$buffer)
case TNEF_MAPI_ATTACH_DATA:
if ($this->debug)
tnef_log("MAPI Found nested attachment. Processing new one.");
tnef_getx(16, $value); // skip the next 16 bytes (unknown data)
tnef_getx(16, $buffer); // skip the next 16 bytes (unknown data)
$att = new TNEFAttachment($this->debug, $this->validateChecksum);
$att->decodeTnef($value);
$this->attachments[] = $att;
Expand Down Expand Up @@ -378,14 +380,14 @@ function extract_mapi_attrs(&$buffer)
}
if (($this->debug) && ($ended))
{
$len = strlen($buffer);
$len = $buffer->getRemainingBytes();
for ($cnt = 0; $cnt < $len; $cnt++)
{
$ord = ord($buffer[$cnt]);
$ord = tnef_geti8($buffer);
if ($ord == 0)
$char = "";
else
$char = $buffer[$cnt];
$char = chr($ord);
tnef_log(sprintf("Char Nr. %6d = 0x%02x = '%s'", $cnt, $ord, $char));
}
}
Expand Down
46 changes: 46 additions & 0 deletions src/TNEFDecoder/TNEFBuffer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php namespace TNEFDecoder;

/**
* SquirrelMail TNEF Decoder Plugin
*
* Copyright (c) 2010- Paul Lesniewski <paul@squirrelmail.org>
* Copyright (c) 2003 Bernd Wiegmann <bernd@wib-software.de>
* Copyright (c) 2002 Graham Norburys <gnorbury@bondcar.com>
*
* Licensed under the GNU GPL. For full terms see the file COPYING.
*
* @package plugins
* @subpackage tnef_decoder
*
*/

class TNEFBuffer
{
private string $data;
private int $offset;

function __construct(string $data)
{
$this->data = $data;
$this->offset = 0;
}

function getBytes(int $numBytes): ?string
{
if ($this->getRemainingBytes() < $numBytes) {
$this->offset = strlen($this->data);
return null;
}

$this->offset += $numBytes;
return substr($this->data, $this->offset - $numBytes, $numBytes);
}

function getRemainingBytes(): int
{
return strlen($this->data) - $this->offset;
}
}



2 changes: 1 addition & 1 deletion src/TNEFDecoder/TNEFDate.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class TNEFDate
var $minute;
var $second;

function setTnefBuffer($buffer)
function setTnefBuffer(TNEFBuffer $buffer)
{
$this->year = tnef_geti16($buffer);
$this->month = tnef_geti16($buffer);
Expand Down
16 changes: 7 additions & 9 deletions src/TNEFDecoder/TNEFFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,20 @@ function receiveTnefAttribute($attribute, $value, $length)
// filename
//
case TNEF_AFILENAME:

// strip path
//
if (($pos = strrpos($value, '/')) !== FALSE)
$this->name = substr($value, $pos + 1);
else
$this->name = $value;

// Strip trailing null bytes if present
$this->name = trim($this->name);
break;

// code page
//
case TNEF_AOEMCODEPAGE:
$this->code_page = tnef_geti16($value);
$this->code_page = tnef_geti16(new TNEFBuffer($value));
break;

// the attachment itself
Expand All @@ -67,11 +67,11 @@ function receiveTnefAttribute($attribute, $value, $length)

case TNEF_AATTACHCREATEDATE:
$this->created = new TNEFDate();
$this->created->setTnefBuffer($value);
$this->created->setTnefBuffer(new TNEFBuffer($value));

case TNEF_AATTACHMODDATE:
$this->modified = new TNEFDate();
$this->modified->setTnefBuffer($value);
$this->modified->setTnefBuffer(new TNEFBuffer($value));
break;
}
}
Expand All @@ -84,7 +84,6 @@ function receiveMapiAttribute($attr_type, $attr_name, $value, $length, $is_unico
// used in preference to AFILENAME value
//
case TNEF_MAPI_ATTACH_LONG_FILENAME:

// strip path
//
if (($pos = strrpos($value, '/')) !== FALSE)
Expand All @@ -93,17 +92,16 @@ function receiveMapiAttribute($attr_type, $attr_name, $value, $length, $is_unico
$this->name = $value;

if ($is_unicode) $this->name_is_unicode = TRUE;

break;

// Is this ever set, and what is format?
//
case TNEF_MAPI_ATTACH_MIME_TAG:
$type0 = $type1 = '';
$mime_type = explode('/', $value, 2);
if (!empty($mime_type[0]))
if (!empty($mime_type[0]))
$type0 = $mime_type[0];
if (!empty($mime_type[1]))
if (!empty($mime_type[1]))
$type1 = $mime_type[1];
$this->type = "$type0/$type1";
if ($is_unicode) {
Expand Down
2 changes: 1 addition & 1 deletion src/TNEFDecoder/TNEFFileBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class TNEFFileBase
var $created;
var $modified;
var $debug;

function __construct($debug)
{
$this->name = 'Untitled';
Expand Down
18 changes: 10 additions & 8 deletions src/TNEFDecoder/TNEFFileRTF.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ class TNEFFileRTF extends TNEFFileBase
const MAX_DICT_SIZE = 4096;
const INIT_DICT_SIZE = 207;

function __construct($debug, $buffer)
function __construct($debug, $data)
{
parent::__construct($debug);
$this->type = "application/rtf";
$this->name = "EmbeddedRTF.rtf";
$this->debug = $debug;

$this->decode_crtf($buffer);
$this->decode_crtf(new TNEFBuffer($data));
}

function getSize()
{
return $this->size;
}

function decode_crtf(&$buffer)
function decode_crtf(TNEFBuffer $buffer)
{
$size_compressed = tnef_geti32($buffer);
$this->size = tnef_geti32($buffer);
Expand All @@ -61,8 +61,10 @@ function decode_crtf(&$buffer)
}
}

function uncompress(&$data)
function uncompress(TNEFBuffer $buffer)
{
$data = tnef_getx($buffer->getRemainingBytes(), $buffer);

$preload = "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscript \\fdecor MS Sans SerifSymbolArialTimes New RomanCourier{\\colortbl\\red0\\green0\\blue0\n\r\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab\\tx";
$length_preload = strlen($preload);
$init_dict = [];
Expand All @@ -71,7 +73,7 @@ function uncompress(&$data)
}
$init_dict = array_merge($init_dict, array_fill(count($init_dict), self::MAX_DICT_SIZE - $length_preload, ' '));
$write_offset = self::INIT_DICT_SIZE;
$output_buffer = '';
$output_buffer = [];
$end = false;
$in = 0;
$l = strlen($data);
Expand All @@ -93,7 +95,7 @@ function uncompress(&$data)
for ($step = 0; $step < $actual_length; $step++) {
$read_offset = ($offset + $step) % self::MAX_DICT_SIZE;
$char = $init_dict[$read_offset];
$output_buffer .= $char;
$output_buffer[] = $char;
$init_dict[$write_offset] = $char;
$write_offset = ($write_offset + 1) % self::MAX_DICT_SIZE;
}
Expand All @@ -102,13 +104,13 @@ function uncompress(&$data)
break;
}
$val = $data[$in++];
$output_buffer .= $val;
$output_buffer[] = $val;
$init_dict[$write_offset] = $val;
$write_offset = ($write_offset + 1) % self::MAX_DICT_SIZE;
}
}
}
$this->content = $output_buffer;
$this->content = new TNEFBuffer(implode('', $output_buffer));
}

}
Expand Down
4 changes: 3 additions & 1 deletion src/TNEFDecoder/TNEFMailinfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,16 @@ function getDateSent()

function receiveTnefAttribute($attribute, $value, $length)
{
$value = new TNEFBuffer($value);

switch($attribute)
{
case TNEF_AOEMCODEPAGE:
$this->code_page = tnef_geti16($value);
break;

case TNEF_ASUBJECT:
$this->subject = substr($value, 0, $length - 1);
$this->subject = tnef_getx($length - 1, $value);
break;

case TNEF_ADATERECEIVED:
Expand Down
Loading