mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-08 12:44:23 +01:00
common/iobuf.c: When requested, fill the buffer even if it is not empty.
* common/iobuf.c (underflow): Don't require that the buffer be empty. When called, fill any available space. -- Signed-off-by: Neal H. Walfield <neal@g10code.com>.
This commit is contained in:
parent
e76c75d872
commit
c7ad36eb0d
138
common/iobuf.c
138
common/iobuf.c
@ -1767,18 +1767,38 @@ underflow (iobuf_t a)
|
||||
size_t len;
|
||||
int rc;
|
||||
|
||||
assert (a->d.start == a->d.len);
|
||||
if (a->use == IOBUF_TEMP)
|
||||
return -1; /* EOF because a temp buffer can't do an underflow */
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: underflow: buffer size: %d; still buffered: %d => space for %d bytes\n",
|
||||
a->no, a->subno,
|
||||
(int) a->d.size, (int) (a->d.len - a->d.start),
|
||||
(int) (a->d.size - (a->d.len - a->d.start)));
|
||||
|
||||
if (a->filter_eof)
|
||||
assert (a->use == IOBUF_INPUT);
|
||||
|
||||
/* If there is still some buffered data, then move it to the start
|
||||
of the buffer and try to fill the end of the buffer. (This is
|
||||
useful if we are called from iobuf_peek().) */
|
||||
assert (a->d.start <= a->d.len);
|
||||
a->d.len -= a->d.start;
|
||||
memmove (a->d.buf, &a->d.buf[a->d.start], a->d.len);
|
||||
a->d.start = 0;
|
||||
|
||||
if (a->d.len == 0 && a->filter_eof)
|
||||
/* The last time we tried to read from this filter, we got an EOF.
|
||||
We couldn't return the EOF, because there was buffered data.
|
||||
Since there is no longer any buffered data, return the
|
||||
error. */
|
||||
{
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
|
||||
a->no, a->subno);
|
||||
if (a->chain)
|
||||
/* A filter follows this one. Free this filter. */
|
||||
{
|
||||
iobuf_t b = a->chain;
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: pop '%s' in underflow\n",
|
||||
a->no, a->subno, iobuf_desc (a));
|
||||
log_debug ("iobuf-%d.%d: filter popped (pending EOF returned)\n",
|
||||
a->no, a->subno);
|
||||
xfree (a->d.buf);
|
||||
xfree (a->real_fname);
|
||||
memcpy (a, b, sizeof *a);
|
||||
@ -1787,82 +1807,108 @@ underflow (iobuf_t a)
|
||||
}
|
||||
else
|
||||
a->filter_eof = 0; /* for the top level filter */
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: underflow: eof (due to filter eof)\n",
|
||||
a->no, a->subno);
|
||||
return -1; /* return one(!) EOF */
|
||||
}
|
||||
if (a->error)
|
||||
|
||||
if (a->d.len == 0 && a->error)
|
||||
/* The last time we tried to read from this filter, we got an
|
||||
error. We couldn't return the error, because there was
|
||||
buffered data. Since there is no longer any buffered data,
|
||||
return the error. */
|
||||
{
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: error\n", a->no, a->subno);
|
||||
log_debug ("iobuf-%d.%d: pending error (%s) returned\n",
|
||||
a->no, a->subno, gpg_strerror (a->error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a->filter)
|
||||
if (a->filter && ! a->filter_eof && ! a->error)
|
||||
/* We have a filter function and the last time we tried to read we
|
||||
didn't get an EOF or an error. Try to fill the buffer. */
|
||||
{
|
||||
len = a->d.size;
|
||||
/* Be careful to account for any buffered data. */
|
||||
len = a->d.size - a->d.len;
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: underflow: req=%lu\n",
|
||||
log_debug ("iobuf-%d.%d: underflow: A->FILTER (%lu bytes)\n",
|
||||
a->no, a->subno, (ulong) len);
|
||||
rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
|
||||
a->d.buf, &len);
|
||||
if (len == 0)
|
||||
/* There is no space for more data. Don't bother calling
|
||||
A->FILTER. */
|
||||
rc = 0;
|
||||
else
|
||||
rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
|
||||
&a->d.buf[a->d.len], &len);
|
||||
a->d.len += len;
|
||||
|
||||
if (DBG_IOBUF)
|
||||
{
|
||||
log_debug ("iobuf-%d.%d: underflow: got=%lu rc=%d\n",
|
||||
a->no, a->subno, (ulong) len, rc);
|
||||
log_debug ("iobuf-%d.%d: A->FILTER() returned rc=%d (%s), read %lu bytes\n",
|
||||
a->no, a->subno,
|
||||
rc, rc == 0 ? "ok" : rc == -1 ? "EOF" : gpg_strerror (rc),
|
||||
(ulong) len);
|
||||
/* if( a->no == 1 ) */
|
||||
/* log_hexdump (" data:", a->d.buf, len); */
|
||||
}
|
||||
if (a->use == IOBUF_INPUT && rc == -1)
|
||||
{ /* EOF: we can remove the filter */
|
||||
|
||||
if (rc == -1)
|
||||
/* EOF. */
|
||||
{
|
||||
size_t dummy_len = 0;
|
||||
|
||||
/* and tell the filter to free itself */
|
||||
/* Tell the filter to free itself */
|
||||
if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain,
|
||||
NULL, &dummy_len)))
|
||||
log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
|
||||
|
||||
/* Free everything except for the internal buffer. */
|
||||
if (a->filter_ov && a->filter_ov_owner)
|
||||
{
|
||||
xfree (a->filter_ov);
|
||||
a->filter_ov = NULL;
|
||||
}
|
||||
a->filter = NULL;
|
||||
xfree (a->filter_ov);
|
||||
a->filter_ov = NULL;
|
||||
a->filter = NULL;
|
||||
a->filter_eof = 1;
|
||||
if (!len && a->chain)
|
||||
|
||||
if (a->d.len == 0 && a->chain)
|
||||
/* We don't need to keep this filter around at all:
|
||||
|
||||
- we got an EOF
|
||||
- we have no buffered data
|
||||
- a filter follows this one.
|
||||
|
||||
Unlink this filter. */
|
||||
{
|
||||
iobuf_t b = a->chain;
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: pop in underflow (!len)\n",
|
||||
log_debug ("iobuf-%d.%d: pop in underflow (nothing buffered, got EOF)\n",
|
||||
a->no, a->subno);
|
||||
xfree (a->d.buf);
|
||||
xfree (a->real_fname);
|
||||
memcpy (a, b, sizeof *a);
|
||||
xfree (b);
|
||||
|
||||
print_chain (a);
|
||||
|
||||
return -1;
|
||||
}
|
||||
else if (a->d.len == 0)
|
||||
/* We can't unlink this filter (it is the only one in the
|
||||
pipeline), but we can immediately return EOF. */
|
||||
return -1;
|
||||
}
|
||||
else if (rc)
|
||||
a->error = rc;
|
||||
|
||||
if (!len)
|
||||
/* Record the error. */
|
||||
{
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: underflow: eof\n", a->no, a->subno);
|
||||
return -1;
|
||||
a->error = rc;
|
||||
|
||||
if (a->d.len == 0)
|
||||
/* There is no buffered data. Immediately return EOF. */
|
||||
return -1;
|
||||
}
|
||||
a->d.len = len;
|
||||
a->d.start = 0;
|
||||
return a->d.buf[a->d.start++];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DBG_IOBUF)
|
||||
log_debug ("iobuf-%d.%d: underflow: eof (no filter)\n",
|
||||
a->no, a->subno);
|
||||
return -1; /* no filter; return EOF */
|
||||
}
|
||||
|
||||
assert (a->d.start <= a->d.len);
|
||||
if (a->d.start < a->d.len)
|
||||
return a->d.buf[a->d.start++];
|
||||
|
||||
/* EOF. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user