mirror of
https://github.com/postgres/postgres.git
synced 2026-04-01 15:26:56 -04:00
Fix multiple bugs in astreamer pipeline code.
astreamer_tar_parser_content() sent the wrong data pointer when forwarding MEMBER_TRAILER padding to the next streamer. After astreamer_buffer_until() buffers the padding bytes, the 'data' pointer has been advanced past them, but the code passed 'data' instead of bbs_buffer.data. This caused the downstream consumer to receive bytes from after the padding rather than the padding itself, and could read past the end of the input buffer. astreamer_gzip_decompressor_content() only checked for Z_STREAM_ERROR from inflate(), silently ignoring Z_DATA_ERROR (corrupted data) and Z_MEM_ERROR (out of memory). Fix by treating any return other than Z_OK, Z_STREAM_END, and Z_BUF_ERROR as fatal. astreamer_gzip_decompressor_free() missed calling inflateEnd() to release zlib's internal decompression state. astreamer_tar_parser_free() neglected to pfree() the streamer struct itself, leaking it. astreamer_extractor_content() did not check the return value of fclose() when closing an extracted file. A deferred write error (e.g., disk full on buffered I/O) would be silently lost. Discussion: https://postgr.es/m/results/98c6b630-acbb-44a7-97fa-1692ce2b827c@dunslane.net Reviewed-By: Tom Lane <tgl@sss.pgh.pa.us> Backpatch-through: 15
This commit is contained in:
parent
0841b219bf
commit
01d58d7e3f
3 changed files with 14 additions and 4 deletions
|
|
@ -266,7 +266,9 @@ astreamer_extractor_content(astreamer *streamer, astreamer_member *member,
|
|||
case ASTREAMER_MEMBER_TRAILER:
|
||||
if (mystreamer->file == NULL)
|
||||
break;
|
||||
fclose(mystreamer->file);
|
||||
if (fclose(mystreamer->file) != 0)
|
||||
pg_fatal("could not close file \"%s\": %m",
|
||||
mystreamer->filename);
|
||||
mystreamer->file = NULL;
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -318,8 +318,9 @@ astreamer_gzip_decompressor_content(astreamer *streamer,
|
|||
*/
|
||||
res = inflate(zs, Z_NO_FLUSH);
|
||||
|
||||
if (res == Z_STREAM_ERROR)
|
||||
pg_fatal("could not decompress data: %s", zs->msg);
|
||||
if (res != Z_OK && res != Z_STREAM_END && res != Z_BUF_ERROR)
|
||||
pg_fatal("could not decompress data: %s",
|
||||
zs->msg ? zs->msg : "unknown error");
|
||||
|
||||
mystreamer->bytes_written =
|
||||
mystreamer->base.bbs_buffer.maxlen - zs->avail_out;
|
||||
|
|
@ -364,7 +365,12 @@ astreamer_gzip_decompressor_finalize(astreamer *streamer)
|
|||
static void
|
||||
astreamer_gzip_decompressor_free(astreamer *streamer)
|
||||
{
|
||||
astreamer_gzip_decompressor *mystreamer;
|
||||
|
||||
mystreamer = (astreamer_gzip_decompressor *) streamer;
|
||||
|
||||
astreamer_free(streamer->bbs_next);
|
||||
inflateEnd(&mystreamer->zstream);
|
||||
pfree(streamer->bbs_buffer.data);
|
||||
pfree(streamer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,7 +224,8 @@ astreamer_tar_parser_content(astreamer *streamer, astreamer_member *member,
|
|||
/* OK, now we can send it. */
|
||||
astreamer_content(mystreamer->base.bbs_next,
|
||||
&mystreamer->member,
|
||||
data, mystreamer->pad_bytes_expected,
|
||||
mystreamer->base.bbs_buffer.data,
|
||||
mystreamer->pad_bytes_expected,
|
||||
ASTREAMER_MEMBER_TRAILER);
|
||||
|
||||
/* Expect next file header. */
|
||||
|
|
@ -346,6 +347,7 @@ astreamer_tar_parser_free(astreamer *streamer)
|
|||
{
|
||||
pfree(streamer->bbs_buffer.data);
|
||||
astreamer_free(streamer->bbs_next);
|
||||
pfree(streamer);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue