summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo André dos Santos Lopes <cataphract@php.net>2010-10-13 03:13:29 +0000
committerGustavo André dos Santos Lopes <cataphract@php.net>2010-10-13 03:13:29 +0000
commit14a54b903e952a9f99bf5a4bf4639ab2e105b1c4 (patch)
tree82bd52c3054e2b3f0b2decfaa5ed251013f97d6d
parentd46dcd301eb75a25cc6f96d708a57e96dcec7816 (diff)
downloadphp-git-14a54b903e952a9f99bf5a4bf4639ab2e105b1c4.tar.gz
- Fixed forward stream seeking emulation in streams that don't support seeking
in situations where the read operation gives back less data than requested and when there was data in the buffer before the emulation started. Also made more consistent its behavior -- should return failure every time less data than was requested was skipped. - Small performance improvement by correcting off-by-one error that generate an invalid call to the seek handler or read handler. in _php_stream_seek.
-rw-r--r--NEWS5
-rwxr-xr-xmain/streams/streams.c16
2 files changed, 12 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index 235105ed6c..2d3aa9b178 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,11 @@
- Fixed inconsistent backlog default value (-1) in FPM on many systems. (fat)
- Fixed bug in the Windows implementation of dns_get_record, where the two
last parameters wouldn't be filled unless the type were DNS_ANY (Gustavo).
+- Fixed forward stream seeking emulation in streams that don't support seeking
+ in situations where the read operation gives back less data than requested
+ and when there was data in the buffer before the emulation started. Also made
+ more consistent its behavior -- should return failure every time less data
+ than was requested was skipped. (Gustavo)
- Fixed bug #53021 (In html_entity_decode, failure to convert numeric entities
with ENT_NOQUOTES and ISO-8859-1). Fixed and extended the fix of ENT_NOQUOTES
diff --git a/main/streams/streams.c b/main/streams/streams.c
index c586d0110f..023977d39e 100755
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -1097,8 +1097,8 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_
if ((stream->flags & PHP_STREAM_FLAG_NO_BUFFER) == 0) {
switch(whence) {
case SEEK_CUR:
- if (offset > 0 && offset < stream->writepos - stream->readpos) {
- stream->readpos += offset;
+ if (offset > 0 && offset <= stream->writepos - stream->readpos) {
+ stream->readpos += offset; /* if offset = ..., then readpos = writepos */
stream->position += offset;
stream->eof = 0;
return 0;
@@ -1106,7 +1106,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_
break;
case SEEK_SET:
if (offset > stream->position &&
- offset < stream->position + stream->writepos - stream->readpos) {
+ offset <= stream->position + stream->writepos - stream->readpos) {
stream->readpos += offset - stream->position;
stream->position = offset;
stream->eof = 0;
@@ -1149,14 +1149,12 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_
/* emulate forward moving seeks with reads */
if (whence == SEEK_CUR && offset > 0) {
char tmp[1024];
- while(offset >= sizeof(tmp)) {
- if (php_stream_read(stream, tmp, sizeof(tmp)) == 0) {
+ size_t didread;
+ while(offset > 0) {
+ if ((didread = php_stream_read(stream, tmp, MIN(offset, sizeof(tmp)))) == 0) {
return -1;
}
- offset -= sizeof(tmp);
- }
- if (offset && (php_stream_read(stream, tmp, offset) == 0)) {
- return -1;
+ offset -= didread;
}
stream->eof = 0;
return 0;