Skip to content

Commit

Permalink
Migrate SOAP SDL resource to object
Browse files Browse the repository at this point in the history
  • Loading branch information
kocsismate committed May 7, 2024
1 parent 44e7537 commit 46b49b0
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 34 deletions.
2 changes: 2 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ PHP 8.4 UPGRADE NOTES
- SOAP:
. SoapClient::$httpurl is now a Soap\Url object rather than a resource.
Value checks using is_resource() should be replaced with checks for `null`.
. SoapClient::$sdl is now a Soap\Sdl object rather than a resource.
Value checks using is_resource() should be replaced with checks for `null`.

- SPL:
. Out of bounds accesses in SplFixedArray now throw an exception of type
Expand Down
8 changes: 3 additions & 5 deletions ext/soap/php_sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3449,12 +3449,10 @@ void delete_sdl_impl(void *handle)
efree(tmp);
}

void delete_sdl(void *handle)
void delete_sdl(sdl *handle)
{
sdlPtr tmp = (sdlPtr)handle;

if (!tmp->is_persistent) {
delete_sdl_impl(tmp);
if (!handle->is_persistent) {
delete_sdl_impl(handle);
}
}

Expand Down
2 changes: 1 addition & 1 deletion ext/soap/php_sdl.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ encodePtr get_encoder_ex(sdlPtr sdl, const char *nscat, int len);
sdlBindingPtr get_binding_from_type(sdlPtr sdl, sdlBindingType type);
sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns);

void delete_sdl(void *handle);
void delete_sdl(sdl *handle);
void delete_sdl_impl(void *handle);

void sdl_set_uri_credentials(sdlCtx *ctx, char *uri);
Expand Down
7 changes: 7 additions & 0 deletions ext/soap/php_soap.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ ZEND_TSRMLS_CACHE_EXTERN()
extern zend_class_entry* soap_class_entry;
extern zend_class_entry* soap_var_class_entry;
extern zend_class_entry* soap_url_class_entry;
extern zend_class_entry* soap_sdl_class_entry;

void add_soap_fault(zval *obj, char *fault_code, char *fault_string, char *fault_actor, zval *fault_detail);

Expand Down Expand Up @@ -263,4 +264,10 @@ static inline soap_url_object *soap_url_object_fetch(zend_object *obj)
}

#define Z_SOAP_URL_P(zv) soap_url_object_fetch(Z_OBJ_P(zv))

typedef struct soap_sdl_object {
sdl *sdl;
zend_object std;
} soap_sdl_object;

#endif
95 changes: 71 additions & 24 deletions ext/soap/soap.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#include "ext/standard/php_incomplete_class.h"


static int le_sdl = 0;
static int le_typemap = 0;

typedef struct _soapHeader {
Expand Down Expand Up @@ -128,15 +127,13 @@ static void soap_error_handler(int error_num, zend_string *error_filename, const
#define FETCH_THIS_SDL(ss) \
{ \
zval *__tmp = Z_CLIENT_SDL_P(ZEND_THIS); \
if (Z_TYPE_P(__tmp) == IS_RESOURCE) { \
FETCH_SDL_RES(ss,__tmp); \
if (Z_TYPE_P(__tmp) == IS_OBJECT && instanceof_function(Z_OBJCE_P(__tmp), soap_sdl_class_entry)) { \
ss = Z_SOAP_SDL_P(__tmp)->sdl; \
} else { \
ss = NULL; \
} \
}

#define FETCH_SDL_RES(ss,tmp) ss = (sdlPtr) zend_fetch_resource_ex(tmp, "sdl", le_sdl)

#define FETCH_TYPEMAP_RES(ss,tmp) ss = (HashTable*) zend_fetch_resource_ex(tmp, "typemap", le_typemap)

#define Z_PARAM_NAME_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 0))
Expand Down Expand Up @@ -177,9 +174,11 @@ static zend_class_entry* soap_header_class_entry;
static zend_class_entry* soap_param_class_entry;
zend_class_entry* soap_var_class_entry;
zend_class_entry *soap_url_class_entry;
zend_class_entry *soap_sdl_class_entry;

static zend_object_handlers soap_server_object_handlers;
static zend_object_handlers soap_url_object_handlers;
static zend_object_handlers soap_sdl_object_handlers;

typedef struct {
soapServicePtr service;
Expand Down Expand Up @@ -234,6 +233,43 @@ static zend_function *soap_url_object_get_constructor(zend_object *object)

return NULL;
}

static inline soap_sdl_object *soap_sdl_object_fetch(zend_object *obj)
{
return (soap_sdl_object *) ((char *) obj - XtOffsetOf(soap_sdl_object, std));
}

#define Z_SOAP_SDL_P(zv) soap_sdl_object_fetch(Z_OBJ_P(zv))

static zend_object *soap_sdl_object_create(zend_class_entry *ce)
{
soap_sdl_object *sdl_obj = zend_object_alloc(sizeof(soap_sdl_object), ce);

zend_object_std_init(&sdl_obj->std, ce);
object_properties_init(&sdl_obj->std, ce);

return &sdl_obj->std;
}

static void soap_sdl_object_free(zend_object *obj)
{
soap_sdl_object *sdl_obj = soap_sdl_object_fetch(obj);

if (sdl_obj->sdl) {
delete_sdl(sdl_obj->sdl);
sdl_obj->sdl = NULL;
}

zend_object_std_dtor(&sdl_obj->std);
}

static zend_function *soap_sdl_object_get_constructor(zend_object *object)
{
zend_throw_error(NULL, "Cannot directly construct Soap\\Sdl");

return NULL;
}

ZEND_DECLARE_MODULE_GLOBALS(soap)

static void (*old_error_handler)(int, zend_string *, const uint32_t, zend_string *);
Expand Down Expand Up @@ -418,11 +454,6 @@ PHP_RINIT_FUNCTION(soap)
return SUCCESS;
}

static void delete_sdl_res(zend_resource *res)
{
delete_sdl(res->ptr);
}

static void delete_hashtable_res(zend_resource *res)
{
delete_hashtable(res->ptr);
Expand Down Expand Up @@ -458,7 +489,6 @@ PHP_MINIT_FUNCTION(soap)

soap_header_class_entry = register_class_SoapHeader();

le_sdl = zend_register_list_destructors_ex(delete_sdl_res, NULL, "SOAP SDL", module_number);
le_typemap = zend_register_list_destructors_ex(delete_hashtable_res, NULL, "SOAP table", module_number);

soap_url_class_entry = register_class_Soap_Url();
Expand All @@ -472,6 +502,17 @@ PHP_MINIT_FUNCTION(soap)
soap_url_object_handlers.clone_obj = NULL;
soap_url_object_handlers.compare = zend_objects_not_comparable;

soap_sdl_class_entry = register_class_Soap_Sdl();
soap_sdl_class_entry->create_object = soap_sdl_object_create;
soap_sdl_class_entry->default_object_handlers = &soap_sdl_object_handlers;

memcpy(&soap_sdl_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
soap_sdl_object_handlers.offset = XtOffsetOf(soap_sdl_object, std);
soap_sdl_object_handlers.free_obj = soap_sdl_object_free;
soap_sdl_object_handlers.get_constructor = soap_sdl_object_get_constructor;
soap_sdl_object_handlers.clone_obj = NULL;
soap_sdl_object_handlers.compare = zend_objects_not_comparable;

register_soap_symbols(module_number);

old_error_handler = zend_error_cb;
Expand Down Expand Up @@ -2086,15 +2127,20 @@ PHP_METHOD(SoapClient, __construct)

if (wsdl) {
int old_soap_version;
zend_resource *res;

old_soap_version = SOAP_GLOBAL(soap_version);
SOAP_GLOBAL(soap_version) = soap_version;

sdl = get_sdl(this_ptr, ZSTR_VAL(wsdl), cache_wsdl);
res = zend_register_resource(sdl, le_sdl);

ZVAL_RES(Z_CLIENT_SDL_P(this_ptr), res);
zval *sdl_zval = Z_CLIENT_SDL_P(this_ptr);
if (Z_TYPE_P(sdl_zval) == IS_OBJECT) {
zval_ptr_dtor(sdl_zval);
}

object_init_ex(sdl_zval, soap_sdl_class_entry);
soap_sdl_object *sdl_object = Z_SOAP_SDL_P(sdl_zval);
sdl_object->sdl = sdl;

SOAP_GLOBAL(soap_version) = old_soap_version;
}
Expand Down Expand Up @@ -2227,8 +2273,11 @@ static void do_soap_call(zend_execute_data *execute_data,
}

tmp = Z_CLIENT_SDL_P(this_ptr);
if (Z_TYPE_P(tmp) == IS_RESOURCE) {
FETCH_SDL_RES(sdl,tmp);
if (Z_TYPE_P(tmp) == IS_OBJECT) {
#ifdef ZEND_DEBUG
ZEND_ASSERT(instanceof_function(Z_OBJCE_P(tmp), soap_sdl_class_entry));
#endif
sdl = Z_SOAP_SDL_P(tmp)->sdl;
}

tmp = Z_CLIENT_TYPEMAP_P(this_ptr);
Expand Down Expand Up @@ -2536,14 +2585,13 @@ PHP_METHOD(SoapClient, __soapCall)
/* {{{ Returns list of SOAP functions */
PHP_METHOD(SoapClient, __getFunctions)
{
sdlPtr sdl;

FETCH_THIS_SDL(sdl);

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

sdl *sdl;
FETCH_THIS_SDL(sdl);

if (sdl) {
smart_str buf = {0};
sdlFunctionPtr function;
Expand All @@ -2562,14 +2610,13 @@ PHP_METHOD(SoapClient, __getFunctions)
/* {{{ Returns list of SOAP types */
PHP_METHOD(SoapClient, __getTypes)
{
sdlPtr sdl;

FETCH_THIS_SDL(sdl);

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

sdl *sdl;
FETCH_THIS_SDL(sdl);

if (sdl) {
sdlTypePtr type;
smart_str buf = {0};
Expand Down
11 changes: 9 additions & 2 deletions ext/soap/soap.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@
final class Url
{
}

/**
* @strict-properties
* @not-serializable
*/
final class Sdl
{
}
}

namespace {
Expand Down Expand Up @@ -528,8 +536,7 @@ class SoapClient
private ?string $location = null;
private bool $trace = false;
private ?int $compression = null;
/** @var resource|null */
private $sdl = null;
private ?Soap\Sdl $sdl = null;
/** @var resource|null */
private $typemap = null;
/** @var resource|null */
Expand Down
20 changes: 18 additions & 2 deletions ext/soap/soap_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 46b49b0

Please sign in to comment.