Skip to content

Commit

Permalink
Use shared cache per message to prevent race conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
slusarz committed Dec 11, 2013
1 parent 9cf792a commit 9682bae
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 56 deletions.
21 changes: 21 additions & 0 deletions imp/lib/Contents.php
Expand Up @@ -101,6 +101,13 @@ class IMP_Contents
*/
protected $_message;

/**
* Cached data for the MIME Viewer objects.
*
* @var object
*/
protected $_viewcache;

/**
* Constructor.
*
Expand Down Expand Up @@ -1567,4 +1574,18 @@ protected function _fetchData(Horde_Imap_Client_Fetch_Query $query)
return $res;
}

/**
* Return the view cache object for this message.
*
* @return object View object.
*/
public function getViewCache()
{
if (!isset($this->_viewcache)) {
$this->_viewcache = new stdClass;
}

return $this->_viewcache;
}

}
17 changes: 7 additions & 10 deletions imp/lib/Mime/Viewer/Partial.php
Expand Up @@ -45,27 +45,21 @@ class IMP_Mime_Viewer_Partial extends Horde_Mime_Viewer_Base
'forceinline' => true
);

/**
* Cached data.
*
* @var array
*/
static protected $_statuscache = array();

/**
* Return the rendered information about the Horde_Mime_Part object.
*
* @return array See parent::render().
*/
protected function _renderInfo()
{
$cache = $this->getConfigParam('imp_contents')->getViewCache();
$id = $this->_mimepart->getMimeId();

if (isset(self::$_statuscache[$id])) {
if (isset($cache->partial) && isset($cache->partial[$id])) {
return array(
$id => array(
'data' => null,
'status' => self::$_statuscache[$id],
'status' => $cache->partial[$id],
'type' => 'text/plain; charset=' . $this->getConfigParam('charset')
)
);
Expand Down Expand Up @@ -102,7 +96,10 @@ protected function _getEmbeddedMimeParts()
if ($msg_count != $total) {
$status = new IMP_Mime_Status(sprintf(_("Cannot display message - found only %s of %s parts of this message in the current mailbox."), $msg_count, $total));
$status->action(IMP_Mime_Status::ERROR);
self::$_statuscache[$this->_mimepart->getMimeId()] = $status;

$cache = $this->getConfigParam('imp_contents')->getViewCache();
$cache->partial[$this->_mimepart->getMimeId()] = $status;

return null;
}

Expand Down
29 changes: 9 additions & 20 deletions imp/lib/Mime/Viewer/Pgp.php
Expand Up @@ -69,13 +69,6 @@ class IMP_Mime_Viewer_Pgp extends Horde_Mime_Viewer_Base
*/
protected $_sender = null;

/**
* Cached data.
*
* @var array
*/
static protected $_cache = array();

/**
* Return the full rendered version of the Horde_Mime_Part object.
*
Expand Down Expand Up @@ -151,20 +144,17 @@ protected function _renderInline()
return $this->_outputPGPSigned();

case 'multipart/encrypted':
if (!isset($headers)) {
$headers = $this->getConfigParam('imp_contents')->getHeader();
}
$cache = $this->getConfigParam('imp_contents')->getViewCache();

$mid = $headers->getValue('message-id');
if (isset(self::$_cache[$mid][$id])) {
if (isset($cache->pgp[$id])) {
return array_merge(array(
$id => array(
'data' => null,
'status' => self::$_cache[$mid][$id]['status'],
'status' => $cache->pgp[$id]['status'],
'type' => 'text/plain; charset=' . $this->getConfigParam('charset'),
'wrap' => self::$_cache[$mid][$id]['wrap']
'wrap' => $cache->pgp[$id]['wrap']
)
), self::$_cache[$mid][$id]['other']);
), $cache->pgp[$id]['other']);
}
// Fall-through

Expand All @@ -188,8 +178,6 @@ protected function _getEmbeddedMimeParts()
return null;
}

$mid = $this->getConfigParam('imp_contents')->getHeader()->getValue('message-id');

$partlist = array_keys($this->_mimepart->contentTypeMap());
$base_id = reset($partlist);
$version_id = next($partlist);
Expand All @@ -198,7 +186,8 @@ protected function _getEmbeddedMimeParts()
$status = new IMP_Mime_Status();
$status->icon('mime/encryption.png', 'PGP');

self::$_cache[$mid][$base_id] = array(
$cache = $this->getConfigParam('imp_contents')->getViewCache();
$cache->pgp[$base_id] = array(
'status' => array($status),
'other' => array(
$version_id => null,
Expand Down Expand Up @@ -308,7 +297,7 @@ protected function _getEmbeddedMimeParts()
return null;
}

self::$_cache[$mid][$base_id]['wrap'] = 'mimePartWrapValid';
$cache->pgp[$base_id]['wrap'] = 'mimePartWrapValid';

/* Check for combined encryption/signature data. */
if ($decrypted_data->result) {
Expand All @@ -319,7 +308,7 @@ protected function _getEmbeddedMimeParts()
$status2 = new IMP_Mime_Status($sig_text);
$status2->action(IMP_Mime_Status::SUCCESS);

self::$_cache[$mid][$base_id]['status'][] = $status2;
$cache->pgp[$base_id]['status'][] = $status2;
}

/* Force armor data as text/plain data. */
Expand Down
13 changes: 4 additions & 9 deletions imp/lib/Mime/Viewer/Plain.php
Expand Up @@ -23,13 +23,6 @@
*/
class IMP_Mime_Viewer_Plain extends Horde_Mime_Viewer_Plain
{
/**
* Cached data.
*
* @var array
*/
static protected $_cache = array();

/**
* Return the full rendered version of the Horde_Mime_Part object.
*
Expand Down Expand Up @@ -67,9 +60,10 @@ protected function _impRender($inline)
{
global $injector, $prefs, $registry;

$cache = $this->getConfigParam('imp_contents')->getViewCache();
$mime_id = $this->_mimepart->getMimeId();

if (isset(self::$_cache[$mime_id])) {
if (isset($cache->plain[$mime_id])) {
return array($mime_id => null);
}

Expand Down Expand Up @@ -252,7 +246,8 @@ protected function _parsePGP()
);

if (!is_null($part)) {
self::$_cache[$this->_mimepart->getMimeId()] = true;
$cache = $this->getConfigParam('imp_contents')->getViewCache();
$cache->plain[$this->_mimepart->getMimeId()] = true;
}

return $part;
Expand Down
32 changes: 15 additions & 17 deletions imp/lib/Mime/Viewer/Smime.php
Expand Up @@ -63,13 +63,6 @@ class IMP_Mime_Viewer_Smime extends Horde_Mime_Viewer_Base
*/
protected $_impsmime = null;

/**
* Cached data.
*
* @var array
*/
static protected $_cache = array();

/**
* Init the S/MIME Horde_Crypt object.
*/
Expand Down Expand Up @@ -112,17 +105,19 @@ protected function _renderInline()

case 'application/pkcs7-mime':
case 'application/x-pkcs7-mime':
if (isset(self::$_cache[$id])) {
$cache = $this->getConfigParam('imp_contents')->getViewCache();

if (isset($cache->smime[$id])) {
$ret = array(
$id => array(
'data' => null,
'status' => self::$_cache[$id]['status'],
'status' => $cache->smime[$id]['status'],
'type' => 'text/plain; charset=' . $this->getConfigParam('charset'),
'wrap' => self::$_cache[$id]['wrap']
'wrap' => $cache->smime[$id]['wrap']
)
);
if (isset(self::$_cache[$id]['sig'])) {
$ret[self::$_cache[$id]['sig']] = null;
if (isset($cache->smime[$id]['sig'])) {
$ret[$cache->smime[$id]['sig']] = null;
}
return $ret;
}
Expand Down Expand Up @@ -173,7 +168,9 @@ protected function _parseEnvelopedData()
/* Initialize inline data. */
$status = new IMP_Mime_Status(_("The data in this part has been encrypted via S/MIME."));
$status->icon('mime/encryption.png', 'S/MIME');
self::$_cache[$base_id] = array(

$cache = $this->getConfigParam('imp_contents')->getViewCache();
$cache->smime[$base_id] = array(
'status' => $status,
'wrap' => ''
);
Expand Down Expand Up @@ -209,7 +206,7 @@ protected function _parseEnvelopedData()
return null;
}

self::$_cache[$base_id]['wrap'] = 'mimePartWrapValid';
$cache->smime[$base_id]['wrap'] = 'mimePartWrapValid';

$new_part = Horde_Mime_Part::parseMessage($decrypted_data, array(
'forcemime' => true
Expand Down Expand Up @@ -265,7 +262,8 @@ protected function _parseSignedData($sig_only = false)
$status = new IMP_Mime_Status(_("The data in this part has been digitally signed via S/MIME."));
$status->icon('mime/encryption.png', 'S/MIME');

self::$_cache[$base_id] = array(
$cache = $this->getConfigParam('imp_contents')->getViewCache();
$cache->smime[$base_id] = array(
'sig' => $sig_id,
'status' => $status,
'wrap' => 'mimePartWrap'
Expand Down Expand Up @@ -294,7 +292,7 @@ protected function _parseSignedData($sig_only = false)
} else {
$status->action(IMP_Mime_Status::WARNING);
}
self::$_cache[$base_id]['wrap'] = 'mimePartWrapValid';
$cache->smime[$base_id]['wrap'] = 'mimePartWrapValid';

$email = is_array($sig_result->email)
? implode(', ', $sig_result->email)
Expand Down Expand Up @@ -337,7 +335,7 @@ protected function _parseSignedData($sig_only = false)
}
} catch (Horde_Exception $e) {
$status->action(IMP_Mime_Status::ERROR);
self::$_cache[$base_id]['wrap'] = 'mimePartWrapInvalid';
$cache->smime[$base_id]['wrap'] = 'mimePartWrapInvalid';
$status->addText($e->getMessage());
}
} else {
Expand Down

0 comments on commit 9682bae

Please sign in to comment.