Skip to content

Commit 47f0a06

Browse files
committed
Merge branch 'PHP-8.3'
* PHP-8.3: [ci skip] NEWS [ci skip] NEWS Fix usage of reentrant functions in ext/posix (#13921)
2 parents 5d91f87 + e2e4e64 commit 47f0a06

File tree

1 file changed

+55
-23
lines changed

1 file changed

+55
-23
lines changed

ext/posix/posix.c

+55-23
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ PHP_FUNCTION(posix_ttyname)
451451
zend_long fd = 0;
452452
#if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
453453
zend_long buflen;
454+
int err;
454455
#endif
455456

456457
ZEND_PARSE_PARAMETERS_START(1, 1)
@@ -476,12 +477,23 @@ PHP_FUNCTION(posix_ttyname)
476477
#if defined(ZTS) && defined(HAVE_TTYNAME_R) && defined(_SC_TTY_NAME_MAX)
477478
buflen = sysconf(_SC_TTY_NAME_MAX);
478479
if (buflen < 1) {
479-
RETURN_FALSE;
480+
buflen = 32;
480481
}
482+
#if ZEND_DEBUG
483+
/* Test retry logic */
484+
buflen = 1;
485+
#endif
481486
p = emalloc(buflen);
482487

483-
if (ttyname_r(fd, p, buflen)) {
484-
POSIX_G(last_error) = errno;
488+
try_again:
489+
err = ttyname_r(fd, p, buflen);
490+
if (err) {
491+
if (err == ERANGE) {
492+
buflen *= 2;
493+
p = erealloc(p, buflen);
494+
goto try_again;
495+
}
496+
POSIX_G(last_error) = err;
485497
efree(p);
486498
RETURN_FALSE;
487499
}
@@ -776,6 +788,7 @@ PHP_FUNCTION(posix_getgrnam)
776788
struct group gbuf;
777789
long buflen;
778790
char *buf;
791+
int err;
779792
#endif
780793

781794
ZEND_PARSE_PARAMETERS_START(1, 1)
@@ -785,19 +798,24 @@ PHP_FUNCTION(posix_getgrnam)
785798
#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
786799
buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
787800
if (buflen < 1) {
788-
RETURN_FALSE;
801+
buflen = 1024;
789802
}
803+
#if ZEND_DEBUG
804+
/* Test retry logic */
805+
buflen = 1;
806+
#endif
790807
buf = emalloc(buflen);
791808
try_again:
792809
g = &gbuf;
793810

794-
if (getgrnam_r(name, g, buf, buflen, &g) || g == NULL) {
795-
if (errno == ERANGE) {
811+
err = getgrnam_r(name, g, buf, buflen, &g);
812+
if (err || g == NULL) {
813+
if (err == ERANGE) {
796814
buflen *= 2;
797815
buf = erealloc(buf, buflen);
798816
goto try_again;
799817
}
800-
POSIX_G(last_error) = errno;
818+
POSIX_G(last_error) = err;
801819
efree(buf);
802820
RETURN_FALSE;
803821
}
@@ -825,7 +843,7 @@ PHP_FUNCTION(posix_getgrgid)
825843
{
826844
zend_long gid;
827845
#if defined(ZTS) && defined(HAVE_GETGRGID_R) && defined(_SC_GETGR_R_SIZE_MAX)
828-
int ret;
846+
int err;
829847
struct group _g;
830848
struct group *retgrptr = NULL;
831849
long grbuflen;
@@ -841,20 +859,24 @@ PHP_FUNCTION(posix_getgrgid)
841859

842860
grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
843861
if (grbuflen < 1) {
844-
RETURN_FALSE;
862+
grbuflen = 1024;
845863
}
864+
#if ZEND_DEBUG
865+
/* Test retry logic */
866+
grbuflen = 1;
867+
#endif
846868

847869
grbuf = emalloc(grbuflen);
848870

849871
try_again:
850-
ret = getgrgid_r(gid, &_g, grbuf, grbuflen, &retgrptr);
851-
if (ret || retgrptr == NULL) {
852-
if (errno == ERANGE) {
872+
err = getgrgid_r(gid, &_g, grbuf, grbuflen, &retgrptr);
873+
if (err || retgrptr == NULL) {
874+
if (err == ERANGE) {
853875
grbuflen *= 2;
854876
grbuf = erealloc(grbuf, grbuflen);
855877
goto try_again;
856878
}
857-
POSIX_G(last_error) = ret;
879+
POSIX_G(last_error) = err;
858880
efree(grbuf);
859881
RETURN_FALSE;
860882
}
@@ -906,6 +928,7 @@ PHP_FUNCTION(posix_getpwnam)
906928
struct passwd pwbuf;
907929
long buflen;
908930
char *buf;
931+
int err;
909932
#endif
910933

911934
ZEND_PARSE_PARAMETERS_START(1, 1)
@@ -915,20 +938,25 @@ PHP_FUNCTION(posix_getpwnam)
915938
#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
916939
buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
917940
if (buflen < 1) {
918-
RETURN_FALSE;
941+
buflen = 1024;
919942
}
943+
#if ZEND_DEBUG
944+
/* Test retry logic */
945+
buflen = 1;
946+
#endif
920947
buf = emalloc(buflen);
921-
pw = &pwbuf;
922948

923949
try_again:
924-
if (getpwnam_r(name, pw, buf, buflen, &pw) || pw == NULL) {
925-
if (errno == ERANGE) {
950+
pw = &pwbuf;
951+
err = getpwnam_r(name, pw, buf, buflen, &pw);
952+
if (err || pw == NULL) {
953+
if (err == ERANGE) {
926954
buflen *= 2;
927955
buf = erealloc(buf, buflen);
928956
goto try_again;
929957
}
930958
efree(buf);
931-
POSIX_G(last_error) = errno;
959+
POSIX_G(last_error) = err;
932960
RETURN_FALSE;
933961
}
934962
#else
@@ -959,7 +987,7 @@ PHP_FUNCTION(posix_getpwuid)
959987
struct passwd *retpwptr = NULL;
960988
long pwbuflen;
961989
char *pwbuf;
962-
int ret;
990+
int err;
963991
#endif
964992
struct passwd *pw;
965993

@@ -970,19 +998,23 @@ PHP_FUNCTION(posix_getpwuid)
970998
#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWUID_R)
971999
pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
9721000
if (pwbuflen < 1) {
973-
RETURN_FALSE;
1001+
pwbuflen = 1024;
9741002
}
1003+
#if ZEND_DEBUG
1004+
/* Test retry logic */
1005+
pwbuflen = 1;
1006+
#endif
9751007
pwbuf = emalloc(pwbuflen);
9761008

9771009
try_again:
978-
ret = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr);
979-
if (ret || retpwptr == NULL) {
1010+
err = getpwuid_r(uid, &_pw, pwbuf, pwbuflen, &retpwptr);
1011+
if (err || retpwptr == NULL) {
9801012
if (errno == ERANGE) {
9811013
pwbuflen *= 2;
9821014
pwbuf = erealloc(pwbuf, pwbuflen);
9831015
goto try_again;
9841016
}
985-
POSIX_G(last_error) = ret;
1017+
POSIX_G(last_error) = err;
9861018
efree(pwbuf);
9871019
RETURN_FALSE;
9881020
}

0 commit comments

Comments
 (0)