Skip to content

Commit c5d6f59

Browse files
committed
Use custom object instead of resource for soap server service
The "service" resource is a purely internal structure used by SoapServer, which userland code cannot interact with. Instead of storing it as a resource in an object propperty, use a custom object structure instead.
1 parent f0dd79a commit c5d6f59

File tree

3 files changed

+39
-25
lines changed

3 files changed

+39
-25
lines changed

ext/soap/soap.c

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131
static int le_sdl = 0;
3232
int le_url = 0;
33-
static int le_service = 0;
3433
static int le_typemap = 0;
3534

3635
typedef struct _soapHeader {
@@ -150,8 +149,7 @@ static void soap_error_handler(int error_num, zend_string *error_filename, const
150149
#define Z_HEADER_MUST_UNDERSTAND_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 3))
151150
#define Z_HEADER_ACTOR_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 4))
152151

153-
#define Z_SERVER_SERVICE_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 0))
154-
#define Z_SERVER_SOAP_FAULT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 1))
152+
#define Z_SERVER_SOAP_FAULT_P(zv) php_soap_deref(OBJ_PROP_NUM(Z_OBJ_P(zv), 0))
155153

156154
/* SoapFault extends Exception, so take those properties into account. */
157155
#define FAULT_PROP_START_OFFSET zend_ce_exception->default_properties_count
@@ -165,8 +163,7 @@ static void soap_error_handler(int error_num, zend_string *error_filename, const
165163

166164
#define FETCH_THIS_SERVICE(ss) \
167165
{ \
168-
zval *tmp = Z_SERVER_SERVICE_P(ZEND_THIS); \
169-
ss = (soapServicePtr)zend_fetch_resource_ex(tmp, "service", le_service); \
166+
ss = soap_server_object_fetch(Z_OBJ_P(ZEND_THIS))->service; \
170167
if (!ss) { \
171168
zend_throw_error(NULL, "Cannot fetch SoapServer object"); \
172169
SOAP_SERVER_END_CODE(); \
@@ -181,6 +178,34 @@ static zend_class_entry* soap_header_class_entry;
181178
static zend_class_entry* soap_param_class_entry;
182179
zend_class_entry* soap_var_class_entry;
183180

181+
static zend_object_handlers soap_server_object_handlers;
182+
183+
typedef struct {
184+
soapServicePtr service;
185+
zend_object std;
186+
} soap_server_object;
187+
188+
static inline soap_server_object *soap_server_object_fetch(zend_object *obj) {
189+
return (soap_server_object *) ((char *) obj - XtOffsetOf(soap_server_object, std));
190+
}
191+
192+
static zend_object *soap_server_object_create(zend_class_entry *ce)
193+
{
194+
soap_server_object *obj = zend_object_alloc(sizeof(soap_server_object), ce);
195+
zend_object_std_init(&obj->std, ce);
196+
object_properties_init(&obj->std, ce);
197+
obj->std.handlers = &soap_server_object_handlers;
198+
return &obj->std;
199+
}
200+
201+
static void soap_server_object_free(zend_object *obj) {
202+
soap_server_object *server_obj = soap_server_object_fetch(obj);
203+
if (server_obj->service) {
204+
delete_service(server_obj->service);
205+
}
206+
zend_object_std_dtor(obj);
207+
}
208+
184209
ZEND_DECLARE_MODULE_GLOBALS(soap)
185210

186211
static void (*old_error_handler)(int, zend_string *, const uint32_t, zend_string *);
@@ -361,11 +386,6 @@ static void delete_url_res(zend_resource *res)
361386
delete_url(res->ptr);
362387
}
363388

364-
static void delete_service_res(zend_resource *res)
365-
{
366-
delete_service(res->ptr);
367-
}
368-
369389
static void delete_hashtable_res(zend_resource *res)
370390
{
371391
delete_hashtable(res->ptr);
@@ -386,6 +406,11 @@ PHP_MINIT_FUNCTION(soap)
386406

387407
/* Register SoapServer class */
388408
soap_server_class_entry = register_class_SoapServer();
409+
soap_server_class_entry->create_object = soap_server_object_create;
410+
411+
memcpy(&soap_server_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
412+
soap_server_object_handlers.offset = XtOffsetOf(soap_server_object, std);
413+
soap_server_object_handlers.free_obj = soap_server_object_free;
389414

390415
/* Register SoapFault class */
391416
soap_fault_class_entry = register_class_SoapFault(zend_ce_exception);
@@ -397,7 +422,6 @@ PHP_MINIT_FUNCTION(soap)
397422

398423
le_sdl = zend_register_list_destructors_ex(delete_sdl_res, NULL, "SOAP SDL", module_number);
399424
le_url = zend_register_list_destructors_ex(delete_url_res, NULL, "SOAP URL", module_number);
400-
le_service = zend_register_list_destructors_ex(delete_service_res, NULL, "SOAP service", module_number);
401425
le_typemap = zend_register_list_destructors_ex(delete_hashtable_res, NULL, "SOAP table", module_number);
402426

403427
REGISTER_LONG_CONSTANT("SOAP_1_1", SOAP_1_1, CONST_CS | CONST_PERSISTENT);
@@ -832,7 +856,6 @@ PHP_METHOD(SoapServer, __construct)
832856
soapServicePtr service;
833857
zval *options = NULL;
834858
zend_string *wsdl;
835-
zend_resource *res;
836859
int version = SOAP_1_1;
837860
zend_long cache_wsdl;
838861
HashTable *typemap_ht = NULL;
@@ -942,8 +965,8 @@ PHP_METHOD(SoapServer, __construct)
942965
service->typemap = soap_create_typemap(service->sdl, typemap_ht);
943966
}
944967

945-
res = zend_register_resource(service, le_service);
946-
ZVAL_RES(Z_SERVER_SERVICE_P(ZEND_THIS), res);
968+
soap_server_object *server_obj = soap_server_object_fetch(Z_OBJ_P(ZEND_THIS));
969+
server_obj->service = service;
947970

948971
SOAP_SERVER_END_CODE();
949972
}
@@ -1824,7 +1847,7 @@ static zend_never_inline ZEND_COLD void soap_real_error_handler(int error_num, z
18241847
}
18251848
if (Z_OBJ_P(error_object) &&
18261849
instanceof_function(Z_OBJCE_P(error_object), soap_server_class_entry) &&
1827-
(service = (soapServicePtr)zend_fetch_resource_ex(Z_SERVER_SERVICE_P(error_object), "service", le_service)) &&
1850+
(service = soap_server_object_fetch(Z_OBJ_P(error_object))->service) &&
18281851
!service->send_errors) {
18291852
buffer = zend_string_init("Internal Error", sizeof("Internal Error")-1, 0);
18301853
} else {

ext/soap/soap.stub.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ public function __construct(mixed $data, ?int $encoding, ?string $typeName = nul
5454

5555
class SoapServer
5656
{
57-
/** @var resource */
58-
private $service;
59-
6057
private ?SoapFault $__soap_fault = null;
6158

6259
public function __construct(?string $wsdl, array $options = []) {}

ext/soap/soap_arginfo.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: ab057422ee42f574e7d00462f3bf173caf14ecc1 */
2+
* Stub hash: 96c82014f1fe922cee14d0cd55dd14a6ba3ffe5f */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_use_soap_error_handler, 0, 0, _IS_BOOL, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, enable, _IS_BOOL, 0, "true")
@@ -400,12 +400,6 @@ static zend_class_entry *register_class_SoapServer(void)
400400
INIT_CLASS_ENTRY(ce, "SoapServer", class_SoapServer_methods);
401401
class_entry = zend_register_internal_class_ex(&ce, NULL);
402402

403-
zval property_service_default_value;
404-
ZVAL_NULL(&property_service_default_value);
405-
zend_string *property_service_name = zend_string_init("service", sizeof("service") - 1, 1);
406-
zend_declare_property_ex(class_entry, property_service_name, &property_service_default_value, ZEND_ACC_PRIVATE, NULL);
407-
zend_string_release(property_service_name);
408-
409403
zend_string *property___soap_fault_class_SoapFault = zend_string_init("SoapFault", sizeof("SoapFault")-1, 1);
410404
zval property___soap_fault_default_value;
411405
ZVAL_NULL(&property___soap_fault_default_value);

0 commit comments

Comments
 (0)