Browse Source

Avoid leaking fd's in case of failures

experimental/newoperator
Zeev Suraski 27 years ago
parent
commit
87ba08d1d0
  1. 50
      Zend/zend-scanner.l
  2. 2
      Zend/zend_compile.c
  3. 3
      Zend/zend_compile.h
  4. 2
      Zend/zend_globals.h
  5. 2
      Zend/zend_llist.c
  6. 2
      Zend/zend_llist.h

50
Zend/zend-scanner.l

@ -162,29 +162,28 @@ inline void restore_lexical_state(zend_lex_state *lex_state CLS_DC)
BEGIN_EXTERN_C()
ZEND_API void zend_close_file_handle(zend_file_handle *file_handle)
ZEND_API void zend_open_file_dtor(void *f)
{
switch (file_handle->type) {
case ZEND_HANDLE_FILENAME:
break;
case ZEND_HANDLE_FD:
close(file_handle->handle.fd);
break;
case ZEND_HANDLE_FP:
if (file_handle->handle.fp != stdin) {
fclose(file_handle->handle.fp);
}
break;
#ifdef ZTS
case ZEND_HANDLE_ISTREAM:
if (file_handle->handle.is != &cin) {
delete file_handle->handle.is;
}
break;
delete *((ifstream **) f);
#else
fclose(*((FILE **) f));
#endif
}
}
ZEND_API void zend_close_file_handle(zend_file_handle *file_handle CLS_DC)
{
#ifdef ZTS
zend_llist_del_element(&CG(open_files), &file_handle->handle.is);
#else
zend_llist_del_element(&CG(open_files), &file_handle->handle.fp);
#endif
}
ZEND_API inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
{
#ifndef ZTS
@ -202,8 +201,10 @@ ZEND_API inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
if (!file_handle->handle.fp) {
return FAILURE;
}
file_handle->type = ZEND_HANDLE_FP;
if (file_handle->handle.fp != stdin) {
zend_llist_add_element(&CG(open_files), &file_handle->handle.fp);
}
file_handle->type = ZEND_HANDLE_FP;
/* Reset the scanner for scanning the new file */
yyin = file_handle->handle.fp;
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
@ -229,6 +230,9 @@ ZEND_API inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
delete file_handle->handle.is;
return FAILURE;
}
if (file_handle->handle.is != &cin) {
zend_llist_add_element(&CG(open_files), &file_handle->handle.is);
}
file_handle->type = ZEND_HANDLE_ISTREAM;
CG(ZFL) = new ZendFlexLexer;
@ -282,7 +286,7 @@ ZEND_API zend_op_array *v_compile_files(int mark_as_ref CLS_DC, int file_count,
} else {
CG(active_op_array) = op_array;
compiler_result = zendparse(CLS_C);
zend_close_file_handle(file_handle);
zend_close_file_handle(file_handle CLS_CC);
restore_lexical_state(&original_lex_state CLS_CC);
CG(active_op_array) = original_active_op_array;
if (compiler_result==1) { /* parser error */
@ -421,7 +425,7 @@ int require_file(zend_file_handle *file_handle CLS_DC)
return FAILURE;
}
compiler_result = zendparse(CLS_C);
zend_close_file_handle(file_handle);
zend_close_file_handle(file_handle CLS_CC);
restore_lexical_state(&original_lex_state CLS_CC);
if (compiler_result==1) {
zend_bailout();
@ -444,7 +448,7 @@ int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlight
return FAILURE;
}
zend_highlight(syntax_highlighter_ini);
zend_close_file_handle(&file_handle);
zend_close_file_handle(&file_handle CLS_CC);
restore_lexical_state(&original_lex_state CLS_CC);
return SUCCESS;
}

2
Zend/zend_compile.c

@ -67,6 +67,7 @@ void init_compiler(CLS_D ELS_DC)
zend_hash_apply(&module_registry, (int (*)(void *)) module_registry_request_startup);
init_resource_list(ELS_C);
CG(unclean_shutdown) = 0;
zend_llist_init(&CG(open_files), sizeof(void *), zend_open_file_dtor, 0);
}
@ -80,6 +81,7 @@ void shutdown_compiler(CLS_D)
zend_hash_apply(CG(function_table), (int (*)(void *)) is_not_internal_function);
zend_hash_apply(CG(class_table), (int (*)(void *)) is_not_internal_class);
zend_hash_apply(&module_registry, (int (*)(void *)) module_registry_cleanup);
zend_llist_destroy(&CG(open_files));
}

3
Zend/zend_compile.h

@ -342,7 +342,8 @@ ZEND_API zend_op_array *compile_filename(zval *filename CLS_DC);
ZEND_API inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC);
ZEND_API void init_op_array(zend_op_array *op_array, int initial_ops_size);
ZEND_API void destroy_op_array(zend_op_array *op_array);
ZEND_API void zend_close_file_handle(zend_file_handle *file_handle);
ZEND_API void zend_close_file_handle(zend_file_handle *file_handle CLS_DC);
ZEND_API void zend_open_file_dtor(void *f);
END_EXTERN_C()
ZEND_API void destroy_zend_function(zend_function *function);

2
Zend/zend_globals.h

@ -147,6 +147,8 @@ struct _zend_compiler_globals {
unsigned char handle_op_arrays; /* run op_arrays through op_array handlers */
unsigned char unclean_shutdown;
zend_llist open_files;
#ifdef ZTS
#ifdef __cplusplus
ZendFlexLexer *ZFL;

2
Zend/zend_llist.c

@ -64,7 +64,7 @@ ZEND_API void zend_llist_del_element(zend_llist *l, void *element)
zend_llist_element *current=l->head;
while (current) {
if (current->data == element) {
if (!memcmp(current->data, element, l->size)) {
if (current->prev) {
current->prev->next = current->next;
} else {

2
Zend/zend_llist.h

@ -34,6 +34,7 @@ typedef struct {
zend_llist_element *traverse_ptr;
} zend_llist;
BEGIN_EXTERN_C()
ZEND_API void zend_llist_init(zend_llist *l, size_t size, void (*dtor)(void *data), unsigned char persistent);
ZEND_API void zend_llist_add_element(zend_llist *l, void *element);
ZEND_API void zend_llist_prepend_element(zend_llist *l, void *element);
@ -51,5 +52,6 @@ ZEND_API void *zend_llist_get_first(zend_llist *l);
ZEND_API void *zend_llist_get_last(zend_llist *l);
ZEND_API void *zend_llist_get_next(zend_llist *l);
ZEND_API void *zend_llist_get_prev(zend_llist *l);
END_EXTERN_C()
#endif /* _ZEND_LLIST_H */
Loading…
Cancel
Save