Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ext/standard/filters.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static void php_conv_base64_encode_dtor(php_conv_base64_encode *inst)
}
}

static php_conv_err_t php_conv_base64_encode_flush(php_conv_base64_encode *inst, const char **in_pp, size_t *in_left_p, char **out_pp, size_t *out_left_p)
static php_conv_err_t php_conv_base64_encode_flush(php_conv_base64_encode *inst, char **out_pp, size_t *out_left_p)
{
volatile php_conv_err_t err = PHP_CONV_ERR_SUCCESS;
register unsigned char *pd;
Expand Down Expand Up @@ -462,7 +462,7 @@ static php_conv_err_t php_conv_base64_encode_convert(php_conv_base64_encode *ins
register unsigned int line_ccnt;

if (in_pp == NULL || in_left_p == NULL) {
return php_conv_base64_encode_flush(inst, in_pp, in_left_p, out_pp, out_left_p);
return php_conv_base64_encode_flush(inst, out_pp, out_left_p);
}

pd = (unsigned char *)(*out_pp);
Expand Down
2 changes: 0 additions & 2 deletions ext/standard/tests/file/stream_rfc2397_007.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ foreach($streams as $stream)
var_dump(feof($fp));
echo "===GETC===\n";
var_dump(fgetc($fp));
var_dump(fgetc($fp));
var_dump(ftell($fp));
var_dump(feof($fp));
echo "===REWIND===\n";
Expand Down Expand Up @@ -95,7 +94,6 @@ int(5)
bool(false)
===GETC===
string(1) "5"
bool(false)
int(6)
bool(true)
===REWIND===
Expand Down
34 changes: 34 additions & 0 deletions ext/standard/tests/streams/bug68948.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
--TEST--
Bug #68948: feof() on temporary streams broken
--FILE--
<?php

$testString = '0123456789';

$stream = fopen("php://memory", "r+");
fwrite($stream, $testString);
rewind($stream);

var_dump(ftell($stream));
var_dump(feof($stream));

var_dump(fread($stream, 1024));

var_dump(ftell($stream));
var_dump(feof($stream));

var_dump(fread($stream, 1024));

var_dump(ftell($stream));
var_dump(feof($stream));

?>
--EXPECT--
int(0)
bool(false)
string(10) "0123456789"
int(10)
bool(true)
string(0) ""
int(10)
bool(true)
20 changes: 8 additions & 12 deletions main/streams/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,15 @@ static size_t php_stream_memory_read(php_stream *stream, char *buf, size_t count
php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract;
assert(ms != NULL);

if (ms->fpos == ms->fsize) {
if (ms->fpos + count >= ms->fsize) {
count = ms->fsize - ms->fpos;
stream->eof = 1;
count = 0;
} else {
if (ms->fpos + count >= ms->fsize) {
count = ms->fsize - ms->fpos;
}
if (count) {
assert(ms->data!= NULL);
assert(buf!= NULL);
memcpy(buf, ms->data+ms->fpos, count);
ms->fpos += count;
}
}
if (count) {
assert(ms->data!= NULL);
assert(buf!= NULL);
memcpy(buf, ms->data+ms->fpos, count);
ms->fpos += count;
}
return count;
}
Expand Down
17 changes: 15 additions & 2 deletions main/streams/streams.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size)
if (stream->readfilters.head) {
char *chunk_buf;
int err_flag = 0;
unsigned int flushed_eof = 0;
php_stream_bucket_brigade brig_in = { NULL, NULL }, brig_out = { NULL, NULL };
php_stream_bucket_brigade *brig_inp = &brig_in, *brig_outp = &brig_out, *brig_swap;

Expand All @@ -582,7 +583,7 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size)
/* allocate a buffer for reading chunks */
chunk_buf = emalloc(stream->chunk_size);

while (!stream->eof && !err_flag && (stream->writepos - stream->readpos < (off_t)size)) {
while ((!stream->eof || flushed_eof == 1) && !err_flag && (stream->writepos - stream->readpos < (off_t)size)) {
size_t justread = 0;
int flags;
php_stream_bucket *bucket;
Expand All @@ -598,8 +599,20 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size)
php_stream_bucket_append(brig_inp, bucket);

flags = PSFS_FLAG_NORMAL;

if (!flushed_eof) {
flushed_eof = 1;
}
} else if (!stream->eof) {
flags = PSFS_FLAG_FLUSH_INC;
} else {
flags = stream->eof ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC;
flags = PSFS_FLAG_FLUSH_CLOSE;
/* Bug #68948: It is possible for a stream to have bucket data
* AND have have reached EOF. Thus, we need a separate flushed
* check to ensure that, even if EOF has been reached, we have
* called the filter method with the flushed flag at least
* once. */
flushed_eof = 2;
}

/* wind the handle... */
Expand Down