Skip to content

Commit 77172c2

Browse files
kocsismatenikic
authored andcommitted
Convert resources to objects in ext/sockets
Closes GH-5900.
1 parent e0fa48f commit 77172c2

36 files changed

+618
-531
lines changed

ext/posix/tests/posix_ttyname_error_wrongparams.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ PHP Testfest Berlin 2009-05-10
2020
<?php
2121
var_dump(posix_ttyname(0)); // param not a resource
2222
try {
23-
var_dump(posix_ttyname(socket_create(AF_INET, SOCK_DGRAM, SOL_UDP))); // wrong resource type
23+
var_dump(posix_ttyname(finfo_open(FILEINFO_NONE, __DIR__))); // wrong resource type
2424
} catch (TypeError $e) {
2525
echo $e->getMessage(), "\n";
2626
}

ext/sockets/conversions.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,29 +1341,32 @@ static void from_zval_write_fd_array_aux(zval *elem, unsigned i, void **args, se
13411341
{
13421342
int *iarr = args[0];
13431343

1344-
if (Z_TYPE_P(elem) == IS_RESOURCE) {
1345-
php_stream *stream;
1346-
php_socket *sock;
1347-
1348-
sock = (php_socket *)zend_fetch_resource_ex(elem, NULL, php_sockets_le_socket());
1349-
if (sock) {
1350-
iarr[i] = sock->bsd_socket;
1344+
if (Z_TYPE_P(elem) == IS_OBJECT && Z_OBJCE_P(elem) == socket_ce) {
1345+
php_socket *sock = Z_SOCKET_P(elem);
1346+
if (IS_INVALID_SOCKET(sock)) {
1347+
do_from_zval_err(ctx, "socket is already closed");
13511348
return;
13521349
}
13531350

1351+
iarr[i] = sock->bsd_socket;
1352+
return;
1353+
}
1354+
1355+
if (Z_TYPE_P(elem) == IS_RESOURCE) {
1356+
php_stream *stream;
1357+
13541358
stream = (php_stream *)zend_fetch_resource2_ex(elem, NULL, php_file_le_stream(), php_file_le_pstream());
13551359
if (stream == NULL) {
1356-
do_from_zval_err(ctx, "resource is not a stream or a socket");
1360+
do_from_zval_err(ctx, "resource is not a stream");
13571361
return;
13581362
}
13591363

1360-
if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&iarr[i - 1],
1361-
REPORT_ERRORS) == FAILURE) {
1364+
if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&iarr[i - 1], REPORT_ERRORS) == FAILURE) {
13621365
do_from_zval_err(ctx, "cast stream to file descriptor failed");
13631366
return;
13641367
}
13651368
} else {
1366-
do_from_zval_err(ctx, "expected a resource variable");
1369+
do_from_zval_err(ctx, "expected a Socket object or a stream resource");
13671370
}
13681371
}
13691372
void from_zval_write_fd_array(const zval *arr, char *int_arr, ser_context *ctx)
@@ -1414,8 +1417,10 @@ void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx)
14141417
return;
14151418
}
14161419
if (S_ISSOCK(statbuf.st_mode)) {
1417-
php_socket *sock = socket_import_file_descriptor(fd);
1418-
ZVAL_RES(&elem, zend_register_resource(sock, php_sockets_le_socket()));
1420+
object_init_ex(&elem, socket_ce);
1421+
php_socket *sock = Z_SOCKET_P(&elem);
1422+
1423+
socket_import_file_descriptor(fd, sock);
14191424
} else {
14201425
php_stream *stream = php_stream_fopen_from_fd(fd, "rw", NULL);
14211426
php_stream_to_zval(stream, &elem);

ext/sockets/php_sockets.h

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#include <php.h>
3030
#ifdef PHP_WIN32
3131
# include "windows_common.h"
32+
#else
33+
# define IS_INVALID_SOCKET(a) (a->bsd_socket < 0)
3234
#endif
3335

3436
#define PHP_SOCKETS_VERSION PHP_VERSION
@@ -52,29 +54,39 @@ typedef int PHP_SOCKET;
5254
typedef SOCKET PHP_SOCKET;
5355
#endif
5456

57+
/* Socket class */
58+
5559
typedef struct {
5660
PHP_SOCKET bsd_socket;
5761
int type;
5862
int error;
5963
int blocking;
6064
zval zstream;
65+
zend_object std;
6166
} php_socket;
6267

68+
extern zend_class_entry *socket_ce;
69+
70+
static inline php_socket *socket_from_obj(zend_object *obj) {
71+
return (php_socket *)((char *)(obj) - XtOffsetOf(php_socket, std));
72+
}
73+
74+
#define Z_SOCKET_P(zv) socket_from_obj(Z_OBJ_P(zv))
75+
76+
#define ENSURE_SOCKET_VALID(php_sock) do { \
77+
if (IS_INVALID_SOCKET(php_sock)) { \
78+
zend_argument_error(NULL, 1, "has already been closed"); \
79+
RETURN_THROWS(); \
80+
} \
81+
} while (0)
82+
6383
#ifdef PHP_WIN32
6484
struct sockaddr_un {
6585
short sun_family;
6686
char sun_path[108];
6787
};
6888
#endif
6989

70-
PHP_SOCKETS_API int php_sockets_le_socket(void);
71-
PHP_SOCKETS_API php_socket *php_create_socket(void);
72-
PHP_SOCKETS_API void php_destroy_socket(zend_resource *rsrc);
73-
PHP_SOCKETS_API void php_destroy_sockaddr(zend_resource *rsrc);
74-
75-
#define php_sockets_le_socket_name "Socket"
76-
#define php_sockets_le_addrinfo_name "AddressInfo"
77-
7890
#define PHP_SOCKET_ERROR(socket, msg, errn) \
7991
do { \
8092
int _err = (errn); /* save value to avoid repeated calls to WSAGetLastError() on Windows */ \
@@ -104,7 +116,7 @@ enum sockopt_return {
104116
};
105117

106118
char *sockets_strerror(int error);
107-
php_socket *socket_import_file_descriptor(PHP_SOCKET sock);
119+
int socket_import_file_descriptor(PHP_SOCKET socket, php_socket *retsock);
108120

109121
#else
110122
#define phpext_sockets_ptr NULL

ext/sockets/sendrecvmsg.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -172,16 +172,14 @@ PHP_FUNCTION(socket_sendmsg)
172172
ssize_t res;
173173

174174
/* zmsg should be passed by ref */
175-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra|l", &zsocket, &zmsg, &flags) == FAILURE) {
175+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa|l", &zsocket, socket_ce, &zmsg, &flags) == FAILURE) {
176176
RETURN_THROWS();
177177
}
178178

179179
LONG_CHECK_VALID_INT(flags, 3);
180180

181-
if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(zsocket),
182-
php_sockets_le_socket_name, php_sockets_le_socket())) == NULL) {
183-
RETURN_THROWS();
184-
}
181+
php_sock = Z_SOCKET_P(zsocket);
182+
ENSURE_SOCKET_VALID(php_sock);
185183

186184
msghdr = from_zval_run_conversions(zmsg, php_sock, from_zval_write_msghdr_send,
187185
sizeof(*msghdr), "msghdr", &allocations, &err);
@@ -216,17 +214,14 @@ PHP_FUNCTION(socket_recvmsg)
216214
struct err_s err = {0};
217215

218216
//ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
219-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ra|l",
220-
&zsocket, &zmsg, &flags) == FAILURE) {
217+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oa|l", &zsocket, socket_ce, &zmsg, &flags) == FAILURE) {
221218
RETURN_THROWS();
222219
}
223220

224221
LONG_CHECK_VALID_INT(flags, 3);
225222

226-
if ((php_sock = (php_socket *)zend_fetch_resource(Z_RES_P(zsocket),
227-
php_sockets_le_socket_name, php_sockets_le_socket())) == NULL) {
228-
RETURN_THROWS();
229-
}
223+
php_sock = Z_SOCKET_P(zsocket);
224+
ENSURE_SOCKET_VALID(php_sock);
230225

231226
msghdr = from_zval_run_conversions(zmsg, php_sock, from_zval_write_msghdr_recv,
232227
sizeof(*msghdr), "msghdr", &allocations, &err);

0 commit comments

Comments
 (0)