mirror of
https://github.com/phpseclib/phpseclib.git
synced 2024-11-17 02:35:10 +00:00
Improve performance of File\X509->_mapInExtensions() for large arrays
This avoids passing array references by-value to is_array() (which would trigger a copy) by refactoring _subArray() into a separate is_array() check on a by-value var, and a separate unchecked reference return.
This commit is contained in:
parent
a1e16797ca
commit
88ce26f8ca
@ -1505,7 +1505,9 @@ class File_X509
|
|||||||
|
|
||||||
$this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
|
$this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
|
||||||
|
|
||||||
|
if ($this->_isSubArrayValid($x509, 'tbsCertificate/extensions')) {
|
||||||
$this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1);
|
$this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1);
|
||||||
|
}
|
||||||
$this->_mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence', $asn1);
|
$this->_mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence', $asn1);
|
||||||
$this->_mapInDNs($x509, 'tbsCertificate/subject/rdnSequence', $asn1);
|
$this->_mapInDNs($x509, 'tbsCertificate/subject/rdnSequence', $asn1);
|
||||||
|
|
||||||
@ -1609,9 +1611,9 @@ class File_X509
|
|||||||
*/
|
*/
|
||||||
function _mapInExtensions(&$root, $path, $asn1)
|
function _mapInExtensions(&$root, $path, $asn1)
|
||||||
{
|
{
|
||||||
$extensions = &$this->_subArray($root, $path);
|
$extensions = &$this->_subArrayUnchecked($root, $path);
|
||||||
|
|
||||||
if (is_array($extensions)) {
|
if ($extensions) {
|
||||||
for ($i = 0; $i < count($extensions); $i++) {
|
for ($i = 0; $i < count($extensions); $i++) {
|
||||||
$id = $extensions[$i]['extnId'];
|
$id = $extensions[$i]['extnId'];
|
||||||
$value = &$extensions[$i]['extnValue'];
|
$value = &$extensions[$i]['extnValue'];
|
||||||
@ -1743,7 +1745,7 @@ class File_X509
|
|||||||
if ($mapped !== false) {
|
if ($mapped !== false) {
|
||||||
$values[$j] = $mapped;
|
$values[$j] = $mapped;
|
||||||
}
|
}
|
||||||
if ($id == 'pkcs-9-at-extensionRequest') {
|
if ($id == 'pkcs-9-at-extensionRequest' && $this->_isSubArrayValid($values, $j)) {
|
||||||
$this->_mapInExtensions($values, $j, $asn1);
|
$this->_mapInExtensions($values, $j, $asn1);
|
||||||
}
|
}
|
||||||
} elseif ($map) {
|
} elseif ($map) {
|
||||||
@ -3276,11 +3278,18 @@ class File_X509
|
|||||||
$this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
|
$this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
|
||||||
|
|
||||||
$this->_mapInDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
|
$this->_mapInDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
|
||||||
|
if ($this->_isSubArrayValid($crl, 'tbsCertList/crlExtensions')) {
|
||||||
$this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
|
$this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
|
||||||
$rclist = &$this->_subArray($crl, 'tbsCertList/revokedCertificates');
|
}
|
||||||
if (is_array($rclist)) {
|
if ($this->_isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) {
|
||||||
|
$rclist_ref = &$this->_subArrayUnchecked($crl, 'tbsCertList/revokedCertificates');
|
||||||
|
if ($rclist_ref) {
|
||||||
|
$rclist = $crl['tbsCertList']['revokedCertificates'];
|
||||||
foreach ($rclist as $i => $extension) {
|
foreach ($rclist as $i => $extension) {
|
||||||
$this->_mapInExtensions($rclist, "$i/crlEntryExtensions", $asn1);
|
if ($this->_isSubArrayValid($rclist, "$i/crlEntryExtensions", $asn1)) {
|
||||||
|
$this->_mapInExtensions($rclist_ref, "$i/crlEntryExtensions", $asn1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3903,6 +3912,74 @@ class File_X509
|
|||||||
$this->caFlag = true;
|
$this->caFlag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for validity of subarray
|
||||||
|
*
|
||||||
|
* This is intended for use in conjunction with _subArrayUnchecked(),
|
||||||
|
* implementing the checks included in _subArray() but without copying
|
||||||
|
* a potentially large array by passing its reference by-value to is_array().
|
||||||
|
*
|
||||||
|
* @param array $root
|
||||||
|
* @param string $path
|
||||||
|
* @return boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _isSubArrayValid($root, $path)
|
||||||
|
{
|
||||||
|
if (!is_array($root)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (explode('/', $path) as $i) {
|
||||||
|
if (!is_array($root)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($root[$i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$root = $root[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a reference to a subarray
|
||||||
|
*
|
||||||
|
* This variant of _subArray() does no is_array() checking,
|
||||||
|
* so $root should be checked with _isSubArrayValid() first.
|
||||||
|
*
|
||||||
|
* This is here for performance reasons:
|
||||||
|
* Passing a reference (i.e. $root) by-value (i.e. to is_array())
|
||||||
|
* creates a copy. If $root is an especially large array, this is expensive.
|
||||||
|
*
|
||||||
|
* @param array $root
|
||||||
|
* @param string $path absolute path with / as component separator
|
||||||
|
* @param bool $create optional
|
||||||
|
* @access private
|
||||||
|
* @return array|false
|
||||||
|
*/
|
||||||
|
function &_subArrayUnchecked(&$root, $path, $create = false)
|
||||||
|
{
|
||||||
|
$false = false;
|
||||||
|
|
||||||
|
foreach (explode('/', $path) as $i) {
|
||||||
|
if (!isset($root[$i])) {
|
||||||
|
if (!$create) {
|
||||||
|
return $false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$root[$i] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$root = &$root[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $root;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a reference to a subarray
|
* Get a reference to a subarray
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user