2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 01:49:11 +00:00

Use a pointer to end of buffer instead of tracking space left.

Fixes a problem in feedback mode where an initial backspace would
reduce the effective buffer size.  GitHub issue #439
This commit is contained in:
Todd C. Miller 2025-03-31 08:50:12 -06:00
parent 627ae4b09c
commit e8695d536c

View File

@ -379,21 +379,22 @@ static char *
getln(int fd, char *buf, size_t bufsiz, bool feedback, getln(int fd, char *buf, size_t bufsiz, bool feedback,
enum tgetpass_errval *errval) enum tgetpass_errval *errval)
{ {
size_t left = bufsiz;
ssize_t nr = -1; ssize_t nr = -1;
const char *ep;
char *cp = buf; char *cp = buf;
char c = '\0'; char c = '\0';
debug_decl(getln, SUDO_DEBUG_CONV); debug_decl(getln, SUDO_DEBUG_CONV);
*errval = TGP_ERRVAL_NOERROR; *errval = TGP_ERRVAL_NOERROR;
if (left == 0) { if (bufsiz == 0) {
*errval = TGP_ERRVAL_READERROR; *errval = TGP_ERRVAL_READERROR;
errno = EINVAL; errno = EINVAL;
debug_return_str(NULL); debug_return_str(NULL);
} }
ep = buf + bufsiz - 1; /* reserve space for NUL byte */
while (--left) { while (cp < ep) {
nr = read(fd, &c, 1); nr = read(fd, &c, 1);
if (nr != 1 || c == '\n' || c == '\r') if (nr != 1 || c == '\n' || c == '\r')
break; break;
@ -408,13 +409,11 @@ getln(int fd, char *buf, size_t bufsiz, bool feedback,
cp--; cp--;
} }
cp = buf; cp = buf;
left = bufsiz;
continue; continue;
} else if (c == sudo_term_erase) { } else if (c == sudo_term_erase) {
if (cp > buf) { if (cp > buf) {
ignore_result(write(fd, "\b \b", 3)); ignore_result(write(fd, "\b \b", 3));
cp--; cp--;
left++;
} }
continue; continue;
} }
@ -428,7 +427,7 @@ getln(int fd, char *buf, size_t bufsiz, bool feedback,
while (cp > buf) { while (cp > buf) {
if (write(fd, "\b \b", 3) != 3) if (write(fd, "\b \b", 3) != 3)
break; break;
--cp; cp--;
} }
} }
@ -444,7 +443,7 @@ getln(int fd, char *buf, size_t bufsiz, bool feedback,
debug_return_str(NULL); debug_return_str(NULL);
case 0: case 0:
/* EOF is only an error if no bytes were read. */ /* EOF is only an error if no bytes were read. */
if (left == bufsiz - 1) { if (buf[0] == '\0') {
*errval = TGP_ERRVAL_NOPASSWORD; *errval = TGP_ERRVAL_NOPASSWORD;
debug_return_str(NULL); debug_return_str(NULL);
} }