X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Flibs%2Fobjectcache%2FAPCUBagOStuff.php;h=eba0af50f8bed35f9fc400dec0fc7bc96f5c58d2;hb=a1389b602411984de0a5258513e97f4702c941cf;hp=da6544b3d102c3828ab36588aa944ba4d2371e6c;hpb=a6facc8a0a4f9b54e0cfb1e5ef6f3991de752342;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/libs/objectcache/APCUBagOStuff.php b/includes/libs/objectcache/APCUBagOStuff.php index da6544b3d1..eba0af50f8 100644 --- a/includes/libs/objectcache/APCUBagOStuff.php +++ b/includes/libs/objectcache/APCUBagOStuff.php @@ -24,19 +24,30 @@ /** * This is a wrapper for APCU's shared memory functions * + * Use PHP serialization to avoid bugs and easily create CAS tokens. + * APCu has a memory corruption bug when the serializer is set to 'default'. + * See T120267, and upstream bug reports: + * - https://github.com/krakjoe/apcu/issues/38 + * - https://github.com/krakjoe/apcu/issues/35 + * - https://github.com/krakjoe/apcu/issues/111 + * * @ingroup Cache */ -class APCUBagOStuff extends APCBagOStuff { +class APCUBagOStuff extends BagOStuff { + /** @var bool Whether to trust the APC implementation to serialization */ + private $nativeSerialize; + /** - * Available parameters are: - * - nativeSerialize: If true, pass objects to apcu_store(), and trust it - * to serialize them correctly. If false, serialize - * all values in PHP. - * - * @param array $params + * @var string String to append to each APC key. This may be changed + * whenever the handling of values is changed, to prevent existing code + * from encountering older values which it cannot handle. */ + const KEY_SUFFIX = ':4'; + public function __construct( array $params = [] ) { parent::__construct( $params ); + // The extension serialize is still buggy, unlike "php" and "igbinary" + $this->nativeSerialize = ( ini_get( 'apc.serializer' ) !== 'default' ); } protected function doGet( $key, $flags = 0, &$casToken = null ) { @@ -52,13 +63,11 @@ class APCUBagOStuff extends APCBagOStuff { } public function set( $key, $value, $exptime = 0, $flags = 0 ) { - apcu_store( + return apcu_store( $key . self::KEY_SUFFIX, $this->serialize( $value ), $exptime ); - - return true; } public function add( $key, $value, $exptime = 0, $flags = 0 ) { @@ -76,11 +85,7 @@ class APCUBagOStuff extends APCBagOStuff { } public function incr( $key, $value = 1 ) { - /** - * @todo When we only support php 7 or higher remove this hack - * - * https://github.com/krakjoe/apcu/issues/166 - */ + // https://github.com/krakjoe/apcu/issues/166 if ( apcu_exists( $key . self::KEY_SUFFIX ) ) { return apcu_inc( $key . self::KEY_SUFFIX, $value ); } else { @@ -89,15 +94,27 @@ class APCUBagOStuff extends APCBagOStuff { } public function decr( $key, $value = 1 ) { - /** - * @todo When we only support php 7 or higher remove this hack - * - * https://github.com/krakjoe/apcu/issues/166 - */ + // https://github.com/krakjoe/apcu/issues/166 if ( apcu_exists( $key . self::KEY_SUFFIX ) ) { return apcu_dec( $key . self::KEY_SUFFIX, $value ); } else { return false; } } + + protected function serialize( $value ) { + if ( $this->nativeSerialize ) { + return $value; + } + + return $this->isInteger( $value ) ? (int)$value : serialize( $value ); + } + + protected function unserialize( $value ) { + if ( $this->nativeSerialize ) { + return $value; + } + + return $this->isInteger( $value ) ? (int)$value : unserialize( $value ); + } }