Merge "Selenium: replace UserLoginPage with BlankPage where possible"
[lhc/web/wiklou.git] / includes / libs / objectcache / APCBagOStuff.php
index 902cd6a..465fe82 100644 (file)
 /**
  * This is a wrapper for APC'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 APCBagOStuff extends BagOStuff {
-
-       /**
-        * @var bool If true, trust the APC implementation to serialize and
-        * deserialize objects correctly. If false, (de-)serialize in PHP.
-        */
-       protected $nativeSerialize;
+       /** @var bool Whether to trust the APC implementation to serialization */
+       private $nativeSerialize;
 
        /**
         * @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 = ':2';
+       const KEY_SUFFIX = ':4';
 
-       /**
-        * Available parameters are:
-        *   - nativeSerialize:     If true, pass objects to apc_store(), and trust it
-        *                          to serialize them correctly. If false, serialize
-        *                          all values in PHP.
-        *
-        * @param array $params
-        */
        public function __construct( array $params = [] ) {
+               $params['segmentationSize'] = $params['segmentationSize'] ?? INF;
                parent::__construct( $params );
-
-               if ( isset( $params['nativeSerialize'] ) ) {
-                       $this->nativeSerialize = $params['nativeSerialize'];
-               } elseif ( extension_loaded( 'apcu' ) && ini_get( 'apc.serializer' ) === 'default' ) {
-                       // 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
-                       $this->logger->warning(
-                               'The APCu extension is loaded and the apc.serializer INI setting ' .
-                               'is set to "default". This can cause memory corruption! ' .
-                               'You should change apc.serializer to "php" instead. ' .
-                               'See <https://github.com/krakjoe/apcu/issues/38>.'
-                       );
-                       $this->nativeSerialize = false;
-               } else {
-                       $this->nativeSerialize = true;
-               }
+               // The extension serializer is still buggy, unlike "php" and "igbinary"
+               $this->nativeSerialize = ( ini_get( 'apc.serializer' ) !== 'default' );
        }
 
        protected function doGet( $key, $flags = 0, &$casToken = null ) {
                $casToken = null;
 
                $blob = apc_fetch( $key . self::KEY_SUFFIX );
-               $value = $this->unserialize( $blob );
+               $value = $this->nativeSerialize ? $blob : $this->unserialize( $blob );
                if ( $value !== false ) {
                        $casToken = $blob; // don't bother hashing this
                }
@@ -84,10 +63,10 @@ class APCBagOStuff extends BagOStuff {
                return $value;
        }
 
-       public function set( $key, $value, $exptime = 0, $flags = 0 ) {
+       protected function doSet( $key, $value, $exptime = 0, $flags = 0 ) {
                apc_store(
                        $key . self::KEY_SUFFIX,
-                       $this->serialize( $value ),
+                       $this->nativeSerialize ? $value : $this->serialize( $value ),
                        $exptime
                );
 
@@ -97,12 +76,12 @@ class APCBagOStuff extends BagOStuff {
        public function add( $key, $value, $exptime = 0, $flags = 0 ) {
                return apc_add(
                        $key . self::KEY_SUFFIX,
-                       $this->serialize( $value ),
+                       $this->nativeSerialize ? $value : $this->serialize( $value ),
                        $exptime
                );
        }
 
-       public function delete( $key, $flags = 0 ) {
+       protected function doDelete( $key, $flags = 0 ) {
                apc_delete( $key . self::KEY_SUFFIX );
 
                return true;
@@ -115,20 +94,4 @@ class APCBagOStuff extends BagOStuff {
        public function decr( $key, $value = 1 ) {
                return apc_dec( $key . self::KEY_SUFFIX, $value );
        }
-
-       protected function serialize( $value ) {
-               if ( !$this->nativeSerialize && !$this->isInteger( $value ) ) {
-                       $value = serialize( $value );
-               }
-               return $value;
-       }
-
-       protected function unserialize( $value ) {
-               if ( is_string( $value ) && !$this->nativeSerialize ) {
-                       $value = $this->isInteger( $value )
-                               ? intval( $value )
-                               : unserialize( $value );
-               }
-               return $value;
-       }
 }