!C99Shell v. 2.1 [PHP 8 Update] [02.02.2022]!

Software: Apache/2.4.53 (Unix) OpenSSL/1.1.1o PHP/7.4.29 mod_perl/2.0.12 Perl/v5.34.1. PHP/7.4.29 

uname -a: Linux vps-2738122-x 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64 

uid=1(daemon) gid=1(daemon) grupos=1(daemon) 

Safe-mode: OFF (not secure)

/opt/apex_led/php/vendor/pimple/pimple/ext/pimple/   drwxrwxr-x
Free 15.59 GB of 61.93 GB (25.17%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     pimple.c (28.55 KB)      -rwxrwxr-x
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |

/*
 * This file is part of Pimple.
 *
 * Copyright (c) 2014 Fabien Potencier
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_pimple.h"
#include "pimple_compat.h"
#include "zend_interfaces.h"
#include "zend.h"
#include "Zend/zend_closures.h"
#include "ext/spl/spl_exceptions.h"
#include "Zend/zend_exceptions.h"
#include "main/php_output.h"
#include "SAPI.h"

static zend_class_entry *pimple_ce;
static zend_object_handlers pimple_object_handlers;
static zend_class_entry *pimple_closure_ce;
static zend_class_entry *pimple_serviceprovider_ce;
static zend_object_handlers pimple_closure_object_handlers;
static zend_internal_function pimple_closure_invoker_function;

#define FETCH_DIM_HANDLERS_VARS     pimple_object *pimple_obj = NULL; \
                                    ulong index; \
                                    pimple_obj = (pimple_object *)zend_object_store_get_object(object TSRMLS_CC); \

#define PIMPLE_OBJECT_HANDLE_INHERITANCE_OBJECT_HANDLERS    do { \
    if (ce != pimple_ce) { \
        zend_hash_find(&ce->function_table, ZEND_STRS("offsetget"), (void **)&function); \
        if (function->common.scope != ce) { /* if the function is not defined in this actual class */ \
            pimple_object_handlers.read_dimension = pimple_object_read_dimension; /* then overwrite the handler to use custom one */ \
        } \
        zend_hash_find(&ce->function_table, ZEND_STRS("offsetset"), (void **)&function); \
        if (function->common.scope != ce) { \
            pimple_object_handlers.write_dimension = pimple_object_write_dimension; \
        } \
        zend_hash_find(&ce->function_table, ZEND_STRS("offsetexists"), (void **)&function); \
        if (function->common.scope != ce) { \
            pimple_object_handlers.has_dimension = pimple_object_has_dimension; \
        } \
        zend_hash_find(&ce->function_table, ZEND_STRS("offsetunset"), (void **)&function); \
        if (function->common.scope != ce) { \
            pimple_object_handlers.unset_dimension = pimple_object_unset_dimension; \
        } \
    } else { \
        pimple_object_handlers.read_dimension = pimple_object_read_dimension; \
        pimple_object_handlers.write_dimension = pimple_object_write_dimension; \
        pimple_object_handlers.has_dimension = pimple_object_has_dimension; \
        pimple_object_handlers.unset_dimension = pimple_object_unset_dimension; \
    }\
                                            } while(0);

#define PIMPLE_CALL_CB    do { \
            zend_fcall_info_argn(&fci TSRMLS_CC, 1, &object); \
            fci.size           = sizeof(fci); \
            fci.object_ptr     = retval->fcc.object_ptr; \
            fci.function_name  = retval->value; \
            fci.no_separation  = 1; \
            fci.retval_ptr_ptr = &retval_ptr_ptr; \
\
            zend_call_function(&fci, &retval->fcc TSRMLS_CC); \
            efree(fci.params); \
            if (EG(exception)) { \
                return EG(uninitialized_zval_ptr); \
            } \
                        } while(0);

ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 0)
ZEND_ARG_ARRAY_INFO(0, value, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetset, 0, 0, 2)
ZEND_ARG_INFO(0, offset)
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetget, 0, 0, 1)
ZEND_ARG_INFO(0, offset)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetexists, 0, 0, 1)
ZEND_ARG_INFO(0, offset)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetunset, 0, 0, 1)
ZEND_ARG_INFO(0, offset)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_factory, 0, 0, 1)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_protect, 0, 0, 1)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_raw, 0, 0, 1)
ZEND_ARG_INFO(0, id)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_extend, 0, 0, 2)
ZEND_ARG_INFO(0, id)
ZEND_ARG_INFO(0, callable)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_keys, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_register, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, provider, Pimple\\ServiceProviderInterface, 0)
ZEND_ARG_ARRAY_INFO(0, values, 1)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_serviceprovider_register, 0, 0, 1)
ZEND_ARG_OBJ_INFO(0, pimple, Pimple\\Container, 0)
ZEND_END_ARG_INFO()

static const zend_function_entry pimple_ce_functions[] = {
    PHP_ME(Pimple, __construct,    arginfo___construct, ZEND_ACC_PUBLIC)
    PHP_ME(Pimple, factory,         arginfo_factory,         ZEND_ACC_PUBLIC)
    PHP_ME(Pimple, protect,         arginfo_protect,         ZEND_ACC_PUBLIC)
    PHP_ME(Pimple, raw,             arginfo_raw,             ZEND_ACC_PUBLIC)
    PHP_ME(Pimple, extend,          arginfo_extend,          ZEND_ACC_PUBLIC)
    PHP_ME(Pimple, keys,            arginfo_keys,            ZEND_ACC_PUBLIC)
    PHP_ME(Pimple, register,        arginfo_register,         ZEND_ACC_PUBLIC)

    PHP_ME(Pimple, offsetSet,       arginfo_offsetset,       ZEND_ACC_PUBLIC)
    PHP_ME(Pimple, offsetGet,       arginfo_offsetget,       ZEND_ACC_PUBLIC)
    PHP_ME(Pimple, offsetExists,    arginfo_offsetexists,    ZEND_ACC_PUBLIC)
    PHP_ME(Pimple, offsetUnset,     arginfo_offsetunset,     ZEND_ACC_PUBLIC)
    PHP_FE_END
};

static const zend_function_entry pimple_serviceprovider_iface_ce_functions[] = {
    PHP_ABSTRACT_ME(ServiceProviderInterface, register, arginfo_serviceprovider_register)
    PHP_FE_END
};

static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC)
{
    zend_object_std_dtor(&obj->zobj TSRMLS_CC);
    if (obj->factory) {
        zval_ptr_dtor(&obj->factory);
    }
    if (obj->callable) {
        zval_ptr_dtor(&obj->callable);
    }
    efree(obj);
}

static void pimple_free_object_storage(pimple_object *obj TSRMLS_DC)
{
    zend_hash_destroy(&obj->factories);
    zend_hash_destroy(&obj->protected);
    zend_hash_destroy(&obj->values);
    zend_object_std_dtor(&obj->zobj TSRMLS_CC);
    efree(obj);
}

static void pimple_free_bucket(pimple_bucket_value *bucket)
{
    if (bucket->raw) {
        zval_ptr_dtor(&bucket->raw);
    }
}

static zend_object_value pimple_closure_object_create(zend_class_entry *ce TSRMLS_DC)
{
    zend_object_value retval;
    pimple_closure_object *pimple_closure_obj = NULL;

    pimple_closure_obj = ecalloc(1, sizeof(pimple_closure_object));
    ZEND_OBJ_INIT(&pimple_closure_obj->zobj, ce);

    pimple_closure_object_handlers.get_constructor = pimple_closure_get_constructor;
    retval.handlers = &pimple_closure_object_handlers;
    retval.handle   = zend_objects_store_put(pimple_closure_obj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) pimple_closure_free_object_storage, NULL TSRMLS_CC);

    return retval;
}

static zend_function *pimple_closure_get_constructor(zval *obj TSRMLS_DC)
{
    zend_error(E_ERROR, "Pimple\\ContainerClosure is an internal class and cannot be instantiated");

    return NULL;
}

static int pimple_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC)
{
    *zobj_ptr = obj;
    *ce_ptr   = Z_OBJCE_P(obj);
    *fptr_ptr = (zend_function *)&pimple_closure_invoker_function;

    return SUCCESS;
}

static zend_object_value pimple_object_create(zend_class_entry *ce TSRMLS_DC)
{
    zend_object_value retval;
    pimple_object *pimple_obj  = NULL;
    zend_function *function    = NULL;

    pimple_obj = emalloc(sizeof(pimple_object));
    ZEND_OBJ_INIT(&pimple_obj->zobj, ce);

    PIMPLE_OBJECT_HANDLE_INHERITANCE_OBJECT_HANDLERS

    retval.handlers = &pimple_object_handlers;
    retval.handle   = zend_objects_store_put(pimple_obj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) pimple_free_object_storage, NULL TSRMLS_CC);

    zend_hash_init(&pimple_obj->factories, PIMPLE_DEFAULT_ZVAL_CACHE_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0);
    zend_hash_init(&pimple_obj->protected, PIMPLE_DEFAULT_ZVAL_CACHE_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0);
    zend_hash_init(&pimple_obj->values, PIMPLE_DEFAULT_ZVAL_VALUES_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0);

    return retval;
}

static void pimple_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC)
{
    FETCH_DIM_HANDLERS_VARS

    pimple_bucket_value pimple_value = {0}, *found_value = NULL;
    ulong hash;

    pimple_zval_to_pimpleval(value, &pimple_value TSRMLS_CC);

    if (!offset) {/* $p[] = 'foo' when not overloaded */
        zend_hash_next_index_insert(&pimple_obj->values, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL);
        Z_ADDREF_P(value);
        return;
    }

    switch (Z_TYPE_P(offset)) {
    case IS_STRING:
        hash = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
        zend_hash_quick_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void **)&found_value);
        if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
            pimple_free_bucket(&pimple_value);
            zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%s\".", Z_STRVAL_P(offset));
            return;
        }
        if (zend_hash_quick_update(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
            pimple_free_bucket(&pimple_value);
            return;
        }
        Z_ADDREF_P(value);
    break;
    case IS_DOUBLE:
    case IS_BOOL:
    case IS_LONG:
        if (Z_TYPE_P(offset) == IS_DOUBLE) {
            index = (ulong)Z_DVAL_P(offset);
        } else {
            index = Z_LVAL_P(offset);
        }
        zend_hash_index_find(&pimple_obj->values, index, (void **)&found_value);
        if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) {
            pimple_free_bucket(&pimple_value);
            zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot override frozen service \"%ld\".", index);
            return;
        }
        if (zend_hash_index_update(&pimple_obj->values, index, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) {
            pimple_free_bucket(&pimple_value);
            return;
        }
        Z_ADDREF_P(value);
    break;
    case IS_NULL: /* $p[] = 'foo' when overloaded */
        zend_hash_next_index_insert(&pimple_obj->values, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL);
        Z_ADDREF_P(value);
    break;
    default:
        pimple_free_bucket(&pimple_value);
        zend_error(E_WARNING, "Unsupported offset type");
    }
}

static void pimple_object_unset_dimension(zval *object, zval *offset TSRMLS_DC)
{
    FETCH_DIM_HANDLERS_VARS

    switch (Z_TYPE_P(offset)) {
    case IS_STRING:
        zend_symtable_del(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
        zend_symtable_del(&pimple_obj->factories, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
        zend_symtable_del(&pimple_obj->protected, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1);
    break;
    case IS_DOUBLE:
    case IS_BOOL:
    case IS_LONG:
        if (Z_TYPE_P(offset) == IS_DOUBLE) {
            index = (ulong)Z_DVAL_P(offset);
        } else {
            index = Z_LVAL_P(offset);
        }
        zend_hash_index_del(&pimple_obj->values, index);
        zend_hash_index_del(&pimple_obj->factories, index);
        zend_hash_index_del(&pimple_obj->protected, index);
    break;
    default:
        zend_error(E_WARNING, "Unsupported offset type");
    }
}

static int pimple_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC)
{
    FETCH_DIM_HANDLERS_VARS

    pimple_bucket_value *retval = NULL;

    switch (Z_TYPE_P(offset)) {
    case IS_STRING:
        if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == SUCCESS) {
            switch (check_empty) {
            case 0: /* isset */
                return 1; /* Differs from PHP behavior (Z_TYPE_P(retval->value) != IS_NULL;) */
            case 1: /* empty */
            default:
                return zend_is_true(retval->value);
            }
        }
        return 0;
    break;
    case IS_DOUBLE:
    case IS_BOOL:
    case IS_LONG:
        if (Z_TYPE_P(offset) == IS_DOUBLE) {
            index = (ulong)Z_DVAL_P(offset);
        } else {
            index = Z_LVAL_P(offset);
        }
        if (zend_hash_index_find(&pimple_obj->values, index, (void **)&retval) == SUCCESS) {
            switch (check_empty) {
                case 0: /* isset */
                    return 1; /* Differs from PHP behavior (Z_TYPE_P(retval->value) != IS_NULL;)*/
                case 1: /* empty */
                default:
                    return zend_is_true(retval->value);
            }
        }
        return 0;
    break;
    default:
        zend_error(E_WARNING, "Unsupported offset type");
        return 0;
    }
}

static zval *pimple_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
{
    FETCH_DIM_HANDLERS_VARS

    pimple_bucket_value *retval = NULL;
    zend_fcall_info fci         = {0};
    zval *retval_ptr_ptr        = NULL;

    switch (Z_TYPE_P(offset)) {
    case IS_STRING:
        if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == FAILURE) {
            zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
            return EG(uninitialized_zval_ptr);
        }
    break;
    case IS_DOUBLE:
    case IS_BOOL:
    case IS_LONG:
        if (Z_TYPE_P(offset) == IS_DOUBLE) {
            index = (ulong)Z_DVAL_P(offset);
        } else {
            index = Z_LVAL_P(offset);
        }
        if (zend_hash_index_find(&pimple_obj->values, index, (void **)&retval) == FAILURE) {
            return EG(uninitialized_zval_ptr);
        }
    break;
    case IS_NULL: /* $p[][3] = 'foo' first dim access */
        return EG(uninitialized_zval_ptr);
    break;
    default:
        zend_error(E_WARNING, "Unsupported offset type");
        return EG(uninitialized_zval_ptr);
    }

    if(retval->type == PIMPLE_IS_PARAM) {
        return retval->value;
    }

    if (zend_hash_index_exists(&pimple_obj->protected, retval->handle_num)) {
        /* Service is protected, return the value every time */
        return retval->value;
    }

    if (zend_hash_index_exists(&pimple_obj->factories, retval->handle_num)) {
        /* Service is a factory, call it everytime and never cache its result */
        PIMPLE_CALL_CB
        Z_DELREF_P(retval_ptr_ptr); /* fetch dim addr will increment refcount */
        return retval_ptr_ptr;
    }

    if (retval->initialized == 1) {
        /* Service has already been called, return its cached value */
        return retval->value;
    }

    ALLOC_INIT_ZVAL(retval->raw);
    MAKE_COPY_ZVAL(&retval->value, retval->raw);

    PIMPLE_CALL_CB

    retval->initialized = 1;
    zval_ptr_dtor(&retval->value);
    retval->value = retval_ptr_ptr;

    return retval->value;
}

static int pimple_zval_is_valid_callback(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC)
{
    if (Z_TYPE_P(_zval) != IS_OBJECT) {
        return FAILURE;
    }

    if (_pimple_bucket_value->fcc.called_scope) {
        return SUCCESS;
    }

    if (Z_OBJ_HANDLER_P(_zval, get_closure) && Z_OBJ_HANDLER_P(_zval, get_closure)(_zval, &_pimple_bucket_value->fcc.calling_scope, &_pimple_bucket_value->fcc.function_handler, &_pimple_bucket_value->fcc.object_ptr TSRMLS_CC) == SUCCESS) {
        _pimple_bucket_value->fcc.called_scope = _pimple_bucket_value->fcc.calling_scope;
        return SUCCESS;
    } else {
        return FAILURE;
    }
}

static int pimple_zval_to_pimpleval(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC)
{
    _pimple_bucket_value->value = _zval;

    if (Z_TYPE_P(_zval) != IS_OBJECT) {
        return PIMPLE_IS_PARAM;
    }

    if (pimple_zval_is_valid_callback(_zval, _pimple_bucket_value TSRMLS_CC) == SUCCESS) {
        _pimple_bucket_value->type       = PIMPLE_IS_SERVICE;
        _pimple_bucket_value->handle_num = Z_OBJ_HANDLE_P(_zval);
    }

    return PIMPLE_IS_SERVICE;
}

static void pimple_bucket_dtor(pimple_bucket_value *bucket)
{
    zval_ptr_dtor(&bucket->value);
    pimple_free_bucket(bucket);
}

PHP_METHOD(Pimple, protect)
{
    zval *protected     = NULL;
    pimple_object *pobj = NULL;
    pimple_bucket_value bucket = {0};

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &protected) == FAILURE) {
        return;
    }

    if (pimple_zval_is_valid_callback(protected, &bucket TSRMLS_CC) == FAILURE) {
        pimple_free_bucket(&bucket);
        zend_throw_exception(spl_ce_InvalidArgumentException, "Callable is not a Closure or invokable object.", 0 TSRMLS_CC);
        return;
    }

    pimple_zval_to_pimpleval(protected, &bucket TSRMLS_CC);
    pobj = (pimple_object *)zend_object_store_get_object(getThis() TSRMLS_CC);

    if (zend_hash_index_update(&pobj->protected, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL) == SUCCESS) {
        Z_ADDREF_P(protected);
        RETURN_ZVAL(protected, 1 , 0);
    } else {
        pimple_free_bucket(&bucket);
    }
    RETURN_FALSE;
}

PHP_METHOD(Pimple, raw)
{
    zval *offset = NULL;
    pimple_object *pobj        = NULL;
    pimple_bucket_value *value = NULL;
    ulong index;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
        return;
    }

    pobj = zend_object_store_get_object(getThis() TSRMLS_CC);

    switch (Z_TYPE_P(offset)) {
        case IS_STRING:
            if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
                RETURN_NULL();
            }
        break;
        case IS_DOUBLE:
        case IS_BOOL:
        case IS_LONG:
            if (Z_TYPE_P(offset) == IS_DOUBLE) {
                index = (ulong)Z_DVAL_P(offset);
            } else {
                index = Z_LVAL_P(offset);
            }
            if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) {
                RETURN_NULL();
            }
        break;
        case IS_NULL:
        default:
            zend_error(E_WARNING, "Unsupported offset type");
    }

    if (value->raw) {
        RETVAL_ZVAL(value->raw, 1, 0);
    } else {
        RETVAL_ZVAL(value->value, 1, 0);
    }
}

PHP_METHOD(Pimple, extend)
{
    zval *offset = NULL, *callable = NULL, *pimple_closure_obj = NULL;
    pimple_bucket_value bucket = {0}, *value = NULL;
    pimple_object *pobj          = NULL;
    pimple_closure_object *pcobj = NULL;
    ulong index;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &offset, &callable) == FAILURE) {
        return;
    }

    pobj = zend_object_store_get_object(getThis() TSRMLS_CC);

    switch (Z_TYPE_P(offset)) {
        case IS_STRING:
            if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) {
                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" is not defined.", Z_STRVAL_P(offset));
                RETURN_NULL();
            }
            if (value->type != PIMPLE_IS_SERVICE) {
                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%s\" does not contain an object definition.", Z_STRVAL_P(offset));
                RETURN_NULL();
            }
        break;
        case IS_DOUBLE:
        case IS_BOOL:
        case IS_LONG:
            if (Z_TYPE_P(offset) == IS_DOUBLE) {
                index = (ulong)Z_DVAL_P(offset);
            } else {
                index = Z_LVAL_P(offset);
            }
            if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) {
                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" is not defined.", index);
                RETURN_NULL();
            }
            if (value->type != PIMPLE_IS_SERVICE) {
                zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Identifier \"%ld\" does not contain an object definition.", index);
                RETURN_NULL();
            }
        break;
        case IS_NULL:
        default:
            zend_error(E_WARNING, "Unsupported offset type");
    }

    if (pimple_zval_is_valid_callback(callable, &bucket TSRMLS_CC) == FAILURE) {
        pimple_free_bucket(&bucket);
        zend_throw_exception(spl_ce_InvalidArgumentException, "Extension service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
        RETURN_NULL();
    }
    pimple_free_bucket(&bucket);

    ALLOC_INIT_ZVAL(pimple_closure_obj);
    object_init_ex(pimple_closure_obj, pimple_closure_ce);

    pcobj = zend_object_store_get_object(pimple_closure_obj TSRMLS_CC);
    pcobj->callable = callable;
    pcobj->factory  = value->value;
    Z_ADDREF_P(callable);
    Z_ADDREF_P(value->value);

    if (zend_hash_index_exists(&pobj->factories, value->handle_num)) {
        pimple_zval_to_pimpleval(pimple_closure_obj, &bucket TSRMLS_CC);
        zend_hash_index_del(&pobj->factories, value->handle_num);
        zend_hash_index_update(&pobj->factories, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL);
        Z_ADDREF_P(pimple_closure_obj);
    }

    pimple_object_write_dimension(getThis(), offset, pimple_closure_obj TSRMLS_CC);

    RETVAL_ZVAL(pimple_closure_obj, 1, 1);
}

PHP_METHOD(Pimple, keys)
{
    HashPosition pos;
    pimple_object *pobj = NULL;
    zval **value        = NULL;
    zval *endval        = NULL;
    char *str_index     = NULL;
    int str_len;
    ulong num_index;

    if (zend_parse_parameters_none() == FAILURE) {
        return;
    }

    pobj = zend_object_store_get_object(getThis() TSRMLS_CC);
    array_init_size(return_value, zend_hash_num_elements(&pobj->values));

    zend_hash_internal_pointer_reset_ex(&pobj->values, &pos);

    while(zend_hash_get_current_data_ex(&pobj->values, (void **)&value, &pos) == SUCCESS) {
        MAKE_STD_ZVAL(endval);
        switch (zend_hash_get_current_key_ex(&pobj->values, &str_index, (uint *)&str_len, &num_index, 0, &pos)) {
            case HASH_KEY_IS_STRING:
                ZVAL_STRINGL(endval, str_index, str_len - 1, 1);
                zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &endval, sizeof(zval *), NULL);
            break;
            case HASH_KEY_IS_LONG:
                ZVAL_LONG(endval, num_index);
                zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &endval, sizeof(zval *), NULL);
            break;
        }
    zend_hash_move_forward_ex(&pobj->values, &pos);
    }
}

PHP_METHOD(Pimple, factory)
{
    zval *factory       = NULL;
    pimple_object *pobj = NULL;
    pimple_bucket_value bucket = {0};

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &factory) == FAILURE) {
        return;
    }

    if (pimple_zval_is_valid_callback(factory, &bucket TSRMLS_CC) == FAILURE) {
        pimple_free_bucket(&bucket);
        zend_throw_exception(spl_ce_InvalidArgumentException, "Service definition is not a Closure or invokable object.", 0 TSRMLS_CC);
        return;
    }

    pimple_zval_to_pimpleval(factory, &bucket TSRMLS_CC);
    pobj = (pimple_object *)zend_object_store_get_object(getThis() TSRMLS_CC);

    if (zend_hash_index_update(&pobj->factories, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL) == SUCCESS) {
        Z_ADDREF_P(factory);
        RETURN_ZVAL(factory, 1 , 0);
    } else {
        pimple_free_bucket(&bucket);
    }

    RETURN_FALSE;
}

PHP_METHOD(Pimple, offsetSet)
{
    zval *offset = NULL, *value = NULL;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &offset, &value) == FAILURE) {
        return;
    }

    pimple_object_write_dimension(getThis(), offset, value TSRMLS_CC);
}

PHP_METHOD(Pimple, offsetGet)
{
    zval *offset = NULL, *retval = NULL;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
        return;
    }

    retval = pimple_object_read_dimension(getThis(), offset, 0 TSRMLS_CC);

    RETVAL_ZVAL(retval, 1, 0);
}

PHP_METHOD(Pimple, offsetUnset)
{
    zval *offset = NULL;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
        return;
    }

    pimple_object_unset_dimension(getThis(), offset TSRMLS_CC);
}

PHP_METHOD(Pimple, offsetExists)
{
    zval *offset = NULL;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) {
        return;
    }

    RETVAL_BOOL(pimple_object_has_dimension(getThis(), offset, 1 TSRMLS_CC));
}

PHP_METHOD(Pimple, register)
{
    zval *provider;
    zval **data;
    zval *retval = NULL;
    zval key;

    HashTable *array = NULL;
    HashPosition pos;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|h", &provider, pimple_serviceprovider_ce, &array) == FAILURE) {
        return;
    }

    RETVAL_ZVAL(getThis(), 1, 0);

    zend_call_method_with_1_params(&provider, Z_OBJCE_P(provider), NULL, "register", &retval, getThis());

    if (retval) {
        zval_ptr_dtor(&retval);
    }

    if (!array) {
        return;
    }

    zend_hash_internal_pointer_reset_ex(array, &pos);

    while(zend_hash_get_current_data_ex(array, (void **)&data, &pos) == SUCCESS) {
        zend_hash_get_current_key_zval_ex(array, &key, &pos);
        pimple_object_write_dimension(getThis(), &key, *data TSRMLS_CC);
        zend_hash_move_forward_ex(array, &pos);
    }
}

PHP_METHOD(Pimple, __construct)
{
    zval *values = NULL, **pData = NULL, offset;
    HashPosition pos;
    char *str_index = NULL;
    zend_uint str_length;
    ulong num_index;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &values) == FAILURE || !values) {
        return;
    }

    zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos);
    while (zend_hash_has_more_elements_ex(Z_ARRVAL_P(values), &pos) == SUCCESS) {
            zend_hash_get_current_data_ex(Z_ARRVAL_P(values), (void **)&pData, &pos);
            zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &str_index, &str_length, &num_index, 0, &pos);
            INIT_ZVAL(offset);
            if (zend_hash_get_current_key_type_ex(Z_ARRVAL_P(values), &pos) == HASH_KEY_IS_LONG) {
                ZVAL_LONG(&offset, num_index);
            } else {
                ZVAL_STRINGL(&offset, str_index, (str_length - 1), 0);
            }
        pimple_object_write_dimension(getThis(), &offset, *pData TSRMLS_CC);
        zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos);
    }
}

/*
 * This is PHP code snippet handling extend()s calls :

  $extended = function ($c) use ($callable, $factory) {
      return $callable($factory($c), $c);
  };

 */
PHP_METHOD(PimpleClosure, invoker)
{
    pimple_closure_object *pcobj = NULL;
    zval *arg = NULL, *retval = NULL, *newretval = NULL;
    zend_fcall_info fci        = {0};
    zval **args[2];

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) {
        return;
    }

    pcobj = zend_object_store_get_object(getThis() TSRMLS_CC);

    fci.function_name = pcobj->factory;
    args[0] = &arg;
    zend_fcall_info_argp(&fci TSRMLS_CC, 1, args);
    fci.retval_ptr_ptr = &retval;
    fci.size = sizeof(fci);

    if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE || EG(exception)) {
        efree(fci.params);
        return; /* Should here return default zval */
    }

    efree(fci.params);
    memset(&fci, 0, sizeof(fci));
    fci.size = sizeof(fci);

    fci.function_name = pcobj->callable;
    args[0] = &retval;
    args[1] = &arg;
    zend_fcall_info_argp(&fci TSRMLS_CC, 2, args);
    fci.retval_ptr_ptr = &newretval;

    if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE || EG(exception)) {
        efree(fci.params);
        zval_ptr_dtor(&retval);
        return;
    }

    efree(fci.params);
    zval_ptr_dtor(&retval);

    RETVAL_ZVAL(newretval, 1 ,1);
}

PHP_MINIT_FUNCTION(pimple)
{
    zend_class_entry tmp_pimple_ce, tmp_pimple_closure_ce, tmp_pimple_serviceprovider_iface_ce;
    INIT_NS_CLASS_ENTRY(tmp_pimple_ce, PIMPLE_NS, "Container", pimple_ce_functions);
    INIT_NS_CLASS_ENTRY(tmp_pimple_closure_ce, PIMPLE_NS, "ContainerClosure", NULL);
    INIT_NS_CLASS_ENTRY(tmp_pimple_serviceprovider_iface_ce, PIMPLE_NS, "ServiceProviderInterface", pimple_serviceprovider_iface_ce_functions);

    tmp_pimple_ce.create_object         = pimple_object_create;
    tmp_pimple_closure_ce.create_object = pimple_closure_object_create;

    pimple_ce = zend_register_internal_class(&tmp_pimple_ce TSRMLS_CC);
    zend_class_implements(pimple_ce TSRMLS_CC, 1, zend_ce_arrayaccess);

    pimple_closure_ce = zend_register_internal_class(&tmp_pimple_closure_ce TSRMLS_CC);
    pimple_closure_ce->ce_flags |= ZEND_ACC_FINAL_CLASS;

    pimple_serviceprovider_ce = zend_register_internal_interface(&tmp_pimple_serviceprovider_iface_ce TSRMLS_CC);

    memcpy(&pimple_closure_object_handlers, zend_get_std_object_handlers(), sizeof(*zend_get_std_object_handlers()));
    pimple_object_handlers                     = std_object_handlers;
    pimple_closure_object_handlers.get_closure = pimple_closure_get_closure;

    pimple_closure_invoker_function.function_name     = "Pimple closure internal invoker";
    pimple_closure_invoker_function.fn_flags         |= ZEND_ACC_CLOSURE;
    pimple_closure_invoker_function.handler           = ZEND_MN(PimpleClosure_invoker);
    pimple_closure_invoker_function.num_args          = 1;
    pimple_closure_invoker_function.required_num_args = 1;
    pimple_closure_invoker_function.scope             = pimple_closure_ce;
    pimple_closure_invoker_function.type              = ZEND_INTERNAL_FUNCTION;
    pimple_closure_invoker_function.module            = &pimple_module_entry;

    return SUCCESS;
}

PHP_MINFO_FUNCTION(pimple)
{
    php_info_print_table_start();
    php_info_print_table_header(2, "SensioLabs Pimple C support", "enabled");
    php_info_print_table_row(2, "Pimple supported version", PIMPLE_VERSION);
    php_info_print_table_end();

    php_info_print_box_start(0);
    php_write((void *)ZEND_STRL("SensioLabs Pimple C support developed by Julien Pauli") TSRMLS_CC);
    if (!sapi_module.phpinfo_as_text) {
        php_write((void *)ZEND_STRL(sensiolabs_logo) TSRMLS_CC);
    }
    php_info_print_box_end();
}

zend_module_entry pimple_module_entry = {
    STANDARD_MODULE_HEADER,
    "pimple",
    NULL,
    PHP_MINIT(pimple),
    NULL,
    NULL,
    NULL,
    PHP_MINFO(pimple),
    PIMPLE_VERSION,
    STANDARD_MODULE_PROPERTIES
};

#ifdef COMPILE_DL_PIMPLE
ZEND_GET_MODULE(pimple)
#endif

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.1 [PHP 8 Update] [02.02.2022] maintained byC99Shell Github | Generation time: 0.33 ]--