diff options
| -rw-r--r-- | Zend/zend_stream.c | 65 | ||||
| -rw-r--r-- | Zend/zend_stream.h | 2 | ||||
| -rw-r--r-- | ext/phar/phar.c | 6 | ||||
| -rw-r--r-- | main/main.c | 11 |
4 files changed, 65 insertions, 19 deletions
diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c index 2403800db7..cf1a3c107b 100644 --- a/Zend/zend_stream.c +++ b/Zend/zend_stream.c @@ -23,10 +23,6 @@ #include "zend_compile.h" #include "zend_stream.h" -#ifndef S_ISREG -# define S_ISREG(m) 1 -#endif - ZEND_DLIMPORT int isatty(int fd); static size_t zend_stream_stdio_reader(void *handle, char *buf, size_t len) /* {{{ */ @@ -41,6 +37,39 @@ static void zend_stream_stdio_closer(void *handle) /* {{{ */ } } /* }}} */ +static size_t zend_stream_stdio_fsizer(void *handle) /* {{{ */ +{ + zend_stat_t buf; + if (handle && zend_fstat(fileno((FILE*)handle), &buf) == 0) { +#ifdef S_ISREG + if (!S_ISREG(buf.st_mode)) { + return 0; + } +#endif + return buf.st_size; + } + return 0; +} /* }}} */ + +static size_t zend_stream_fsize(zend_file_handle *file_handle) /* {{{ */ +{ + zend_stat_t buf; + + if (file_handle->type == ZEND_HANDLE_STREAM) { + return file_handle->handle.stream.fsizer(file_handle->handle.stream.handle); + } + if (file_handle->handle.fp && zend_fstat(fileno(file_handle->handle.fp), &buf) == 0) { +#ifdef S_ISREG + if (!S_ISREG(buf.st_mode)) { + return 0; + } +#endif + return buf.st_size; + } + + return -1; +} /* }}} */ + ZEND_API void zend_stream_init_fp(zend_file_handle *handle, FILE *fp, const char *filename) { memset(handle, 0, sizeof(zend_file_handle)); handle->type = ZEND_HANDLE_FP; @@ -96,7 +125,8 @@ static size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t ZEND_API int zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len) /* {{{ */ { - size_t size = 0; + size_t size; + zend_bool is_fp = 0; if (file_handle->buf) { *buf = file_handle->buf; @@ -111,28 +141,25 @@ ZEND_API int zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t } if (file_handle->type == ZEND_HANDLE_FP) { - FILE *fp = file_handle->handle.fp; - int is_tty; - if (!fp) { + if (!file_handle->handle.fp) { return FAILURE; } - is_tty = isatty(fileno(fp)); - if (!is_tty) { - zend_stat_t buf; - if (zend_fstat(fileno(fp), &buf) == 0 && S_ISREG(buf.st_mode)) { - size = buf.st_size; - } - } - + is_fp = 1; file_handle->type = ZEND_HANDLE_STREAM; - file_handle->handle.stream.handle = fp; - file_handle->handle.stream.isatty = is_tty; + file_handle->handle.stream.handle = file_handle->handle.fp; + file_handle->handle.stream.isatty = isatty(fileno((FILE *)file_handle->handle.stream.handle)); file_handle->handle.stream.reader = (zend_stream_reader_t)zend_stream_stdio_reader; file_handle->handle.stream.closer = (zend_stream_closer_t)zend_stream_stdio_closer; + file_handle->handle.stream.fsizer = (zend_stream_fsizer_t)zend_stream_stdio_fsizer; + } + + size = zend_stream_fsize(file_handle); + if (size == (size_t)-1) { + return FAILURE; } - if (size) { + if (is_fp && !file_handle->handle.stream.isatty && size) { file_handle->buf = *buf = safe_emalloc(1, size, ZEND_MMAP_AHEAD); file_handle->len = zend_stream_read(file_handle, *buf, size); } else { diff --git a/Zend/zend_stream.h b/Zend/zend_stream.h index ae5c73028f..87aec7aff3 100644 --- a/Zend/zend_stream.h +++ b/Zend/zend_stream.h @@ -28,6 +28,7 @@ /* Lightweight stream implementation for the ZE scanners. * These functions are private to the engine. * */ +typedef size_t (*zend_stream_fsizer_t)(void* handle); typedef size_t (*zend_stream_reader_t)(void* handle, char *buf, size_t len); typedef void (*zend_stream_closer_t)(void* handle); @@ -43,6 +44,7 @@ typedef struct _zend_stream { void *handle; int isatty; zend_stream_reader_t reader; + zend_stream_fsizer_t fsizer; zend_stream_closer_t closer; } zend_stream; diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 27ea2ff679..db81b14d8e 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -3221,6 +3221,11 @@ static size_t phar_zend_stream_reader(void *handle, char *buf, size_t len) /* {{ } /* }}} */ +static size_t phar_zend_stream_fsizer(void *handle) /* {{{ */ +{ + return ((phar_archive_data*)handle)->halt_offset + 32; +} /* }}} */ + zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type); #define phar_orig_zend_open zend_stream_open_function @@ -3277,6 +3282,7 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type) file_handle->handle.stream.handle = phar; file_handle->handle.stream.reader = phar_zend_stream_reader; file_handle->handle.stream.closer = NULL; + file_handle->handle.stream.fsizer = phar_zend_stream_fsizer; file_handle->handle.stream.isatty = 0; phar->is_persistent ? php_stream_rewind(PHAR_G(cached_fp)[phar->phar_pos].fp) : diff --git a/main/main.c b/main/main.c index bd713d3137..809ebbfd5e 100644 --- a/main/main.c +++ b/main/main.c @@ -1562,6 +1562,16 @@ static void php_zend_stream_closer(void *handle) /* {{{ */ } /* }}} */ +static size_t php_zend_stream_fsizer(void *handle) /* {{{ */ +{ + php_stream_statbuf ssb; + if (php_stream_stat((php_stream*)handle, &ssb) == 0) { + return ssb.sb.st_size; + } + return 0; +} +/* }}} */ + static int php_stream_open_for_zend(const char *filename, zend_file_handle *handle) /* {{{ */ { return php_stream_open_for_zend_ex(filename, handle, USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE); @@ -1579,6 +1589,7 @@ PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *h handle->opened_path = opened_path; handle->handle.stream.handle = stream; handle->handle.stream.reader = (zend_stream_reader_t)_php_stream_read; + handle->handle.stream.fsizer = php_zend_stream_fsizer; handle->handle.stream.isatty = 0; handle->handle.stream.closer = php_zend_stream_closer; /* suppress warning if this stream is not explicitly closed */ |
