Skip to content

Commit 7728160

Browse files
committed
Fixed bug #76803 ftruncate changes file pointer
1 parent 441b6a6 commit 7728160

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
Bug #76803 ftruncate changes file pointer
3+
--FILE--
4+
<?php
5+
6+
$fn = dirname(__FILE__) . DIRECTORY_SEPARATOR . "test76803";
7+
8+
$f = fopen($fn, "w");
9+
fwrite($f, "Hello");
10+
ftruncate($f, 2);
11+
fwrite($f, "World");
12+
fclose($f);
13+
var_dump(addslashes(file_get_contents($fn)));
14+
15+
$f = fopen($fn, "w");
16+
fwrite($f, "Hello");
17+
ftruncate($f, 2);
18+
fclose($f);
19+
var_dump(addslashes(file_get_contents($fn)));
20+
21+
$f = fopen('php://memory', 'w+');
22+
fwrite($f, 'Hello');
23+
ftruncate($f, 2); // in 7.3 changes file pointer to 2
24+
fwrite($f, 'World');
25+
rewind($f);
26+
var_dump(addslashes(stream_get_contents($f)));
27+
fclose($f);
28+
29+
?>
30+
--CLEAN--
31+
<?php
32+
$fn = dirname(__FILE__) . DIRECTORY_SEPARATOR . "test76803";
33+
unlink($fn);
34+
?>
35+
--EXPECT--
36+
string(13) "He\0\0\0World"
37+
string(2) "He"
38+
string(7) "HeWorld"

main/streams/plain_wrapper.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,12 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
857857
if (INVALID_HANDLE_VALUE == h) {
858858
return PHP_STREAM_OPTION_RETURN_ERR;
859859
}
860+
861+
LARGE_INTEGER old_sz;
862+
if (!GetFileSizeEx(h, &old_sz)) {
863+
return PHP_STREAM_OPTION_RETURN_ERR;
864+
}
865+
860866
LARGE_INTEGER sz;
861867
#if defined(_WIN64)
862868
sz.HighPart = (new_size >> 32);
@@ -871,6 +877,9 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
871877
if (0 == SetEndOfFile(h)) {
872878
return PHP_STREAM_OPTION_RETURN_ERR;
873879
}
880+
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(h, old_sz, NULL, FILE_BEGIN) && NO_ERROR != GetLastError()) {
881+
return PHP_STREAM_OPTION_RETURN_ERR;
882+
}
874883
return PHP_STREAM_OPTION_RETURN_OK;
875884
#else
876885
return ftruncate(fd, new_size) == 0 ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;

0 commit comments

Comments
 (0)