Skip to content

Commit b4fb579

Browse files
NattyNarwhalcharmitro
authored andcommitted
Fix FD getting code on big endian (php#17259)
* Fix FD getting code on big endian (PHP 8.3) stream casting as FD returns a php_socket_t, which is an int, but zend_long is 64-bit (on those platforms). This works on LE by accidental (unless it forgets to clear the high word), but is fatal on big endian. * change cast to match sig
1 parent a689978 commit b4fb579

File tree

1 file changed

+23
-20
lines changed

1 file changed

+23
-20
lines changed

ext/posix/posix.c

+23-20
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
*/
1616

1717
#ifdef HAVE_CONFIG_H
18-
#include <config.h>
18+
#include "config.h"
1919
#endif
2020

2121
#include "php.h"
2222
#include <unistd.h>
2323
#include "ext/standard/info.h"
24+
#include "ext/standard/php_string.h"
2425
#include "php_posix.h"
26+
#include "main/php_network.h"
2527

2628
#ifdef HAVE_POSIX
2729

@@ -38,9 +40,10 @@
3840
#include <errno.h>
3941
#include <grp.h>
4042
#include <pwd.h>
41-
#ifdef MAJOR_IN_MKDEV
43+
#ifdef HAVE_SYS_MKDEV_H
4244
# include <sys/mkdev.h>
43-
#elif defined(MAJOR_IN_SYSMACROS)
45+
#endif
46+
#ifdef HAVE_SYS_SYSMACROS_H
4447
# include <sys/sysmacros.h>
4548
#endif
4649

@@ -356,7 +359,7 @@ PHP_FUNCTION(posix_uname)
356359
add_assoc_string(return_value, "version", u.version);
357360
add_assoc_string(return_value, "machine", u.machine);
358361

359-
#if defined(_GNU_SOURCE) && defined(HAVE_STRUCT_UTSNAME_DOMAINNAME)
362+
#if defined(_GNU_SOURCE) && !defined(DARWIN) && defined(HAVE_UTSNAME_DOMAINNAME)
360363
add_assoc_string(return_value, "domainname", u.domainname);
361364
#endif
362365
}
@@ -415,30 +418,32 @@ PHP_FUNCTION(posix_ctermid)
415418
/* }}} */
416419

417420
/* Checks if the provides resource is a stream and if it provides a file descriptor */
418-
static zend_result php_posix_stream_get_fd(zval *zfp, zend_long *fd) /* {{{ */
421+
static int php_posix_stream_get_fd(zval *zfp, zend_long *ret) /* {{{ */
419422
{
420423
php_stream *stream;
421424

422425
php_stream_from_zval_no_verify(stream, zfp);
423426

424427
if (stream == NULL) {
425-
return FAILURE;
428+
return 0;
426429
}
427430

428-
/* get the fd.
431+
/* get the fd. php_socket_t is used for FDs, and is shorter than zend_long.
429432
* NB: Most other code will NOT use the PHP_STREAM_CAST_INTERNAL flag when casting.
430433
* It is only used here so that the buffered data warning is not displayed.
431434
*/
435+
php_socket_t fd = -1;
432436
if (php_stream_can_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL) == SUCCESS) {
433-
php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)fd, 0);
437+
php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void**)&fd, 0);
434438
} else if (php_stream_can_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL) == SUCCESS) {
435-
php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void*)fd, 0);
439+
php_stream_cast(stream, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void**)&fd, 0);
436440
} else {
437441
php_error_docref(NULL, E_WARNING, "Could not use stream of type '%s'",
438442
stream->ops->label);
439-
return FAILURE;
443+
return 0;
440444
}
441-
return SUCCESS;
445+
*ret = fd;
446+
return 1;
442447
}
443448
/* }}} */
444449

@@ -458,7 +463,7 @@ PHP_FUNCTION(posix_ttyname)
458463
ZEND_PARSE_PARAMETERS_END();
459464

460465
if (Z_TYPE_P(z_fd) == IS_RESOURCE) {
461-
if (php_posix_stream_get_fd(z_fd, &fd) == FAILURE) {
466+
if (!php_posix_stream_get_fd(z_fd, &fd)) {
462467
RETURN_FALSE;
463468
}
464469
} else {
@@ -519,7 +524,7 @@ PHP_FUNCTION(posix_isatty)
519524
ZEND_PARSE_PARAMETERS_END();
520525

521526
if (Z_TYPE_P(z_fd) == IS_RESOURCE) {
522-
if (php_posix_stream_get_fd(z_fd, &fd) == FAILURE) {
527+
if (!php_posix_stream_get_fd(z_fd, &fd)) {
523528
RETURN_FALSE;
524529
}
525530
} else {
@@ -532,13 +537,11 @@ PHP_FUNCTION(posix_isatty)
532537

533538
/* A valid file descriptor must fit in an int and be positive */
534539
if (fd < 0 || fd > INT_MAX) {
535-
POSIX_G(last_error) = EBADF;
536540
RETURN_FALSE;
537541
}
538542
if (isatty(fd)) {
539543
RETURN_TRUE;
540544
} else {
541-
POSIX_G(last_error) = errno;
542545
RETURN_FALSE;
543546
}
544547
}
@@ -632,7 +635,7 @@ PHP_FUNCTION(posix_mknod)
632635
zend_argument_value_error(3, "cannot be 0 for the POSIX_S_IFCHR and POSIX_S_IFBLK modes");
633636
RETURN_THROWS();
634637
} else {
635-
#ifdef HAVE_MAKEDEV
638+
#if defined(HAVE_MAKEDEV) || defined(makedev)
636639
php_dev = makedev(major, minor);
637640
#else
638641
php_error_docref(NULL, E_WARNING, "Cannot create a block or character device, creating a normal file instead");
@@ -746,7 +749,7 @@ PHP_FUNCTION(posix_eaccess)
746749

747750
path = expand_filepath(filename, NULL);
748751
if (!path) {
749-
zend_argument_must_not_be_empty_error(1);
752+
zend_argument_value_error(1, "cannot be empty");
750753
RETURN_THROWS();
751754
}
752755

@@ -1043,7 +1046,7 @@ PHP_FUNCTION(posix_getpwuid)
10431046
#define UNLIMITED_STRING "unlimited"
10441047

10451048
/* {{{ posix_addlimit */
1046-
static zend_result posix_addlimit(int limit, const char *name, zval *return_value) {
1049+
static int posix_addlimit(int limit, const char *name, zval *return_value) {
10471050
int result;
10481051
struct rlimit rl;
10491052
char hard[80];
@@ -1285,7 +1288,7 @@ PHP_FUNCTION(posix_pathconf)
12851288
ZEND_PARSE_PARAMETERS_END();
12861289

12871290
if (path_len == 0) {
1288-
zend_argument_must_not_be_empty_error(1);
1291+
zend_argument_value_error(1, "cannot be empty");
12891292
RETURN_THROWS();
12901293
} else if (php_check_open_basedir(path)) {
12911294
php_error_docref(NULL, E_WARNING, "Invalid path supplied: %s", path);
@@ -1315,7 +1318,7 @@ PHP_FUNCTION(posix_fpathconf)
13151318
ZEND_PARSE_PARAMETERS_END();
13161319

13171320
if (Z_TYPE_P(z_fd) == IS_RESOURCE) {
1318-
if (php_posix_stream_get_fd(z_fd, &fd) == FAILURE) {
1321+
if (!php_posix_stream_get_fd(z_fd, &fd)) {
13191322
RETURN_FALSE;
13201323
}
13211324
} else {

0 commit comments

Comments
 (0)