summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_stream.c65
-rw-r--r--Zend/zend_stream.h2
-rw-r--r--ext/phar/phar.c6
-rw-r--r--main/main.c11
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 */