Avoid a cppcheck warning about undefined behavior (using the address
of a stack buffer - 1) and fix a memory leak of the iov when doing nl->crnl conversion.
This commit is contained in:
@@ -487,20 +487,27 @@ replay_session(const double max_wait, const char *decimal)
|
|||||||
if (need_nlcr) {
|
if (need_nlcr) {
|
||||||
size_t remainder = nread;
|
size_t remainder = nread;
|
||||||
size_t linelen;
|
size_t linelen;
|
||||||
char *cp = buf;
|
char *line = buf;
|
||||||
char *ep = buf - 1;
|
char *nl, *cp = buf;
|
||||||
|
|
||||||
/* Handle a "\r\n" pair that spans a buffer. */
|
/*
|
||||||
if (last_char == '\r' && buf[0] == '\n') {
|
* Handle a "\r\n" pair that spans a buffer.
|
||||||
ep++;
|
* The newline will be written as part of the next line.
|
||||||
|
*/
|
||||||
|
if (last_char == '\r' && *cp == '\n') {
|
||||||
|
cp++;
|
||||||
remainder--;
|
remainder--;
|
||||||
}
|
}
|
||||||
|
|
||||||
iovcnt = 0;
|
iovcnt = 0;
|
||||||
while ((ep = memchr(ep + 1, '\n', remainder)) != NULL) {
|
while ((nl = memchr(cp, '\n', remainder)) != NULL) {
|
||||||
/* Is there already a carriage return? */
|
/*
|
||||||
if (cp != ep && ep[-1] == '\r') {
|
* If there is already a carriage return, keep going.
|
||||||
remainder = (size_t)(&buf[nread - 1] - ep);
|
* We'll include it as part of the next line written.
|
||||||
|
*/
|
||||||
|
if (cp != nl && nl[-1] == '\r') {
|
||||||
|
remainder = (size_t)(&buf[nread - 1] - nl);
|
||||||
|
cp = nl + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,23 +517,23 @@ replay_session(const double max_wait, const char *decimal)
|
|||||||
sudo_ereallocarray(iov, iovmax <<= 1, sizeof(*iov)) :
|
sudo_ereallocarray(iov, iovmax <<= 1, sizeof(*iov)) :
|
||||||
sudo_emallocarray(iovmax = 32, sizeof(*iov));
|
sudo_emallocarray(iovmax = 32, sizeof(*iov));
|
||||||
}
|
}
|
||||||
linelen = (size_t)(ep - cp) + 1;
|
linelen = (size_t)(nl - line) + 1;
|
||||||
iov[iovcnt].iov_base = cp;
|
iov[iovcnt].iov_base = line;
|
||||||
iov[iovcnt].iov_len = linelen - 1; /* not including \n */
|
iov[iovcnt].iov_len = linelen - 1; /* not including \n */
|
||||||
iovcnt++;
|
iovcnt++;
|
||||||
iov[iovcnt].iov_base = "\r\n";
|
iov[iovcnt].iov_base = "\r\n";
|
||||||
iov[iovcnt].iov_len = 2;
|
iov[iovcnt].iov_len = 2;
|
||||||
iovcnt++;
|
iovcnt++;
|
||||||
cp = ep + 1;
|
line = cp = nl + 1;
|
||||||
remainder -= linelen;
|
remainder -= linelen;
|
||||||
}
|
}
|
||||||
if ((size_t)(cp - buf) != nread) {
|
if ((size_t)(line - buf) != nread) {
|
||||||
/*
|
/*
|
||||||
* Partial line without a linefeed or multiple lines
|
* Partial line without a linefeed or multiple lines
|
||||||
* with \r\n pairs.
|
* that already had \r\n pairs.
|
||||||
*/
|
*/
|
||||||
iov[iovcnt].iov_base = cp;
|
iov[iovcnt].iov_base = line;
|
||||||
iov[iovcnt].iov_len = nread - (cp - buf);
|
iov[iovcnt].iov_len = nread - (line - buf);
|
||||||
iovcnt++;
|
iovcnt++;
|
||||||
}
|
}
|
||||||
last_char = buf[nread - 1]; /* stash last char of old buffer */
|
last_char = buf[nread - 1]; /* stash last char of old buffer */
|
||||||
@@ -550,6 +557,8 @@ replay_session(const double max_wait, const char *decimal)
|
|||||||
sudo_ev_add(evbase, output_ev, NULL, false);
|
sudo_ev_add(evbase, output_ev, NULL, false);
|
||||||
sudo_ev_loop(evbase, 0);
|
sudo_ev_loop(evbase, 0);
|
||||||
}
|
}
|
||||||
|
if (iov != &iovb)
|
||||||
|
sudo_efree(iov);
|
||||||
}
|
}
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user