diff options
author | Wez Furlong <wez@php.net> | 2002-10-14 02:28:35 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2002-10-14 02:28:35 +0000 |
commit | 86e60a2d7ac3b19c1b27523f647575d45bbfc692 (patch) | |
tree | 7e3cc8ffc6958cae8d6f5b229ce82cc7c6c3d3c2 | |
parent | 39f8d4c9715271a854650b2486936a1cc3eb19f8 (diff) | |
download | php-git-86e60a2d7ac3b19c1b27523f647575d45bbfc692.tar.gz |
@- fgets($fp) (with no length parameter) now uses a buffer as long as the
@ the next line available from the $fp. Previously, there was a 1KB limit.
@ (Wez)
-rw-r--r-- | ext/standard/file.c | 40 | ||||
-rwxr-xr-x | main/streams.c | 10 |
2 files changed, 29 insertions, 21 deletions
diff --git a/ext/standard/file.c b/ext/standard/file.c index ab778e4c78..b264a2a637 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1247,8 +1247,8 @@ PHP_FUNCTION(stream_set_timeout) PHPAPI PHP_FUNCTION(fgets) { zval **arg1, **arg2; - int len = 1024; - char *buf; + int len; + char *buf = NULL; int argc = ZEND_NUM_ARGS(); php_stream *stream; @@ -1258,30 +1258,33 @@ PHPAPI PHP_FUNCTION(fgets) php_stream_from_zval(stream, arg1); - if (argc>1) { + if (argc == 1) { + /* ask streams to give us a buffer of an appropriate size */ + buf = php_stream_gets(stream, NULL, 0); + if (buf == NULL) + goto exit_failed; + } else if (argc > 1) { convert_to_long_ex(arg2); len = Z_LVAL_PP(arg2); - } - - if (len < 0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative"); - RETURN_FALSE; - } - - buf = emalloc(sizeof(char) * (len + 1)); - /* needed because recv doesnt put a null at the end*/ - memset(buf, 0, len+1); - if (php_stream_gets(stream, buf, len) == NULL) - goto exit_failed; + if (len < 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter may not be negative"); + RETURN_FALSE; + } + buf = ecalloc(len + 1, sizeof(char)); + if (php_stream_gets(stream, buf, len) == NULL) + goto exit_failed; + } + if (PG(magic_quotes_runtime)) { Z_STRVAL_P(return_value) = php_addslashes(buf, 0, &Z_STRLEN_P(return_value), 1 TSRMLS_CC); Z_TYPE_P(return_value) = IS_STRING; } else { ZVAL_STRING(return_value, buf, 0); - /* resize buffer if it's much larger than the result */ - if (Z_STRLEN_P(return_value) < len / 2) { + /* resize buffer if it's much larger than the result. + * Only needed if the user requested a buffer size. */ + if (argc > 1 && Z_STRLEN_P(return_value) < len / 2) { Z_STRVAL_P(return_value) = erealloc(buf, Z_STRLEN_P(return_value) + 1); } } @@ -1289,7 +1292,8 @@ PHPAPI PHP_FUNCTION(fgets) exit_failed: RETVAL_FALSE; - efree(buf); + if (buf) + efree(buf); } /* }}} */ diff --git a/main/streams.c b/main/streams.c index 177e78ba2b..743fcac233 100755 --- a/main/streams.c +++ b/main/streams.c @@ -666,8 +666,8 @@ static char *php_stream_locate_eol(php_stream *stream TSRMLS_DC) PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRMLS_DC) { size_t avail = 0; - int did_copy = 0; size_t current_buf_size = 0; + size_t total_copied = 0; int grow_mode = 0; char *bufstart = buf; @@ -718,6 +718,7 @@ PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRML * hard to follow */ bufstart = erealloc(bufstart, current_buf_size + cpysz + 1); current_buf_size += cpysz + 1; + buf = bufstart + total_copied; } else { if (cpysz >= maxlen - 1) { cpysz = maxlen - 1; @@ -731,8 +732,8 @@ PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRML stream->readpos += cpysz; buf += cpysz; maxlen -= cpysz; + total_copied += cpysz; - did_copy = 1; if (done) { break; } @@ -758,8 +759,11 @@ PHPAPI char *_php_stream_gets(php_stream *stream, char *buf, size_t maxlen TSRML } } - if (!did_copy) + if (total_copied == 0) { + if (grow_mode) + assert(bufstart != NULL); return NULL; + } buf[0] = '\0'; |