Skip to content

Commit e88cf38

Browse files
committed
Support sysconf(_SC_GETPW_R_SIZE_MAX) == -1
1 parent 85d6212 commit e88cf38

File tree

3 files changed

+68
-19
lines changed

3 files changed

+68
-19
lines changed

ext/standard/filestat.c

+30-6
Original file line numberDiff line numberDiff line change
@@ -313,13 +313,25 @@ PHPAPI int php_get_gid_by_name(const char *name, gid_t *gid)
313313
struct group *retgrptr;
314314
long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
315315
char *grbuf;
316+
int err;
316317

317318
if (grbuflen < 1) {
318-
return FAILURE;
319+
grbuflen = 1024;
319320
}
320-
321+
# if ZEND_DEBUG
322+
/* Test retry logic */
323+
grbuflen = 1;
324+
# endif
321325
grbuf = emalloc(grbuflen);
322-
if (getgrnam_r(name, &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) {
326+
327+
try_again:
328+
err = getgrnam_r(name, &gr, grbuf, grbuflen, &retgrptr);
329+
if (err != 0 || retgrptr == NULL) {
330+
if (err == ERANGE) {
331+
grbuflen *= 2;
332+
grbuf = erealloc(grbuf, grbuflen);
333+
goto try_again;
334+
}
323335
efree(grbuf);
324336
return FAILURE;
325337
}
@@ -439,13 +451,25 @@ PHPAPI uid_t php_get_uid_by_name(const char *name, uid_t *uid)
439451
struct passwd *retpwptr = NULL;
440452
long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
441453
char *pwbuf;
454+
int err;
442455

443456
if (pwbuflen < 1) {
444-
return FAILURE;
457+
pwbuflen = 1024;
445458
}
446-
459+
# if ZEND_DEBUG
460+
/* Test retry logic */
461+
pwbuflen = 1;
462+
# endif
447463
pwbuf = emalloc(pwbuflen);
448-
if (getpwnam_r(name, &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) {
464+
465+
try_again:
466+
err = getpwnam_r(name, &pw, pwbuf, pwbuflen, &retpwptr);
467+
if (err != 0 || retpwptr == NULL) {
468+
if (err == EAGAIN) {
469+
pwbuflen *= 2;
470+
pwbuf = erealloc(pwbuf, pwbuflen);
471+
goto try_again;
472+
}
449473
efree(pwbuf);
450474
return FAILURE;
451475
}

main/fopen_wrappers.c

+23-11
Original file line numberDiff line numberDiff line change
@@ -362,26 +362,38 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle)
362362

363363
if (s) { /* if there is no path name after the file, do not bother */
364364
char user[32]; /* to try open the directory */
365+
366+
length = s - (path_info + 2);
367+
if (length > sizeof(user) - 1) {
368+
length = sizeof(user) - 1;
369+
}
370+
memcpy(user, path_info + 2, length);
371+
user[length] = '\0';
372+
365373
struct passwd *pw;
366374
#if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
367375
struct passwd pwstruc;
368376
long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
369377
char *pwbuf;
378+
int err;
370379

371380
if (pwbuflen < 1) {
372-
return FAILURE;
381+
pwbuflen = 1024;
373382
}
374-
383+
# if ZEND_DEBUG
384+
/* Test retry logic */
385+
pwbuflen = 1;
386+
# endif
375387
pwbuf = emalloc(pwbuflen);
376-
#endif
377-
length = s - (path_info + 2);
378-
if (length > sizeof(user) - 1) {
379-
length = sizeof(user) - 1;
380-
}
381-
memcpy(user, path_info + 2, length);
382-
user[length] = '\0';
383-
#if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX)
384-
if (getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw)) {
388+
389+
try_again:
390+
err = getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw);
391+
if (err) {
392+
if (err == ERANGE) {
393+
pwbuflen *= 2;
394+
pwbuf = erealloc(pwbuf, pwbuflen);
395+
goto try_again;
396+
}
385397
efree(pwbuf);
386398
return FAILURE;
387399
}

main/main.c

+15-2
Original file line numberDiff line numberDiff line change
@@ -1452,12 +1452,25 @@ PHPAPI char *php_get_current_user(void)
14521452
struct passwd *retpwptr = NULL;
14531453
int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
14541454
char *pwbuf;
1455+
int err;
14551456

14561457
if (pwbuflen < 1) {
1457-
return "";
1458+
pwbuflen = 1024;
14581459
}
1460+
# if ZEND_DEBUG
1461+
/* Test retry logic */
1462+
pwbuflen = 1;
1463+
# endif
14591464
pwbuf = emalloc(pwbuflen);
1460-
if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) {
1465+
1466+
try_again:
1467+
err = getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr);
1468+
if (err != 0) {
1469+
if (err == ERANGE) {
1470+
pwbuflen *= 2;
1471+
pwbuf = erealloc(pwbuf, pwbuflen);
1472+
goto try_again;
1473+
}
14611474
efree(pwbuf);
14621475
return "";
14631476
}

0 commit comments

Comments
 (0)