Skip to content

Commit 2dbc8f4

Browse files
authored
Merge pull request #110 from nicolas-grekas/fix-stream-close-return-value
Report success from the stream close handlers
2 parents 4d73494 + bbdc337 commit 2dbc8f4

2 files changed

Lines changed: 75 additions & 9 deletions

File tree

‎tests/streams_10.phpt‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--TEST--
2+
compress.zstd streams report a successful close
3+
--FILE--
4+
<?php
5+
$file = dirname(__FILE__) . '/streams_10.out';
6+
$plain = dirname(__FILE__) . '/streams_10.txt';
7+
8+
// As of PHP 8.6, fclose(), file_put_contents() and copy() return false when
9+
// closing the stream fails, so the close handler has to report success.
10+
$data = str_repeat('abcd', 1024);
11+
12+
echo "Compress\n";
13+
14+
$fp = fopen('compress.zstd://' . $file, 'w');
15+
var_dump($fp !== false);
16+
var_dump(fwrite($fp, $data) === strlen($data));
17+
var_dump(fclose($fp));
18+
19+
echo "Decompress\n";
20+
21+
$fp = fopen('compress.zstd://' . $file, 'r');
22+
var_dump($fp !== false);
23+
var_dump(stream_get_contents($fp) === $data);
24+
var_dump(fclose($fp));
25+
26+
echo "Copy\n";
27+
28+
file_put_contents($plain, $data);
29+
var_dump(copy($plain, 'compress.zstd://' . $file));
30+
var_dump(file_get_contents('compress.zstd://' . $file) === $data);
31+
32+
@unlink($file);
33+
@unlink($plain);
34+
?>
35+
===DONE===
36+
--EXPECT--
37+
Compress
38+
bool(true)
39+
bool(true)
40+
bool(true)
41+
Decompress
42+
bool(true)
43+
bool(true)
44+
bool(true)
45+
Copy
46+
bool(true)
47+
bool(true)
48+
===DONE===

‎zstd.c‎

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -841,9 +841,13 @@ static int php_zstd_decomp_close(php_stream *stream, int close_handle)
841841
return EOF;
842842
}
843843

844+
int ret = 0;
845+
844846
if (close_handle) {
845847
if (self->stream) {
846-
php_stream_close(self->stream);
848+
if (php_stream_close(self->stream)) {
849+
ret = EOF;
850+
}
847851
self->stream = NULL;
848852
}
849853
}
@@ -854,7 +858,7 @@ static int php_zstd_decomp_close(php_stream *stream, int close_handle)
854858
efree(self);
855859
stream->abstract = NULL;
856860

857-
return EOF;
861+
return ret;
858862
}
859863

860864
static int php_zstd_comp_flush_or_end(php_zstd_stream_data *self, int end)
@@ -872,9 +876,15 @@ static int php_zstd_comp_flush_or_end(php_zstd_stream_data *self, int end)
872876
if (ZSTD_isError(res)) {
873877
ZSTD_WARNING("zstd: %s", ZSTD_getErrorName(res));
874878
ret = EOF;
879+
break;
880+
}
881+
if (self->ctx.output.pos
882+
&& (size_t) php_stream_write(self->stream, self->ctx.output.dst,
883+
self->ctx.output.pos)
884+
!= self->ctx.output.pos) {
885+
ret = EOF;
886+
break;
875887
}
876-
php_stream_write(self->stream,
877-
self->ctx.output.dst, self->ctx.output.pos);
878888
} while (res > 0);
879889

880890
return ret;
@@ -897,11 +907,13 @@ static int php_zstd_comp_close(php_stream *stream, int close_handle)
897907
return EOF;
898908
}
899909

900-
php_zstd_comp_flush_or_end(self, 1);
910+
int ret = php_zstd_comp_flush_or_end(self, 1);
901911

902912
if (close_handle) {
903913
if (self->stream) {
904-
php_stream_close(self->stream);
914+
if (php_stream_close(self->stream)) {
915+
ret = EOF;
916+
}
905917
self->stream = NULL;
906918
}
907919
}
@@ -911,7 +923,7 @@ static int php_zstd_comp_close(php_stream *stream, int close_handle)
911923
efree(self);
912924
stream->abstract = NULL;
913925

914-
return EOF;
926+
return ret;
915927
}
916928

917929

@@ -997,8 +1009,14 @@ php_zstd_comp_write(php_stream *stream, const char *buf, size_t count)
9971009
return -1;
9981010
#endif
9991011
}
1000-
php_stream_write(self->stream,
1001-
self->ctx.output.dst, self->ctx.output.pos);
1012+
if (self->ctx.output.pos
1013+
&& (size_t) php_stream_write(self->stream, self->ctx.output.dst,
1014+
self->ctx.output.pos)
1015+
!= self->ctx.output.pos) {
1016+
#if PHP_VERSION_ID >= 70400
1017+
return -1;
1018+
#endif
1019+
}
10021020

10031021
} while (res > 0);
10041022

0 commit comments

Comments
 (0)