Skip to content

Commit c79528a

Browse files
committed
MFH: Fixed bug #48309 (stream_copy_to_stream() and fpasstru() do not
update stream position of plain files)
1 parent 7c30401 commit c79528a

File tree

4 files changed

+55
-3
lines changed

4 files changed

+55
-3
lines changed
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug #48309 (stream_copy_to_stream() and fpasstru() do not update stream position)
3+
--FILE--
4+
<?php
5+
6+
$tmp = tmpfile();
7+
fwrite($tmp, b'test');
8+
fseek($tmp, 0, SEEK_SET);
9+
10+
echo "-- stream_copy_to_stream() --\n";
11+
12+
fseek($tmp, 0, SEEK_SET);
13+
stream_copy_to_stream($tmp, STDOUT, 2);
14+
15+
echo "\n";
16+
var_dump(stream_get_contents($tmp));
17+
18+
echo "-- fpassthru() --\n";
19+
20+
fseek($tmp, 0, SEEK_SET);
21+
fpassthru($tmp);
22+
23+
echo "\n";
24+
var_dump(stream_get_contents($tmp));
25+
26+
?>
27+
--EXPECTF--
28+
-- stream_copy_to_stream() --
29+
te
30+
string(2) "st"
31+
-- fpassthru() --
32+
test
33+
string(0) ""

main/streams/mmap.c

+14
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ PHPAPI int _php_stream_mmap_unmap(php_stream *stream TSRMLS_DC)
5151
return php_stream_set_option(stream, PHP_STREAM_OPTION_MMAP_API, PHP_STREAM_MMAP_UNMAP, NULL) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0;
5252
}
5353

54+
PHPAPI int _php_stream_mmap_unmap_ex(php_stream *stream, off_t readden TSRMLS_DC)
55+
{
56+
int ret = 1;
57+
58+
if (php_stream_seek(stream, readden, SEEK_CUR) != 0) {
59+
ret = 0;
60+
}
61+
if (php_stream_mmap_unmap(stream) == 0) {
62+
ret = 0;
63+
}
64+
65+
return ret;
66+
}
67+
5468
/*
5569
* Local variables:
5670
* tab-width: 4

main/streams/php_stream_mmap.h

+5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ typedef struct {
5858

5959
} php_stream_mmap_range;
6060

61+
#define PHP_STREAM_MMAP_ALL 0
62+
6163
#define php_stream_mmap_supported(stream) (_php_stream_set_option((stream), PHP_STREAM_OPTION_MMAP_API, PHP_STREAM_MMAP_SUPPORTED, NULL TSRMLS_CC) == 0 ? 1 : 0)
6264

6365
/* Returns 1 if the stream in its current state can be memory mapped,
@@ -71,6 +73,9 @@ PHPAPI char *_php_stream_mmap_range(php_stream *stream, size_t offset, size_t le
7173
/* un-maps the last mapped range */
7274
PHPAPI int _php_stream_mmap_unmap(php_stream *stream TSRMLS_DC);
7375
#define php_stream_mmap_unmap(stream) _php_stream_mmap_unmap((stream) TSRMLS_CC)
76+
77+
PHPAPI int _php_stream_mmap_unmap_ex(php_stream *stream, off_t readden TSRMLS_DC);
78+
#define php_stream_mmap_unmap_ex(stream, readden) _php_stream_mmap_unmap_ex((stream), (readden) TSRMLS_CC)
7479
END_EXTERN_C()
7580

7681
/*

main/streams/streams.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1215,12 +1215,12 @@ PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC)
12151215
char *p;
12161216
size_t mapped;
12171217

1218-
p = php_stream_mmap_range(stream, php_stream_tell(stream), PHP_STREAM_COPY_ALL, PHP_STREAM_MAP_MODE_SHARED_READONLY, &mapped);
1218+
p = php_stream_mmap_range(stream, php_stream_tell(stream), PHP_STREAM_MMAP_ALL, PHP_STREAM_MAP_MODE_SHARED_READONLY, &mapped);
12191219

12201220
if (p) {
12211221
PHPWRITE(p, mapped);
12221222

1223-
php_stream_mmap_unmap(stream);
1223+
php_stream_mmap_unmap_ex(stream, mapped);
12241224

12251225
return mapped;
12261226
}
@@ -1340,7 +1340,7 @@ PHPAPI size_t _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, s
13401340
if (p) {
13411341
mapped = php_stream_write(dest, p, mapped);
13421342

1343-
php_stream_mmap_unmap(src);
1343+
php_stream_mmap_unmap_ex(src, mapped);
13441344

13451345
*len = mapped;
13461346

0 commit comments

Comments
 (0)