diff options
-rw-r--r-- | Zend/Makefile.am | 2 | ||||
-rw-r--r-- | Zend/flex.skl | 42 | ||||
-rw-r--r-- | Zend/zend.c | 2 | ||||
-rw-r--r-- | Zend/zend.h | 3 | ||||
-rw-r--r-- | Zend/zend_compile.h | 13 | ||||
-rw-r--r-- | Zend/zend_execute.c | 20 | ||||
-rw-r--r-- | Zend/zend_globals.h | 4 | ||||
-rw-r--r-- | Zend/zend_ini_scanner.l | 22 | ||||
-rw-r--r-- | Zend/zend_language_scanner.h | 2 | ||||
-rw-r--r-- | Zend/zend_language_scanner.l | 33 | ||||
-rw-r--r-- | Zend/zend_stream.c | 123 | ||||
-rw-r--r-- | Zend/zend_stream.h | 59 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | ext/standard/basic_functions.c | 17 | ||||
-rw-r--r-- | main/main.c | 27 | ||||
-rw-r--r-- | main/php_ini.c | 2 |
16 files changed, 274 insertions, 99 deletions
diff --git a/Zend/Makefile.am b/Zend/Makefile.am index 2182442d5b..ac7a68e57d 100644 --- a/Zend/Makefile.am +++ b/Zend/Makefile.am @@ -14,7 +14,7 @@ libZend_la_SOURCES=\ zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ zend_ini.c zend_qsort.c zend_objects.c zend_object_handlers.c \ - zend_object_API.c + zend_object_API.c zend_ts_hash.c zend_stream.c libZend_la_LDFLAGS = libZend_la_LIBADD = @ZEND_EXTRA_LIBS@ diff --git a/Zend/flex.skl b/Zend/flex.skl index 65ed5ca2a5..919aacad69 100644 --- a/Zend/flex.skl +++ b/Zend/flex.skl @@ -2,6 +2,7 @@ /* Scanner skeleton version: * $Header$ + * vim:ft=lex: */ #define FLEX_SCANNER @@ -154,7 +155,7 @@ typedef unsigned int yy_size_t; struct yy_buffer_state { %- - FILE *yy_input_file; + struct _zend_file_handle *yy_input_file; %+ istream* yy_input_file; %* @@ -256,13 +257,13 @@ static int yy_n_chars; /* number of characters read into yy_ch_buf */ /* static int yy_did_buffer_switch_on_eof; */ #define yy_did_buffer_switch_on_eof SCNG(_yy_did_buffer_switch_on_eof) -void yyrestart YY_PROTO(( FILE *input_file TSRMLS_DC )); +void yyrestart YY_PROTO(( struct _zend_file_handle *input_file TSRMLS_DC )); void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer TSRMLS_DC )); void yy_load_buffer_state YY_PROTO(( TSRMLS_D )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size TSRMLS_DC )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( struct _zend_file_handle *file, int size TSRMLS_DC )); void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b TSRMLS_DC )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file TSRMLS_DC )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, struct _zend_file_handle *file TSRMLS_DC )); void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b TSRMLS_DC )); #define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer TSRMLS_CC ) @@ -434,6 +435,18 @@ YY_MALLOC_DECL /* Copy whatever the last rule matched to the standard output. */ +/* Zend file handle reading */ +#ifndef ECHO +#define ECHO /* There is no output */ +#endif + +#define YY_INPUT(buf, result, max_size) \ + if ( ((result = zend_stream_read(yyin, buf, max_size TSRMLS_CC)) == 0) \ + && zend_stream_ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); + + + #ifndef ECHO %- Standard (non-C++) definition /* This used to be an fputs(), but since the string might contain NUL's, @@ -524,6 +537,7 @@ YY_DECL if ( ! yy_start ) yy_start = 1; /* first start state */ +#if 0 if ( ! SCNG(yy_in) ) %- SCNG(yy_in) = stdin; @@ -537,6 +551,7 @@ YY_DECL %+ SCNG(yy_out) = &cout; %* +#endif if ( ! yy_current_buffer ) yy_current_buffer = @@ -1111,10 +1126,10 @@ int yyFlexLexer::yyinput(TSRMLS_D) %- #ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file TSRMLS_DC ) +void yyrestart( struct _zend_file_handle *input_file TSRMLS_DC ) #else void yyrestart( input_file TSRMLS_CC ) -FILE *input_file; +struct _zend_file_handle *input_file; #endif %+ void yyFlexLexer::yyrestart( istream* input_file TSRMLS_DC ) @@ -1187,10 +1202,10 @@ void yyFlexLexer::yy_load_buffer_state() %- #ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size TSRMLS_DC ) +YY_BUFFER_STATE yy_create_buffer( struct _zend_file_handle *file, int size TSRMLS_DC ) #else YY_BUFFER_STATE yy_create_buffer( file, size TSRMLS_CC ) -FILE *file; +struct _zend_file_handle *file; int size; #ifdef ZTS void ***tsrm_ls; @@ -1251,18 +1266,13 @@ void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b TSRMLS_DC ) %- -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -ZEND_DLIMPORT int isatty YY_PROTO(( int )); -#endif -#endif #ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file TSRMLS_DC ) +void yy_init_buffer( YY_BUFFER_STATE b, struct _zend_file_handle *file TSRMLS_DC ) #else void yy_init_buffer( b, file TSRMLS_CC ) YY_BUFFER_STATE b; -FILE *file; +struct _zend_file_handle *file; #ifdef ZTS void ***tsrm_ls; #endif @@ -1286,7 +1296,7 @@ void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, istream* file TSRMLS_DC ) #if YY_NEVER_INTERACTIVE b->yy_is_interactive = 0; #else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + b->yy_is_interactive = file->handle.stream.interactive; #endif #endif %+ diff --git a/Zend/zend.c b/Zend/zend.c index 2a0c1c88b7..9a4e1460de 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -48,6 +48,7 @@ ZEND_API zend_class_entry *zend_standard_class_def = NULL; ZEND_API int (*zend_printf)(const char *format, ...); ZEND_API zend_write_func_t zend_write; ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path); +ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); ZEND_API void (*zend_block_interruptions)(void); ZEND_API void (*zend_unblock_interruptions)(void); ZEND_API void (*zend_ticks_function)(int ticks); @@ -534,6 +535,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i if (!zend_fopen) { zend_fopen = zend_fopen_wrapper; } + zend_stream_open_function = utility_functions->stream_open_function; zend_message_dispatcher_p = utility_functions->message_handler; zend_block_interruptions = utility_functions->block_interruptions; zend_unblock_interruptions = utility_functions->unblock_interruptions; diff --git a/Zend/zend.h b/Zend/zend.h index c031bce103..f6eca9989e 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -342,6 +342,7 @@ struct _zend_class_entry { typedef struct _zend_class_entry zend_namespace; /* namespace is the same as class */ +#include "zend_stream.h" typedef struct _zend_utility_functions { void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); int (*printf_function)(const char *format, ...); @@ -353,6 +354,7 @@ typedef struct _zend_utility_functions { int (*get_configuration_directive)(char *name, uint name_length, zval *contents); void (*ticks_function)(int ticks); void (*on_timeout)(int seconds TSRMLS_DC); + int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); } zend_utility_functions; @@ -485,6 +487,7 @@ extern ZEND_API void (*zend_unblock_interruptions)(void); extern ZEND_API void (*zend_ticks_function)(int ticks); extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args); extern void (*zend_on_timeout)(int seconds TSRMLS_DC); +extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC); ZEND_API void zend_error(int type, const char *format, ...); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index aec37e0159..83622a8f01 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -198,18 +198,6 @@ typedef struct _list_llist_element { znode value; } list_llist_element; - -typedef struct _zend_file_handle { - zend_uchar type; - char *filename; - char *opened_path; - union { - int fd; - FILE *fp; - } handle; - zend_bool free_filename; -} zend_file_handle; - union _temp_variable; struct _zend_execute_data { @@ -726,6 +714,7 @@ int zendlex(znode *zendlval TSRMLS_DC); #define ZEND_HANDLE_FP 2 #define ZEND_HANDLE_STDIOSTREAM 3 #define ZEND_HANDLE_FSTREAM 4 +#define ZEND_HANDLE_STREAM 5 #define ZEND_FETCH_STANDARD 0 #define ZEND_FETCH_ADD_LOCK 1 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 961a52fd93..052f6e87c4 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3338,28 +3338,21 @@ int zend_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS) switch (EX(opline)->op2.u.constant.value.lval) { case ZEND_INCLUDE_ONCE: case ZEND_REQUIRE_ONCE: { - char *opened_path=NULL; int dummy = 1; zend_file_handle file_handle; - file_handle.handle.fp = zend_fopen(inc_filename->value.str.val, &opened_path); - file_handle.type = ZEND_HANDLE_FP; - file_handle.filename = inc_filename->value.str.val; - file_handle.opened_path = opened_path; - file_handle.free_filename = 0; + if (SUCCESS == zend_stream_open(inc_filename->value.str.val, &file_handle TSRMLS_CC)) { - if (file_handle.handle.fp) { - if (!opened_path) { - opened_path = file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); + if (!file_handle.opened_path) { + file_handle.opened_path = estrndup(inc_filename->value.str.val, inc_filename->value.str.len); } - if (zend_hash_add(&EG(included_files), opened_path, strlen(opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) { + if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) { CG(active_namespace) = EG(active_namespace); new_op_array = zend_compile_file(&file_handle, (EX(opline)->op2.u.constant.value.lval==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); - opened_path = NULL; /* zend_destroy_file_handle() already frees it */ } else { - fclose(file_handle.handle.fp); + zend_file_handle_dtor(&file_handle); failure_retval=1; } } else { @@ -3369,9 +3362,6 @@ int zend_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS) zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle.filename); } } - if (opened_path) { - efree(opened_path); - } break; } break; diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index e5c6520787..016c935cef 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -254,8 +254,8 @@ struct _zend_alloc_globals { }; struct _zend_scanner_globals { - FILE *yy_in; - FILE *yy_out; + zend_file_handle *yy_in; + zend_file_handle *yy_out; int yy_leng; char *yy_text; struct yy_buffer_state *current_buffer; diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l index 45aae83154..33d1d294dd 100644 --- a/Zend/zend_ini_scanner.l +++ b/Zend/zend_ini_scanner.l @@ -71,22 +71,12 @@ char *zend_ini_scanner_get_filename(TSRMLS_D) int zend_ini_open_file_for_scanning(zend_file_handle *fh TSRMLS_DC) { - FILE *fp; - - switch (fh->type) { - case ZEND_HANDLE_FP: - fp = fh->handle.fp; - break; - case ZEND_HANDLE_FILENAME: - fp = zend_fopen(fh->filename, NULL); - fh->type = ZEND_HANDLE_FP; - break; - default: - return FAILURE; + if (FAILURE == zend_stream_fixup(fh TSRMLS_CC)) { + return FAILURE; } init_ini_scanner(TSRMLS_C); - yyin = fp; + yyin = fh; yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE TSRMLS_CC) TSRMLS_CC); ini_filename = fh->filename; return SUCCESS; @@ -95,11 +85,7 @@ int zend_ini_open_file_for_scanning(zend_file_handle *fh TSRMLS_DC) void zend_ini_close_file(zend_file_handle *fh TSRMLS_DC) { - switch (fh->type) { - case ZEND_HANDLE_FP: - fclose(fh->handle.fp); - break; - } + zend_stream_close(fh); } %} diff --git a/Zend/zend_language_scanner.h b/Zend/zend_language_scanner.h index be373c2100..50227ee9c7 100644 --- a/Zend/zend_language_scanner.h +++ b/Zend/zend_language_scanner.h @@ -25,7 +25,7 @@ typedef struct _zend_lex_state { YY_BUFFER_STATE buffer_state; int state; - FILE *in; + zend_file_handle *in; uint lineno; char *filename; } zend_lex_state; diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 6908e15318..d8f4d28362 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -171,10 +171,15 @@ BEGIN_EXTERN_C() ZEND_API void zend_file_handle_dtor(zend_file_handle *fh) { + TSRMLS_FETCH(); + switch (fh->type) { case ZEND_HANDLE_FP: fclose(fh->handle.fp); break; + case ZEND_HANDLE_STREAM: + fh->handle.stream.closer(fh->handle.stream.handle TSRMLS_CC); + break; case ZEND_HANDLE_FILENAME: /* We're only supposed to get here when destructing the used_files hash, * which doesn't really contain open files, but references to their names/paths @@ -183,9 +188,11 @@ ZEND_API void zend_file_handle_dtor(zend_file_handle *fh) } if (fh->opened_path) { efree(fh->opened_path); + fh->opened_path = NULL; } if (fh->free_filename && fh->filename) { efree(fh->filename); + fh->filename = NULL; } } @@ -199,6 +206,9 @@ int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2) case ZEND_HANDLE_FP: return fh1->handle.fp==fh2->handle.fp; break; + case ZEND_HANDLE_STREAM: + return fh1->handle.stream.handle == fh2->handle.stream.handle; + break; } return 0; } @@ -214,27 +224,14 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC) { char *file_path=NULL; - switch (file_handle->type) { - case ZEND_HANDLE_FILENAME: - file_handle->handle.fp = zend_fopen(file_handle->filename, &file_handle->opened_path); - break; - case ZEND_HANDLE_FD: - file_handle->handle.fp = fdopen(file_handle->handle.fd, "r"); - break; - case ZEND_HANDLE_FP: - file_handle->handle.fp = file_handle->handle.fp; - break; - } - if (!file_handle->handle.fp) { + if (FAILURE == zend_stream_fixup(file_handle TSRMLS_CC)) { return FAILURE; } - file_handle->type = ZEND_HANDLE_FP; - if (file_handle->handle.fp != stdin) { - zend_llist_add_element(&CG(open_files), file_handle); - } + zend_llist_add_element(&CG(open_files), file_handle); + /* Reset the scanner for scanning the new file */ - SCNG(yy_in) = file_handle->handle.fp; + SCNG(yy_in) = file_handle; yy_switch_to_buffer(yy_create_buffer(SCNG(yy_in), YY_BUF_SIZE TSRMLS_CC) TSRMLS_CC); BEGIN(INITIAL); @@ -339,7 +336,7 @@ zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC) retval = zend_compile_file(&file_handle, type TSRMLS_CC); - if (retval && file_handle.handle.fp) { + if (retval && file_handle.handle.stream.handle) { int dummy = 1; if (!file_handle.opened_path) { diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c new file mode 100644 index 0000000000..f6d6e16072 --- /dev/null +++ b/Zend/zend_stream.c @@ -0,0 +1,123 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) 1998-2003 Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Wez Furlong <wez@thebrainroom.com> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + + +#include "zend.h" +#include "zend_compile.h" + +ZEND_DLIMPORT int isatty(int fd); + +static size_t zend_stream_stdio_reader(void *handle, char *buf, size_t len TSRMLS_DC) +{ + return fread(buf, 1, len, (FILE*)handle); +} + +static void zend_stream_stdio_closer(void *handle TSRMLS_DC) +{ + if ((FILE*)handle != stdin) + fclose((FILE*)handle); +} + +int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC) +{ + if (zend_stream_open) { + return zend_stream_open_function(filename, handle TSRMLS_CC); + } + handle->type = ZEND_HANDLE_FP; + handle->opened_path = NULL; + handle->handle.fp = zend_fopen(filename, &handle->opened_path); + handle->filename = (char *)filename; + handle->free_filename = 0; + + return (handle->handle.fp) ? SUCCESS : FAILURE; +} + +int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC) +{ + switch (file_handle->type) { + case ZEND_HANDLE_FILENAME: + if (FAILURE == zend_stream_open(file_handle->filename, file_handle TSRMLS_CC)) { + return FAILURE; + } + break; + + case ZEND_HANDLE_FD: + file_handle->handle.fp = fdopen(file_handle->handle.fd, "rb"); + file_handle->type = ZEND_HANDLE_FP; + break; + + case ZEND_HANDLE_FP: + file_handle->handle.fp = file_handle->handle.fp; + break; + + case ZEND_HANDLE_STREAM: + /* nothing to do */ + return SUCCESS; + + default: + return FAILURE; + } + if (file_handle->type == ZEND_HANDLE_FP) { + if (!file_handle->handle.fp) { + return FAILURE; + } + + /* promote to stream */ + file_handle->handle.stream.handle = file_handle->handle.fp; + file_handle->handle.stream.reader = zend_stream_stdio_reader; + file_handle->handle.stream.closer = zend_stream_stdio_closer; + file_handle->type = ZEND_HANDLE_STREAM; + + file_handle->handle.stream.interactive = isatty(fileno(file_handle->handle.stream.handle)); + } + return SUCCESS; +} + +size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC) +{ + if (file_handle->handle.stream.interactive) { + int c = '*', n; + + for ( n = 0; n < len && (c = zend_stream_getc( file_handle TSRMLS_CC)) != EOF && c != '\n'; ++n ) + buf[n] = (char) c; + if ( c == '\n' ) + buf[n++] = (char) c; + + return n; + } + return file_handle->handle.stream.reader(file_handle->handle.stream.handle, buf, len TSRMLS_CC); +} + +int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC) +{ + char buf; + + if (zend_stream_read(file_handle, &buf, sizeof(buf) TSRMLS_CC)) { + return buf; + } + return EOF; +} + +int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC) +{ + return 0; +} + + diff --git a/Zend/zend_stream.h b/Zend/zend_stream.h new file mode 100644 index 0000000000..130793287c --- /dev/null +++ b/Zend/zend_stream.h @@ -0,0 +1,59 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) 1998-2003 Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available at through the world-wide-web at | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Wez Furlong <wez@thebrainroom.com> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef ZEND_STREAM_H +#define ZEND_STREAM_H + +/* Lightweight stream implementation for the ZE scanners. + * These functions are private to the engine. + * */ + +typedef size_t (*zend_stream_reader_t)(void *handle, char *buf, size_t len TSRMLS_DC); +typedef void (*zend_stream_closer_t)(void *handle TSRMLS_DC); + +typedef struct _zend_stream { + void *handle; + zend_stream_reader_t reader; + zend_stream_closer_t closer; + int interactive; +} zend_stream; + +typedef struct _zend_file_handle { + zend_uchar type; + char *filename; + char *opened_path; + union { + int fd; + FILE *fp; + zend_stream stream; + } handle; + zend_bool free_filename; +} zend_file_handle; + +int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC); +int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC); +int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC); +size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC); +int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC); + +#define zend_stream_close(handle) zend_file_handle_dtor((handle)) + +#endif + diff --git a/configure.in b/configure.in index 00aa4ac5de..fb7dc63b54 100644 --- a/configure.in +++ b/configure.in @@ -1116,7 +1116,7 @@ PHP_ADD_SOURCES(Zend, \ zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ - zend_ini.c zend_qsort.c zend_multibyte.c) + zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c) if test -r "$abs_srcdir/Zend/zend_objects.c"; then PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_mm.c) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index a9930811a9..fed8e51b93 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2941,21 +2941,10 @@ PHP_FUNCTION(parse_ini_file) convert_to_string_ex(filename); - if (PG(safe_mode) && (!php_checkuid(Z_STRVAL_PP(filename), NULL, CHECKUID_ALLOW_ONLY_FILE))) { - RETURN_FALSE; - } - - if (php_check_open_basedir(Z_STRVAL_PP(filename) TSRMLS_CC)) { - RETURN_FALSE; - } - - fh.handle.fp = VCWD_FOPEN(Z_STRVAL_PP(filename), "r"); - if (!fh.handle.fp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot open '%s' for reading", Z_STRVAL_PP(filename)); - RETURN_FALSE; - } - Z_TYPE(fh) = ZEND_HANDLE_FP; + memset(&fh, 0, sizeof(fh)); fh.filename = Z_STRVAL_PP(filename); + Z_TYPE(fh) = ZEND_HANDLE_FILENAME; + array_init(return_value); zend_parse_ini_file(&fh, 0, ini_parser_cb, return_value); } diff --git a/main/main.c b/main/main.c index 1cf0bf7eb6..d5d8d15623 100644 --- a/main/main.c +++ b/main/main.c @@ -732,6 +732,32 @@ static FILE *php_fopen_wrapper_for_zend(const char *filename, char **opened_path } /* }}} */ +static void stream_closer_for_zend(void *handle TSRMLS_DC) +{ + php_stream_close((php_stream*)handle); +} + +static int php_stream_open_for_zend(const char *filename, zend_file_handle *handle TSRMLS_DC) +{ + php_stream *stream; + + stream = php_stream_open_wrapper((char *)filename, "rb", ENFORCE_SAFE_MODE|USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE, &handle->opened_path); + + if (stream) { + handle->type = ZEND_HANDLE_STREAM; + handle->filename = (char*)filename; + handle->free_filename = 0; + handle->handle.stream.handle = stream; + handle->handle.stream.reader = (zend_stream_reader_t)_php_stream_read; + handle->handle.stream.closer = stream_closer_for_zend; + handle->handle.stream.interactive = 0; + + return SUCCESS; + } + return FAILURE; +} + + /* {{{ php_get_configuration_directive_for_zend */ static int php_get_configuration_directive_for_zend(char *name, uint name_length, zval *contents) @@ -1185,6 +1211,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod zuf.get_configuration_directive = php_get_configuration_directive_for_zend; zuf.ticks_function = php_run_ticks; zuf.on_timeout = php_on_timeout; + zuf.stream_open_function = php_stream_open_for_zend; zend_startup(&zuf, NULL, 1); #ifdef ZTS diff --git a/main/php_ini.c b/main/php_ini.c index 6380a1b831..6e599ebcaf 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -370,7 +370,7 @@ int php_init_config() PG(safe_mode) = 0; PG(open_basedir) = NULL; - fh.handle.fp = NULL; + memset(&fh, 0, sizeof(fh)); /* Check if php_ini_path_override is a file */ if (!sapi_module.php_ini_ignore) { if (sapi_module.php_ini_path_override && sapi_module.php_ini_path_override[0]) { |