Skip to content

Commit

Permalink
Require bcmath extension and remove Math_BigInteger dependency.
Browse files Browse the repository at this point in the history
Math_BigInteger's native implementation is very buggy. No longer
support it.
  • Loading branch information
mrubinsk committed Dec 24, 2017
1 parent c300dc2 commit afc8c48
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 27 deletions.
37 changes: 21 additions & 16 deletions lib/Horde/Mapi.php
Expand Up @@ -141,8 +141,12 @@ public static function filetimeToUnixtime($ft)
$dtval = substr($ft, 0, 16); // clip overlength string
$dtval = str_pad($dtval, 16, '0'); // pad underlength string
$quad = self::_flipEndian($dtval);
$win64_datetime = self::_hexToBcint($quad);
return self::_win64ToUnix($win64_datetime);
try {
$win64_datetime = self::_hexToBcint($quad);
return self::_win64ToUnix($win64_datetime);
} catch (Horde_Mapi_Exception $e) {
return -1;
}
}

// swap little-endian to big-endian
Expand All @@ -162,38 +166,39 @@ protected static function _flipEndian($str)
// convert hex string to BC-int
protected static function _hexToBcint($str)
{
if (!extension_loaded('bcmath')) {
throw new Horde_Mapi_Exception('bcmath extension not loaded.');
}

$hex = array(
'0'=>'0', '1'=>'1', '2'=>'2', '3'=>'3', '4'=>'4',
'5'=>'5', '6'=>'6', '7'=>'7', '8'=>'8', '9'=>'9',
'a'=>'10', 'b'=>'11', 'c'=>'12', 'd'=>'13', 'e'=>'14', 'f'=>'15',
'A'=>'10', 'B'=>'11', 'C'=>'12', 'D'=>'13', 'E'=>'14', 'F'=>'15'
);

$bci = new Math_BigInteger('0');
$bci = '0';
$len = strlen($str);
for ($i = 0; $i < $len; ++$i) {
$bci = $bci->multiply(new Math_BigInteger('16'));
$bci = bcmul($bci, '16');
$ch = $str[$i];
if (isset($hex[$ch])) {
$bci = $bci->add(new Math_BigInteger($hex[$ch]));
}
if (isset($hex[$ch]))
$bci = bcadd($bci, $hex[$ch]);
}

return $bci;
}

/**
*
* @param Math_BigInteger $bci
* @return string
*/
protected static function _win64ToUnix($bci)
{
// Unix epoch as a Windows file date-time value
$t = $bci->subtract(new Math_BigInteger('116444735995904000')); // Cast to Unix epoch
list($quotient, $remainder) = $t->divide(new Math_BigInteger('10000000'));
if (!extension_loaded('bcmath')) {
throw new Horde_Mapi_Exception('bcmath extension not loaded.');
}

return (string)$quotient;
// Unix epoch as a Windows file date-time value
$magicnum = '116444735995904000';
$t = bcsub($bci, $magicnum); // Cast to Unix epoch
return bcdiv($t, '10000000', 0); // Convert from ticks to seconds
}


Expand Down
16 changes: 6 additions & 10 deletions package.xml
Expand Up @@ -21,7 +21,7 @@
</stability>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
*
*
</notes>
<contents>
<dir baseinstalldir="/" name="/">
Expand Down Expand Up @@ -82,13 +82,9 @@
<max>3.0.0alpha1</max>
<exclude>3.0.0alpha1</exclude>
</package>
<package>
<name>Math_BigInteger</name>
<channel>pear.php.net</channel>
<min>1.0.2</min>
<max>2.0.0alpha1</max>
<exclude>2.0.0alpha1</exclude>
</package>
<extension>
<name>bcmath</name>
</extension>
</required>
</dependencies>
<phprelease>
Expand Down Expand Up @@ -132,7 +128,7 @@
<date>2014-01-18</date>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
*
*
</notes>
</release>
<release>
Expand Down Expand Up @@ -236,7 +232,7 @@
<date>2017-11-11</date>
<license uri="http://www.horde.org/licenses/lgpl21">LGPL-2.1</license>
<notes>
*
*
</notes>
</release>
</changelog>
Expand Down
6 changes: 5 additions & 1 deletion test/Horde/Mapi/MapiTest.php
Expand Up @@ -22,7 +22,11 @@ class Horde_Mapi_MapiTest extends PHPUnit_Framework_TestCase
public function testFiletimeToUnixTime()
{
$data = file_get_contents(__DIR__ . '/fixtures/filetime');
$this->assertEquals(Horde_Mapi::filetimeToUnixtime($data), 1387818000);

$this->assertEquals(
extension_loaded('bcmath') ? 1387818000 : -1,
Horde_Mapi::filetimeToUnixtime($data)
);
}

/**
Expand Down

0 comments on commit afc8c48

Please sign in to comment.