AnonSec Shell
Server IP : 172.67.157.199  /  Your IP : 3.15.182.138   [ Reverse IP ]
Web Server : Apache
System : Linux b70eb322-3aee-0c53-7c82-0db91281f2c6.secureserver.net 6.1.90-1.el9.elrepo.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 2 12:09:22 EDT 2024 x86_64
User : root ( 0)
PHP Version : 8.0.30.2
Disable Function : NONE
Domains : 0 Domains
MySQL : ON  |  cURL : ON  |  WGET : ON  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/wp-content/mu-plugins/object-cache-pro/src/ObjectCaches/Concerns/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME ]     [ BACKUP SHELL ]     [ JUMPING ]     [ MASS DEFACE ]     [ SCAN ROOT ]     [ SYMLINK ]     

Current File : /var/www/wp-content/mu-plugins/object-cache-pro/src/ObjectCaches/Concerns/KeepsMetadata.php
<?php
/**
 * Copyright © 2019-2024 Rhubarb Tech Inc. All Rights Reserved.
 *
 * The Object Cache Pro Software and its related materials are property and confidential
 * information of Rhubarb Tech Inc. Any reproduction, use, distribution, or exploitation
 * of the Object Cache Pro Software and its related materials, in whole or in part,
 * is strictly forbidden unless prior permission is obtained from Rhubarb Tech Inc.
 *
 * In addition, any reproduction, use, distribution, or exploitation of the Object Cache Pro
 * Software and its related materials, in whole or in part, is subject to the End-User License
 * Agreement accessible in the included `LICENSE` file, or at: https://objectcache.pro/eula
 */

declare(strict_types=1);

namespace RedisCachePro\ObjectCaches\Concerns;

use Throwable;

use RedisCachePro\Exceptions\ObjectCacheException;

/**
 * Keeps track of object cache metadata, such as the used configuration.
 *
 * If risky configuration options have changed and the `strict` mode is
 * enabled, the cache will be automatically flushed to avoid collisions.
 */
trait KeepsMetadata
{
    /**
     * The stored object cache metadata.
     *
     * @var ?array<string, array<string, mixed>>
     */
    private $metadata;

    /**
     * Boots the metadata component.
     *
     * @return void
     */
    protected function bootMetadata(): void
    {
        try {
            $this->loadMetadata();
            $this->throwIfRiskyConfigurationChanged();
        } catch (Throwable $exception) {
            $this->integrityProtectionFlush($exception->getMessage());
        }

        $this->maybeUpdateMetadata();
    }

    /**
     * Retrieves the stored metadata from the cache.
     *
     * @return void
     */
    private function loadMetadata()
    {
        $json = $this->withoutMutations([$this, 'getMetadata']);

        if (! is_string($json)) {
            throw new ObjectCacheException('Cache metadata not found');
        }

        $metadata = json_decode($json, true);

        if (! is_array($metadata)) {
            throw new ObjectCacheException(sprintf(
                'Unable to decode cache metadata (%s)',
                (json_last_error() !== JSON_ERROR_NONE)
                    ? json_last_error_msg()
                    : gettype($metadata) . ' found'
            ));
        }

        $this->metadata = $metadata;
    }

    /**
     * Saves the current metadata to the cache.
     *
     * @return void
     */
    public function writeMetadata()
    {
        $this->metadata = $this->buildMetadata();

        $this->withoutMutations([$this, 'setMetadata']);
    }

    /**
     * Build the metadata based on the current configuration.
     *
     * @return array<string, array<string, mixed>>
     */
    private function buildMetadata(): array
    {
        global $wp_version;

        return [
            'config' => [
                'client' => $this->clientName(),
                'database' => $this->config->database,
                'prefix' => $this->config->prefix,
                'serializer' => $this->config->serializer,
                'compression' => $this->config->compression,
                'prefetch' => $this->config->prefetch,
                'split_alloptions' => $this->config->split_alloptions,
            ],
            'versions' => [
                'wordpress' => $wp_version,
            ],
        ];
    }

    /**
     * Throws an exception if a risky configuration option has changed.
     *
     * @return void
     */
    private function throwIfRiskyConfigurationChanged()
    {
        $storedConfig = $this->metadata['config'] ?? [];
        $currentConfig = $this->buildMetadata()['config'];

        $riskyOptions = [
            'client', // just a precaution (no known issues)
            'database', // avoid loading foreign dataset
            'prefix', // avoid loading foreign dataset
            'split_alloptions', // avoid loading stale `alloptions` data
            'serializer', // mixing serializers will cause critical errors
            'compression', // mixing data compressions will cause critical errors
        ];

        foreach ($riskyOptions as $option) {
            if (! array_key_exists($option, $storedConfig) || $storedConfig[$option] !== $currentConfig[$option]) {
                throw new ObjectCacheException("Risky configuration option `{$option}` changed");
            }
        }
    }

    /**
     * Updates the object cache metadata, if it has changed.
     *
     * @return void
     */
    private function maybeUpdateMetadata()
    {
        $storedConfig = $this->metadata['config'] ?? [];
        $currentConfig = $this->buildMetadata()['config'];

        if (! empty(array_diff_assoc($currentConfig, $storedConfig))) {
            $this->writeMetadata();
        }
    }

    /**
     * Flushes the object cache for integrity protection, if `strict` mode is enabled.
     *
     * @return bool
     */
    private function integrityProtectionFlush(string $message)
    {
        global $wp_object_cache_flushlog;

        $this->metadata = null;

        if (! $this->config->strict) {
            error_log("objectcache.notice: {$message}, skipping integrity protection flush because `strict` mode is disabled");

            return false;
        }

        error_log("objectcache.notice: {$message}, flushing cache for integrity protection...");

        $wp_object_cache_flushlog[] = [
            'type' => 'flush',
            'backtrace' => \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 5),
        ];

        try {
            $this->flush_runtime();

            return $this->connection->flushdb();
        } catch (Throwable $exception) {
            $this->error($exception);

            return false;
        } finally {
            $this->metrics->flush();
        }
    }

    /**
     * Callback for `withoutMutations()` in `loadMetadata()`.
     * Improves Query Monitor readability.
     *
     * @internal
     * @return string|false
     */
    public function getMetadata()
    {
        return $this->get('meta', 'objectcache');
    }

    /**
     * Callback for `withoutMutations()` in `writeMetadata()`.
     * Avoids `maxttl` by using connection directly.
     * Improves Query Monitor readability.
     *
     * @internal
     * @return void
     */
    public function setMetadata()
    {
        $this->connection->set(
            (string) $this->id('meta', 'objectcache'),
            json_encode($this->metadata)
        );
    }
}

Anon7 - 2022
AnonSec Team