Skip to content

Commit 25984e2

Browse files
Fix ReadBuffer is canceled exception in zip archive operations
When a `ReadBuffer::nextImpl` throws, `ReadBuffer::next` calls `cancel()` and re-throws. The minizip library catches the exception via the C callback (`readFileFunc`) which stores it and returns 0. However, minizip may then call `readFileFunc` again before the stored exception is re-thrown via `rethrowStreamException`. At that point the underlying `ReadBuffer` is already canceled, and the `chassert(!isCanceled())` in `ReadBuffer::next` fires as a logical error. The fix adds early-return checks for `stored_exception` in all minizip callback functions (`readFileFunc`, `tellFunc`, `seekFunc`, `writeFileFunc`) to avoid touching the buffer after a prior exception has already canceled it. https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=100395&sha=97c66cfd486cfc33344b02f7bf69a66ce1664104&name_0=PR&name_1=Stress%20test%20%28amd_msan%29 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
1 parent 9e0dd1f commit 25984e2

File tree

2 files changed

+10
-0
lines changed

2 files changed

+10
-0
lines changed

src/IO/Archives/ZipArchiveReader.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ namespace
130130
static unsigned long readFileFunc(void *, void * stream, void * buf, unsigned long size) // NOLINT(google-runtime-int)
131131
{
132132
auto & strm = get(stream);
133+
if (strm.stored_exception)
134+
return 0;
133135
try
134136
{
135137
if (strm.at_end)
@@ -146,6 +148,8 @@ namespace
146148
static ZPOS64_T tellFunc(void *, void * stream)
147149
{
148150
auto & strm = get(stream);
151+
if (strm.stored_exception)
152+
return static_cast<ZPOS64_T>(-1);
149153
try
150154
{
151155
if (strm.at_end)
@@ -162,6 +166,8 @@ namespace
162166
static long seekFunc(void *, void * stream, ZPOS64_T offset, int origin) // NOLINT(google-runtime-int)
163167
{
164168
auto & strm = get(stream);
169+
if (strm.stored_exception)
170+
return -1;
165171
try
166172
{
167173
if (origin == SEEK_END)

src/IO/Archives/ZipArchiveWriter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ class ZipArchiveWriter::StreamInfo
220220
static unsigned long writeFileFunc(void * opaque, void *, const void * buf, unsigned long size) // NOLINT(google-runtime-int)
221221
{
222222
auto * stream_info = reinterpret_cast<StreamInfo *>(opaque);
223+
if (stream_info->stored_exception)
224+
return 0;
223225
try
224226
{
225227
stream_info->write_buffer->write(reinterpret_cast<const char *>(buf), size);
@@ -241,6 +243,8 @@ class ZipArchiveWriter::StreamInfo
241243
static ZPOS64_T tellFunc(void * opaque, void *)
242244
{
243245
auto * stream_info = reinterpret_cast<StreamInfo *>(opaque);
246+
if (stream_info->stored_exception)
247+
return static_cast<ZPOS64_T>(-1);
244248
try
245249
{
246250
auto pos = stream_info->write_buffer->count() - stream_info->start_offset;

0 commit comments

Comments
 (0)