HEX
Server: Apache/2.4.59 (Debian)
System: Linux skycube.cz 4.19.0-25-amd64 #1 SMP Debian 4.19.289-2 (2023-08-08) x86_64
User: ilya (534)
PHP: 7.3.31-1~deb10u7
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,
Upload Files
File: /var/www/ilya/data/www/rudomilov.ru/wp-content/plugins/widget-logic/widget/logic/parser.php
<?php
if (!defined('ABSPATH')) exit; // Exit if accessed directly

include_once 'function/is_function.php';
include_once 'function/main_function.php';

/**
 * Helper function to parse expressions
 */
function widget_logic_parse_expression(&$tokens, &$pos, $allowed_functions)
{
    // Parse first term or AND expression
    $result = widget_logic_parse_and_expression($tokens, $pos, $allowed_functions);

    while ($pos < count($tokens)) {
        $token = $tokens[$pos];

        if (')' === $token) {
            // This closing parenthesis should be handled by the calling function
            break;
        }

        // Handle OR operator (lower precedence than AND)
        if ('||' === $token) {
            $pos++;

            // Check for empty parentheses in boolean expression
            if ($pos < count($tokens) && '(' === $tokens[$pos] &&
                $pos + 1 < count($tokens) && ')' === $tokens[$pos + 1]) {
                throw new Exception( esc_html__('Widget Logic: Empty parentheses not allowed in boolean expressions.', 'widget-logic'));
            }

            // Parse the right side as an AND expression
            $right = widget_logic_parse_and_expression($tokens, $pos, $allowed_functions);
            $result = $result || $right;
        } else {
            break;
        }
    }

    return $result;
}

// Helper function to parse AND expressions (terms connected by &&)
function widget_logic_parse_and_expression(&$tokens, &$pos, $allowed_functions)
{
    $result = widget_logic_parse_term($tokens, $pos, $allowed_functions);

    while ($pos < count($tokens)) {
        $token = $tokens[$pos];

        if (')' === $token || '||' === $token) {
            // These should be handled by the calling function
            break;
        }

        if ('&&' === $token) {
            $pos++;

            // Check for empty parentheses in boolean expression
            if ($pos < count($tokens) && '(' === $tokens[$pos] &&
                $pos + 1 < count($tokens) && ')' === $tokens[$pos + 1]) {
                throw new Exception( esc_html__('Widget Logic: Empty parentheses not allowed in boolean expressions.', 'widget-logic'));
            }

            $term = widget_logic_parse_term($tokens, $pos, $allowed_functions);
            $result = $result && $term;
        } else {
            break;
        }
    }

    return $result;
}

// Helper function to parse terms
function widget_logic_parse_term(&$tokens, &$pos, $allowed_functions)
{
    if ($pos >= count($tokens)) {
        throw new Exception(esc_html__('Widget Logic: Unexpected end of expression.', 'widget-logic'));
    }

    $token = $tokens[$pos++];

    // Handle negation
    if ('!' === $token) {
        return !widget_logic_parse_term($tokens, $pos, $allowed_functions);
    }

    // Handle parenthesized expressions
    if ('(' === $token) {
        // Check for empty parentheses case
        if ($pos < count($tokens) && ')' === $tokens[$pos]) {
            $pos++; // Skip the closing parenthesis
            return true; // Empty parentheses treated like empty string
        }

        $result = widget_logic_parse_expression($tokens, $pos, $allowed_functions);

        if ($pos >= count($tokens) || ')' !== $tokens[$pos]) {
            throw new Exception(esc_html__('Widget Logic: Missing closing parenthesis.', 'widget-logic'));
        }

        $pos++; // Skip the closing parenthesis
        return $result;
    }

    // Handle closing parenthesis without matching opening parenthesis
    if (')' === $token) {
        throw new Exception( esc_html__('Widget Logic: Unbalanced closing parenthesis.', 'widget-logic'));
    }

    // Reject direct array usage
    if (strpos($token, 'array(') === 0 || strpos($token, '[') === 0) {
        throw new Exception( esc_html__('Widget Logic: Direct array usage is not allowed in expressions.', 'widget-logic'));
    }

    // Handle boolean constants
    if (0 === strcasecmp('true', $token)) {
        return true;
    }

    if (0 === strcasecmp('false', $token)) {
        return false;
    }

    if (0 === strcasecmp('null', $token)) {
        return false;
    }

    // Handle function calls
    if (widget_logic_is_function_call( $token, $matches)) {
        return widget_logic_handle_function_call($matches, $allowed_functions);
    }

    /* translators: %s: The unexpected token found in the expression */
    throw new Exception(sprintf(esc_html__('Widget Logic: Unexpected token: %s', 'widget-logic'), esc_html($token)));
}