diff options
Diffstat (limited to 'main')
71 files changed, 5804 insertions, 4051 deletions
diff --git a/main/SAPI.c b/main/SAPI.c index 9b5ea1ae62..c0ea144015 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -1,6 +1,6 @@ -/* +/* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -43,12 +43,6 @@ #include "rfc1867.h" -#ifdef PHP_WIN32 -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp -#endif - #include "php_content_types.h" #ifdef ZTS @@ -57,14 +51,22 @@ SAPI_API int sapi_globals_id; sapi_globals_struct sapi_globals; #endif -static void sapi_globals_ctor(sapi_globals_struct *sapi_globals TSRMLS_DC) +static void _type_dtor(zval *zv) +{ + free(Z_PTR_P(zv)); +} + +static void sapi_globals_ctor(sapi_globals_struct *sapi_globals) { +#ifdef ZTS + ZEND_TSRMLS_CACHE_UPDATE(); +#endif memset(sapi_globals, 0, sizeof(*sapi_globals)); - zend_hash_init_ex(&sapi_globals->known_post_content_types, 5, NULL, NULL, 1, 0); - php_setup_sapi_content_types(TSRMLS_C); + zend_hash_init_ex(&sapi_globals->known_post_content_types, 8, NULL, _type_dtor, 1, 0); + php_setup_sapi_content_types(); } -static void sapi_globals_dtor(sapi_globals_struct *sapi_globals TSRMLS_DC) +static void sapi_globals_dtor(sapi_globals_struct *sapi_globals) { zend_hash_destroy(&sapi_globals->known_post_content_types); } @@ -75,10 +77,6 @@ SAPI_API sapi_module_struct sapi_module; SAPI_API void sapi_startup(sapi_module_struct *sf) { -#ifdef ZEND_SIGNALS - zend_signal_startup(); -#endif - sf->ini_entries = NULL; sapi_module = *sf; @@ -124,78 +122,69 @@ SAPI_API void sapi_free_header(sapi_header_struct *sapi_header) PHP_FUNCTION(header_register_callback) { zval *callback_func; - char *callback_name; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &callback_func) == FAILURE) { + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &callback_func) == FAILURE) { return; } - - if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) { - efree(callback_name); + + if (!zend_is_callable(callback_func, 0, NULL)) { RETURN_FALSE; } - efree(callback_name); - - if (SG(callback_func)) { + if (Z_TYPE(SG(callback_func)) != IS_UNDEF) { zval_ptr_dtor(&SG(callback_func)); SG(fci_cache) = empty_fcall_info_cache; } - SG(callback_func) = callback_func; - - Z_ADDREF_P(SG(callback_func)); + ZVAL_COPY(&SG(callback_func), callback_func); RETURN_TRUE; } /* }}} */ -static void sapi_run_header_callback(TSRMLS_D) +static void sapi_run_header_callback(void) { int error; zend_fcall_info fci; - char *callback_name = NULL; char *callback_error = NULL; - zval *retval_ptr = NULL; - - if (zend_fcall_info_init(SG(callback_func), 0, &fci, &SG(fci_cache), &callback_name, &callback_error TSRMLS_CC) == SUCCESS) { - fci.retval_ptr_ptr = &retval_ptr; - - error = zend_call_function(&fci, &SG(fci_cache) TSRMLS_CC); + zval retval; + + if (zend_fcall_info_init(&SG(callback_func), 0, &fci, &SG(fci_cache), NULL, &callback_error) == SUCCESS) { + fci.retval = &retval; + + error = zend_call_function(&fci, &SG(fci_cache)); if (error == FAILURE) { goto callback_failed; - } else if (retval_ptr) { - zval_ptr_dtor(&retval_ptr); + } else { + zval_ptr_dtor(&retval); } } else { callback_failed: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the sapi_header_callback"); - } - - if (callback_name) { - efree(callback_name); + php_error_docref(NULL, E_WARNING, "Could not call the sapi_header_callback"); } + if (callback_error) { efree(callback_error); - } + } } -SAPI_API void sapi_handle_post(void *arg TSRMLS_DC) +SAPI_API void sapi_handle_post(void *arg) { if (SG(request_info).post_entry && SG(request_info).content_type_dup) { - SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, arg TSRMLS_CC); + SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, arg); efree(SG(request_info).content_type_dup); SG(request_info).content_type_dup = NULL; } } -static void sapi_read_post_data(TSRMLS_D) +static void sapi_read_post_data(void) { sapi_post_entry *post_entry; - uint content_type_length = strlen(SG(request_info).content_type); + uint content_type_length = (uint)strlen(SG(request_info).content_type); char *content_type = estrndup(SG(request_info).content_type, content_type_length); char *p; char oldchar=0; - void (*post_reader_func)(TSRMLS_D) = NULL; + void (*post_reader_func)(void) = NULL; /* dedicated implementation for increased performance: @@ -218,8 +207,8 @@ static void sapi_read_post_data(TSRMLS_D) } /* now try to find an appropriate POST content handler */ - if (zend_hash_find(&SG(known_post_content_types), content_type, - content_type_length+1, (void **) &post_entry) == SUCCESS) { + if ((post_entry = zend_hash_str_find_ptr(&SG(known_post_content_types), content_type, + content_type_length)) != NULL) { /* found one, register it for use */ SG(request_info).post_entry = post_entry; post_reader_func = post_entry->post_reader; @@ -240,23 +229,23 @@ static void sapi_read_post_data(TSRMLS_D) SG(request_info).content_type_dup = content_type; if(post_reader_func) { - post_reader_func(TSRMLS_C); + post_reader_func(); } if(sapi_module.default_post_reader) { - sapi_module.default_post_reader(TSRMLS_C); + sapi_module.default_post_reader(); } } -SAPI_API int sapi_read_post_block(char *buffer, size_t buflen TSRMLS_DC) +SAPI_API size_t sapi_read_post_block(char *buffer, size_t buflen) { - int read_bytes; + size_t read_bytes; if (!sapi_module.read_post) { - return -1; + return 0; } - read_bytes = sapi_module.read_post(buffer, buflen TSRMLS_CC); + read_bytes = sapi_module.read_post(buffer, buflen); if (read_bytes > 0) { /* gogo */ @@ -273,7 +262,7 @@ SAPI_API int sapi_read_post_block(char *buffer, size_t buflen TSRMLS_DC) SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data) { if ((SG(post_max_size) > 0) && (SG(request_info).content_length > SG(post_max_size))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", + php_error_docref(NULL, E_WARNING, "POST Content-Length of %pd bytes exceeds the limit of %pd bytes", SG(request_info).content_length, SG(post_max_size)); return; } @@ -282,24 +271,24 @@ SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data) SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir)); if (sapi_module.read_post) { - int read_bytes; + size_t read_bytes; for (;;) { char buffer[SAPI_POST_BLOCK_SIZE]; - read_bytes = sapi_read_post_block(buffer, SAPI_POST_BLOCK_SIZE TSRMLS_CC); + read_bytes = sapi_read_post_block(buffer, SAPI_POST_BLOCK_SIZE); if (read_bytes > 0) { if (php_stream_write(SG(request_info).request_body, buffer, read_bytes) != read_bytes) { /* if parts of the stream can't be written, purge it completely */ php_stream_truncate_set_size(SG(request_info).request_body, 0); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "POST data can't be buffered; all data discarded"); + php_error_docref(NULL, E_WARNING, "POST data can't be buffered; all data discarded"); break; } } if ((SG(post_max_size) > 0) && (SG(read_post_bytes) > SG(post_max_size))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Actual POST length does not match Content-Length, and exceeds %ld bytes", SG(post_max_size)); + php_error_docref(NULL, E_WARNING, "Actual POST length does not match Content-Length, and exceeds " ZEND_LONG_FMT " bytes", SG(post_max_size)); break; } @@ -313,21 +302,21 @@ SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data) } -static inline char *get_default_content_type(uint prefix_len, uint *len TSRMLS_DC) +static inline char *get_default_content_type(uint prefix_len, uint *len) { char *mimetype, *charset, *content_type; uint mimetype_len, charset_len; if (SG(default_mimetype)) { mimetype = SG(default_mimetype); - mimetype_len = strlen(SG(default_mimetype)); + mimetype_len = (uint)strlen(SG(default_mimetype)); } else { mimetype = SAPI_DEFAULT_MIMETYPE; mimetype_len = sizeof(SAPI_DEFAULT_MIMETYPE) - 1; } if (SG(default_charset)) { charset = SG(default_charset); - charset_len = strlen(SG(default_charset)); + charset_len = (uint)strlen(SG(default_charset)); } else { charset = SAPI_DEFAULT_CHARSET; charset_len = sizeof(SAPI_DEFAULT_CHARSET) - 1; @@ -353,19 +342,19 @@ static inline char *get_default_content_type(uint prefix_len, uint *len TSRMLS_D } -SAPI_API char *sapi_get_default_content_type(TSRMLS_D) +SAPI_API char *sapi_get_default_content_type(void) { uint len; - return get_default_content_type(0, &len TSRMLS_CC); + return get_default_content_type(0, &len); } -SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header TSRMLS_DC) +SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header) { uint len; - default_header->header = get_default_content_type(sizeof("Content-type: ")-1, &len TSRMLS_CC); + default_header->header = get_default_content_type(sizeof("Content-type: ")-1, &len); default_header->header_len = len; memcpy(default_header->header, "Content-type: ", sizeof("Content-type: ") - 1); } @@ -381,7 +370,7 @@ SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_h * unchanged, 0 is returned. * */ -SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len TSRMLS_DC) +SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len) { char *charset, *newtype; size_t newlen; @@ -402,16 +391,16 @@ SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len TSRMLS_DC return 0; } -SAPI_API void sapi_activate_headers_only(TSRMLS_D) +SAPI_API void sapi_activate_headers_only(void) { if (SG(request_info).headers_read == 1) return; SG(request_info).headers_read = 1; - zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), + zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), (void (*)(void *)) sapi_free_header, 0); SG(sapi_headers).send_default_content_type = 1; - /* SG(sapi_headers).http_response_code = 200; */ + /* SG(sapi_headers).http_response_code = 200; */ SG(sapi_headers).http_status_line = NULL; SG(sapi_headers).mimetype = NULL; SG(read_post_bytes) = 0; @@ -423,7 +412,7 @@ SAPI_API void sapi_activate_headers_only(TSRMLS_D) SG(global_request_time) = 0; /* - * It's possible to override this general case in the activate() callback, + * It's possible to override this general case in the activate() callback, * if necessary. */ if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) { @@ -432,13 +421,13 @@ SAPI_API void sapi_activate_headers_only(TSRMLS_D) SG(request_info).headers_only = 0; } if (SG(server_context)) { - SG(request_info).cookie_data = sapi_module.read_cookies(TSRMLS_C); + SG(request_info).cookie_data = sapi_module.read_cookies(); if (sapi_module.activate) { - sapi_module.activate(TSRMLS_C); + sapi_module.activate(); } } if (sapi_module.input_filter_init ) { - sapi_module.input_filter_init(TSRMLS_C); + sapi_module.input_filter_init(); } } @@ -446,7 +435,7 @@ SAPI_API void sapi_activate_headers_only(TSRMLS_D) * Called from php_request_startup() for every request. */ -SAPI_API void sapi_activate(TSRMLS_D) +SAPI_API void sapi_activate(void) { zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), (void (*)(void *)) sapi_free_header, 0); SG(sapi_headers).send_default_content_type = 1; @@ -458,7 +447,7 @@ SAPI_API void sapi_activate(TSRMLS_D) SG(sapi_headers).mimetype = NULL; SG(headers_sent) = 0; SG(callback_run) = 0; - SG(callback_func) = NULL; + ZVAL_UNDEF(&SG(callback_func)); SG(read_post_bytes) = 0; SG(request_info).request_body = NULL; SG(request_info).current_user = NULL; @@ -484,33 +473,33 @@ SAPI_API void sapi_activate(TSRMLS_D) && !strcmp(SG(request_info).request_method, "POST")) { /* HTTP POST may contain form data to be processed into variables * depending on given content type */ - sapi_read_post_data(TSRMLS_C); + sapi_read_post_data(); } else { SG(request_info).content_type_dup = NULL; } /* Cookies */ - SG(request_info).cookie_data = sapi_module.read_cookies(TSRMLS_C); + SG(request_info).cookie_data = sapi_module.read_cookies(); if (sapi_module.activate) { - sapi_module.activate(TSRMLS_C); + sapi_module.activate(); } } if (sapi_module.input_filter_init) { - sapi_module.input_filter_init(TSRMLS_C); + sapi_module.input_filter_init(); } } -static void sapi_send_headers_free(TSRMLS_D) +static void sapi_send_headers_free(void) { if (SG(sapi_headers).http_status_line) { efree(SG(sapi_headers).http_status_line); SG(sapi_headers).http_status_line = NULL; } } - -SAPI_API void sapi_deactivate(TSRMLS_D) + +SAPI_API void sapi_deactivate(void) { zend_llist_destroy(&SG(sapi_headers).headers); if (SG(request_info).request_body) { @@ -519,10 +508,10 @@ SAPI_API void sapi_deactivate(TSRMLS_D) if (!SG(post_read)) { /* make sure we've consumed all request input data */ char dummy[SAPI_POST_BLOCK_SIZE]; - int read_bytes; + size_t read_bytes; do { - read_bytes = sapi_read_post_block(dummy, SAPI_POST_BLOCK_SIZE TSRMLS_CC); + read_bytes = sapi_read_post_block(dummy, SAPI_POST_BLOCK_SIZE); } while (SAPI_POST_BLOCK_SIZE == read_bytes); } } @@ -542,28 +531,26 @@ SAPI_API void sapi_deactivate(TSRMLS_D) efree(SG(request_info).current_user); } if (sapi_module.deactivate) { - sapi_module.deactivate(TSRMLS_C); + sapi_module.deactivate(); } if (SG(rfc1867_uploaded_files)) { - destroy_uploaded_files_hash(TSRMLS_C); + destroy_uploaded_files_hash(); } if (SG(sapi_headers).mimetype) { efree(SG(sapi_headers).mimetype); SG(sapi_headers).mimetype = NULL; } - sapi_send_headers_free(TSRMLS_C); + sapi_send_headers_free(); SG(sapi_started) = 0; SG(headers_sent) = 0; SG(callback_run) = 0; - if (SG(callback_func)) { - zval_ptr_dtor(&SG(callback_func)); - } + zval_ptr_dtor(&SG(callback_func)); SG(request_info).headers_read = 0; SG(global_request_time) = 0; } -SAPI_API void sapi_initialize_empty_request(TSRMLS_D) +SAPI_API void sapi_initialize_empty_request(void) { SG(server_context) = NULL; SG(request_info).request_method = NULL; @@ -583,12 +570,12 @@ static int sapi_extract_response_code(const char *header_line) break; } } - + return code; } -static void sapi_update_response_code(int ncode TSRMLS_DC) +static void sapi_update_response_code(int ncode) { /* if the status code did not change, we do not want to change the status line, and no need to change the code */ @@ -603,11 +590,11 @@ static void sapi_update_response_code(int ncode TSRMLS_DC) SG(sapi_headers).http_response_code = ncode; } -/* +/* * since zend_llist_del_element only remove one matched item once, * we should remove them by ourself */ -static void sapi_remove_header(zend_llist *l, char *name, uint len) { +static void sapi_remove_header(zend_llist *l, char *name, size_t len) { sapi_header_struct *header; zend_llist_element *next; zend_llist_element *current=l->head; @@ -635,16 +622,16 @@ static void sapi_remove_header(zend_llist *l, char *name, uint len) { } } -SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace TSRMLS_DC) +SAPI_API int sapi_add_header_ex(char *header_line, size_t header_line_len, zend_bool duplicate, zend_bool replace) { sapi_header_line ctr = {0}; int r; - + ctr.line = header_line; ctr.line_len = header_line_len; r = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, - &ctr TSRMLS_CC); + &ctr); if (!duplicate) efree(header_line); @@ -652,10 +639,10 @@ SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bo return r; } -static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_header TSRMLS_DC) +static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_header) { if (!sapi_module.header_handler || - (SAPI_HEADER_ADD & sapi_module.header_handler(sapi_header, op, &SG(sapi_headers) TSRMLS_CC))) { + (SAPI_HEADER_ADD & sapi_module.header_handler(sapi_header, op, &SG(sapi_headers)))) { if (op == SAPI_HEADER_REPLACE) { char *colon_offset = strchr(sapi_header->header, ':'); @@ -663,7 +650,7 @@ static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_ char sav = *colon_offset; *colon_offset = 0; - sapi_remove_header(&SG(sapi_headers).headers, sapi_header->header, strlen(sapi_header->header)); + sapi_remove_header(&SG(sapi_headers).headers, sapi_header->header, (int)strlen(sapi_header->header)); *colon_offset = sav; } } @@ -673,17 +660,17 @@ static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_ } } -SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) +SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg) { sapi_header_struct sapi_header; char *colon_offset; char *header_line; - uint header_line_len; + size_t header_line_len; int http_response_code; if (SG(headers_sent) && !SG(request_info).no_headers) { - const char *output_start_filename = php_output_get_start_filename(TSRMLS_C); - int output_start_lineno = php_output_get_start_lineno(TSRMLS_C); + const char *output_start_filename = php_output_get_start_filename(); + int output_start_lineno = php_output_get_start_lineno(); if (output_start_filename) { sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent by (output started at %s:%d)", @@ -696,7 +683,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) switch (op) { case SAPI_HEADER_SET_STATUS: - sapi_update_response_code((int)(zend_intptr_t) arg TSRMLS_CC); + sapi_update_response_code((int)(zend_intptr_t) arg); return SUCCESS; case SAPI_HEADER_ADD: @@ -715,7 +702,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) case SAPI_HEADER_DELETE_ALL: if (sapi_module.header_handler) { - sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers) TSRMLS_CC); + sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers)); } zend_llist_clean(&SG(sapi_headers).headers); return SUCCESS; @@ -733,7 +720,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) } while(header_line_len && isspace(header_line[header_line_len-1])); header_line[header_line_len]='\0'; } - + if (op == SAPI_HEADER_DELETE) { if (strchr(header_line, ':')) { efree(header_line); @@ -743,14 +730,14 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) if (sapi_module.header_handler) { sapi_header.header = header_line; sapi_header.header_len = header_line_len; - sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers) TSRMLS_CC); + sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers)); } sapi_remove_header(&SG(sapi_headers).headers, header_line, header_line_len); efree(header_line); return SUCCESS; } else { /* new line/NUL character safety check */ - int i; + uint i; for (i = 0; i < header_line_len; i++) { /* RFC 7230 ch. 3.2.4 deprecates folding support */ if (header_line[i] == '\n' || header_line[i] == '\r') { @@ -771,10 +758,10 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) sapi_header.header_len = header_line_len; /* Check the header for a few cases that we have special support for in SAPI */ - if (header_line_len>=5 + if (header_line_len>=5 && !strncasecmp(header_line, "HTTP/", 5)) { /* filter out the response code */ - sapi_update_response_code(sapi_extract_response_code(header_line) TSRMLS_CC); + sapi_update_response_code(sapi_extract_response_code(header_line)); /* sapi_update_response_code doesn't free the status line if the code didn't change */ if (SG(sapi_headers).http_status_line) { efree(SG(sapi_headers).http_status_line); @@ -785,7 +772,7 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) colon_offset = strchr(header_line, ':'); if (colon_offset) { *colon_offset = 0; - if (!STRCASECMP(header_line, "Content-Type")) { + if (!strcasecmp(header_line, "Content-Type")) { char *ptr = colon_offset+1, *mimetype = NULL, *newheader; size_t len = header_line_len - (ptr - header_line), newlen; while (*ptr == ' ') { @@ -795,11 +782,13 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) /* Disable possible output compression for images */ if (!strncmp(ptr, "image/", sizeof("image/")-1)) { - zend_alter_ini_entry("zlib.output_compression", sizeof("zlib.output_compression"), "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_string *key = zend_string_init("zlib.output_compression", sizeof("zlib.output_compression")-1, 0); + zend_alter_ini_entry_chars(key, "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_string_release(key); } mimetype = estrdup(ptr); - newlen = sapi_apply_default_charset(&mimetype, len TSRMLS_CC); + newlen = sapi_apply_default_charset(&mimetype, len); if (!SG(sapi_headers).mimetype){ SG(sapi_headers).mimetype = estrdup(mimetype); } @@ -810,37 +799,39 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) PHP_STRLCPY(newheader, "Content-type: ", newlen, sizeof("Content-type: ")-1); strlcat(newheader, mimetype, newlen); sapi_header.header = newheader; - sapi_header.header_len = newlen - 1; + sapi_header.header_len = (uint)(newlen - 1); efree(header_line); } efree(mimetype); SG(sapi_headers).send_default_content_type = 0; - } else if (!STRCASECMP(header_line, "Content-Length")) { + } else if (!strcasecmp(header_line, "Content-Length")) { /* Script is setting Content-length. The script cannot reasonably * know the size of the message body after compression, so it's best * do disable compression altogether. This contributes to making scripts * portable between setups that have and don't have zlib compression * enabled globally. See req #44164 */ - zend_alter_ini_entry("zlib.output_compression", sizeof("zlib.output_compression"), + zend_string *key = zend_string_init("zlib.output_compression", sizeof("zlib.output_compression")-1, 0); + zend_alter_ini_entry_chars(key, "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); - } else if (!STRCASECMP(header_line, "Location")) { + zend_string_release(key); + } else if (!strcasecmp(header_line, "Location")) { if ((SG(sapi_headers).http_response_code < 300 || SG(sapi_headers).http_response_code > 399) && SG(sapi_headers).http_response_code != 201) { /* Return a Found Redirect if one is not already specified */ if (http_response_code) { /* user specified redirect code */ - sapi_update_response_code(http_response_code TSRMLS_CC); - } else if (SG(request_info).proto_num > 1000 && - SG(request_info).request_method && + sapi_update_response_code(http_response_code); + } else if (SG(request_info).proto_num > 1000 && + SG(request_info).request_method && strcmp(SG(request_info).request_method, "HEAD") && strcmp(SG(request_info).request_method, "GET")) { - sapi_update_response_code(303 TSRMLS_CC); + sapi_update_response_code(303); } else { - sapi_update_response_code(302 TSRMLS_CC); + sapi_update_response_code(302); } } - } else if (!STRCASECMP(header_line, "WWW-Authenticate")) { /* HTTP Authentication */ - sapi_update_response_code(401 TSRMLS_CC); /* authentication-required */ + } else if (!strcasecmp(header_line, "WWW-Authenticate")) { /* HTTP Authentication */ + sapi_update_response_code(401); /* authentication-required */ } if (sapi_header.header==header_line) { *colon_offset = ':'; @@ -848,14 +839,14 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) } } if (http_response_code) { - sapi_update_response_code(http_response_code TSRMLS_CC); + sapi_update_response_code(http_response_code); } - sapi_header_add_op(op, &sapi_header TSRMLS_CC); + sapi_header_add_op(op, &sapi_header); return SUCCESS; } -SAPI_API int sapi_send_headers(TSRMLS_D) +SAPI_API int sapi_send_headers(void) { int retval; int ret = FAILURE; @@ -871,24 +862,24 @@ SAPI_API int sapi_send_headers(TSRMLS_D) sapi_header_struct default_header; uint len; - SG(sapi_headers).mimetype = get_default_content_type(0, &len TSRMLS_CC); + SG(sapi_headers).mimetype = get_default_content_type(0, &len); default_header.header_len = sizeof("Content-type: ") - 1 + len; default_header.header = emalloc(default_header.header_len + 1); memcpy(default_header.header, "Content-type: ", sizeof("Content-type: ") - 1); memcpy(default_header.header + sizeof("Content-type: ") - 1, SG(sapi_headers).mimetype, len + 1); - sapi_header_add_op(SAPI_HEADER_ADD, &default_header TSRMLS_CC); + sapi_header_add_op(SAPI_HEADER_ADD, &default_header); SG(sapi_headers).send_default_content_type = 0; } - if (SG(callback_func) && !SG(callback_run)) { + if (Z_TYPE(SG(callback_func)) != IS_UNDEF && !SG(callback_run)) { SG(callback_run) = 1; - sapi_run_header_callback(TSRMLS_C); + sapi_run_header_callback(); } SG(headers_sent) = 1; if (sapi_module.send_headers) { - retval = sapi_module.send_headers(&SG(sapi_headers) TSRMLS_CC); + retval = sapi_module.send_headers(&SG(sapi_headers)); } else { retval = SAPI_HEADER_DO_SEND; } @@ -903,22 +894,22 @@ SAPI_API int sapi_send_headers(TSRMLS_D) if (SG(sapi_headers).http_status_line) { http_status_line.header = SG(sapi_headers).http_status_line; - http_status_line.header_len = strlen(SG(sapi_headers).http_status_line); + http_status_line.header_len = (uint)strlen(SG(sapi_headers).http_status_line); } else { http_status_line.header = buf; http_status_line.header_len = slprintf(buf, sizeof(buf), "HTTP/1.0 %d X", SG(sapi_headers).http_response_code); } - sapi_module.send_header(&http_status_line, SG(server_context) TSRMLS_CC); + sapi_module.send_header(&http_status_line, SG(server_context)); } - zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) sapi_module.send_header, SG(server_context) TSRMLS_CC); + zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) sapi_module.send_header, SG(server_context)); if(SG(sapi_headers).send_default_content_type) { sapi_header_struct default_header; - sapi_get_default_content_type_header(&default_header TSRMLS_CC); - sapi_module.send_header(&default_header, SG(server_context) TSRMLS_CC); + sapi_get_default_content_type_header(&default_header); + sapi_module.send_header(&default_header, SG(server_context)); sapi_free_header(&default_header); } - sapi_module.send_header(NULL, SG(server_context) TSRMLS_CC); + sapi_module.send_header(NULL, SG(server_context)); ret = SUCCESS; break; case SAPI_HEADER_SEND_FAILED: @@ -927,18 +918,18 @@ SAPI_API int sapi_send_headers(TSRMLS_D) break; } - sapi_send_headers_free(TSRMLS_C); + sapi_send_headers_free(); return ret; } -SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entries TSRMLS_DC) +SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entries) { sapi_post_entry *p=post_entries; while (p->content_type) { - if (sapi_register_post_entry(p TSRMLS_CC) == FAILURE) { + if (sapi_register_post_entry(p) == FAILURE) { return FAILURE; } p++; @@ -947,29 +938,29 @@ SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entries TSRMLS_DC) } -SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry TSRMLS_DC) +SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry) { - if (SG(sapi_started) && EG(in_execution)) { + if (SG(sapi_started) && EG(current_execute_data)) { return FAILURE; } - return zend_hash_add(&SG(known_post_content_types), - post_entry->content_type, post_entry->content_type_len+1, - (void *) post_entry, sizeof(sapi_post_entry), NULL); + return zend_hash_str_add_mem(&SG(known_post_content_types), + post_entry->content_type, post_entry->content_type_len, + (void *) post_entry, sizeof(sapi_post_entry)) ? SUCCESS : FAILURE; } -SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry TSRMLS_DC) +SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry) { - if (SG(sapi_started) && EG(in_execution)) { + if (SG(sapi_started) && EG(current_execute_data)) { return; } - zend_hash_del(&SG(known_post_content_types), post_entry->content_type, - post_entry->content_type_len+1); + zend_hash_str_del(&SG(known_post_content_types), post_entry->content_type, + post_entry->content_type_len); } -SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D) TSRMLS_DC) +SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(void)) { - if (SG(sapi_started) && EG(in_execution)) { + if (SG(sapi_started) && EG(current_execute_data)) { return FAILURE; } sapi_module.default_post_reader = default_post_reader; @@ -977,18 +968,18 @@ SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRML } -SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC) TSRMLS_DC) +SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray)) { - if (SG(sapi_started) && EG(in_execution)) { + if (SG(sapi_started) && EG(current_execute_data)) { return FAILURE; } sapi_module.treat_data = treat_data; return SUCCESS; } -SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC), unsigned int (*input_filter_init)(TSRMLS_D) TSRMLS_DC) +SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, size_t val_len, size_t *new_val_len), unsigned int (*input_filter_init)(void)) { - if (SG(sapi_started) && EG(in_execution)) { + if (SG(sapi_started) && EG(current_execute_data)) { return FAILURE; } sapi_module.input_filter = input_filter; @@ -996,7 +987,7 @@ SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, ch return SUCCESS; } -SAPI_API int sapi_flush(TSRMLS_D) +SAPI_API int sapi_flush(void) { if (sapi_module.flush) { sapi_module.flush(SG(server_context)); @@ -1006,10 +997,10 @@ SAPI_API int sapi_flush(TSRMLS_D) } } -SAPI_API struct stat *sapi_get_stat(TSRMLS_D) +SAPI_API zend_stat_t *sapi_get_stat(void) { if (sapi_module.get_stat) { - return sapi_module.get_stat(TSRMLS_C); + return sapi_module.get_stat(); } else { if (!SG(request_info).path_translated || (VCWD_STAT(SG(request_info).path_translated, &SG(global_stat)) == -1)) { return NULL; @@ -1018,66 +1009,66 @@ SAPI_API struct stat *sapi_get_stat(TSRMLS_D) } } -SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC) +SAPI_API char *sapi_getenv(char *name, size_t name_len) { - if (sapi_module.getenv) { - char *value, *tmp = sapi_module.getenv(name, name_len TSRMLS_CC); + if (sapi_module.getenv) { + char *value, *tmp = sapi_module.getenv(name, name_len); if (tmp) { value = estrdup(tmp); } else { return NULL; } if (sapi_module.input_filter) { - sapi_module.input_filter(PARSE_STRING, name, &value, strlen(value), NULL TSRMLS_CC); + sapi_module.input_filter(PARSE_STRING, name, &value, strlen(value), NULL); } return value; } return NULL; } -SAPI_API int sapi_get_fd(int *fd TSRMLS_DC) +SAPI_API int sapi_get_fd(int *fd) { if (sapi_module.get_fd) { - return sapi_module.get_fd(fd TSRMLS_CC); + return sapi_module.get_fd(fd); } else { return FAILURE; } } -SAPI_API int sapi_force_http_10(TSRMLS_D) +SAPI_API int sapi_force_http_10(void) { if (sapi_module.force_http_10) { - return sapi_module.force_http_10(TSRMLS_C); + return sapi_module.force_http_10(); } else { return FAILURE; } } -SAPI_API int sapi_get_target_uid(uid_t *obj TSRMLS_DC) +SAPI_API int sapi_get_target_uid(uid_t *obj) { if (sapi_module.get_target_uid) { - return sapi_module.get_target_uid(obj TSRMLS_CC); + return sapi_module.get_target_uid(obj); } else { return FAILURE; } } -SAPI_API int sapi_get_target_gid(gid_t *obj TSRMLS_DC) +SAPI_API int sapi_get_target_gid(gid_t *obj) { if (sapi_module.get_target_gid) { - return sapi_module.get_target_gid(obj TSRMLS_CC); + return sapi_module.get_target_gid(obj); } else { return FAILURE; } } -SAPI_API double sapi_get_request_time(TSRMLS_D) +SAPI_API double sapi_get_request_time(void) { if(SG(global_request_time)) return SG(global_request_time); if (sapi_module.get_request_time && SG(server_context)) { - SG(global_request_time) = sapi_module.get_request_time(TSRMLS_C); + SG(global_request_time) = sapi_module.get_request_time(); } else { struct timeval tp = {0}; if (!gettimeofday(&tp, NULL)) { @@ -1089,9 +1080,9 @@ SAPI_API double sapi_get_request_time(TSRMLS_D) return SG(global_request_time); } -SAPI_API void sapi_terminate_process(TSRMLS_D) { +SAPI_API void sapi_terminate_process(void) { if (sapi_module.terminate_process) { - sapi_module.terminate_process(TSRMLS_C); + sapi_module.terminate_process(); } } diff --git a/main/SAPI.h b/main/SAPI.h index 224f0b5a9a..67ee50dec2 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -31,15 +31,16 @@ #include "win32/php_stdint.h" #endif #include <sys/stat.h> +#include "php.h" #define SAPI_OPTION_NO_CHDIR 1 #define SAPI_POST_BLOCK_SIZE 0x4000 #ifdef PHP_WIN32 # ifdef SAPI_EXPORTS -# define SAPI_API __declspec(dllexport) +# define SAPI_API __declspec(dllexport) # else -# define SAPI_API __declspec(dllimport) +# define SAPI_API __declspec(dllimport) # endif #elif defined(__GNUC__) && __GNUC__ >= 4 # define SAPI_API __attribute__ ((visibility("default"))) @@ -51,7 +52,7 @@ typedef struct { char *header; - uint header_len; + size_t header_len; } sapi_header_struct; @@ -81,7 +82,7 @@ typedef struct { const char *request_method; char *query_string; char *cookie_data; - long content_length; + zend_long content_length; char *path_translated; char *request_uri; @@ -124,16 +125,16 @@ typedef struct _sapi_globals_struct { int64_t read_post_bytes; unsigned char post_read; unsigned char headers_sent; - struct stat global_stat; + zend_stat_t global_stat; char *default_mimetype; char *default_charset; HashTable *rfc1867_uploaded_files; - long post_max_size; + zend_long post_max_size; int options; zend_bool sapi_started; double global_request_time; HashTable known_post_content_types; - zval *callback_func; + zval callback_func; zend_fcall_info_cache fci_cache; zend_bool callback_run; } sapi_globals_struct; @@ -141,7 +142,7 @@ typedef struct _sapi_globals_struct { BEGIN_EXTERN_C() #ifdef ZTS -# define SG(v) TSRMG(sapi_globals_id, sapi_globals_struct *, v) +# define SG(v) ZEND_TSRMG(sapi_globals_id, sapi_globals_struct *, v) SAPI_API extern int sapi_globals_id; #else # define SG(v) (sapi_globals.v) @@ -150,13 +151,13 @@ extern SAPI_API sapi_globals_struct sapi_globals; SAPI_API void sapi_startup(sapi_module_struct *sf); SAPI_API void sapi_shutdown(void); -SAPI_API void sapi_activate(TSRMLS_D); -SAPI_API void sapi_deactivate(TSRMLS_D); -SAPI_API void sapi_initialize_empty_request(TSRMLS_D); +SAPI_API void sapi_activate(void); +SAPI_API void sapi_deactivate(void); +SAPI_API void sapi_initialize_empty_request(void); END_EXTERN_C() /* - * This is the preferred and maintained API for + * This is the preferred and maintained API for * operating on HTTP headers. */ @@ -165,11 +166,11 @@ END_EXTERN_C() * * sapi_header_line ctr = {0}; */ - + typedef struct { char *line; /* If you allocated this, you need to free it yourself */ - uint line_len; - long response_code; /* long due to zend_parse_parameters compatibility */ + size_t line_len; + zend_long response_code; /* long due to zend_parse_parameters compatibility */ } sapi_header_line; typedef enum { /* Parameter: */ @@ -181,40 +182,40 @@ typedef enum { /* Parameter: */ } sapi_header_op_enum; BEGIN_EXTERN_C() -SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC); +SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg); /* Deprecated functions. Use sapi_header_op instead. */ -SAPI_API int sapi_add_header_ex(char *header_line, uint header_line_len, zend_bool duplicate, zend_bool replace TSRMLS_DC); -#define sapi_add_header(a, b, c) sapi_add_header_ex((a),(b),(c),1 TSRMLS_CC) +SAPI_API int sapi_add_header_ex(char *header_line, size_t header_line_len, zend_bool duplicate, zend_bool replace); +#define sapi_add_header(a, b, c) sapi_add_header_ex((a),(b),(c),1) -SAPI_API int sapi_send_headers(TSRMLS_D); +SAPI_API int sapi_send_headers(void); SAPI_API void sapi_free_header(sapi_header_struct *sapi_header); -SAPI_API void sapi_handle_post(void *arg TSRMLS_DC); -SAPI_API int sapi_read_post_block(char *buffer, size_t buflen TSRMLS_DC); -SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entry TSRMLS_DC); -SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry TSRMLS_DC); -SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry TSRMLS_DC); -SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D) TSRMLS_DC); -SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC) TSRMLS_DC); -SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC), unsigned int (*input_filter_init)(TSRMLS_D) TSRMLS_DC); - -SAPI_API int sapi_flush(TSRMLS_D); -SAPI_API struct stat *sapi_get_stat(TSRMLS_D); -SAPI_API char *sapi_getenv(char *name, size_t name_len TSRMLS_DC); - -SAPI_API char *sapi_get_default_content_type(TSRMLS_D); -SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header TSRMLS_DC); -SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len TSRMLS_DC); -SAPI_API void sapi_activate_headers_only(TSRMLS_D); - -SAPI_API int sapi_get_fd(int *fd TSRMLS_DC); -SAPI_API int sapi_force_http_10(TSRMLS_D); - -SAPI_API int sapi_get_target_uid(uid_t * TSRMLS_DC); -SAPI_API int sapi_get_target_gid(gid_t * TSRMLS_DC); -SAPI_API double sapi_get_request_time(TSRMLS_D); -SAPI_API void sapi_terminate_process(TSRMLS_D); +SAPI_API void sapi_handle_post(void *arg); +SAPI_API size_t sapi_read_post_block(char *buffer, size_t buflen); +SAPI_API int sapi_register_post_entries(sapi_post_entry *post_entry); +SAPI_API int sapi_register_post_entry(sapi_post_entry *post_entry); +SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry); +SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(void)); +SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray)); +SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, size_t val_len, size_t *new_val_len), unsigned int (*input_filter_init)(void)); + +SAPI_API int sapi_flush(void); +SAPI_API zend_stat_t *sapi_get_stat(void); +SAPI_API char *sapi_getenv(char *name, size_t name_len); + +SAPI_API char *sapi_get_default_content_type(void); +SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header); +SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len); +SAPI_API void sapi_activate_headers_only(void); + +SAPI_API int sapi_get_fd(int *fd); +SAPI_API int sapi_force_http_10(void); + +SAPI_API int sapi_get_target_uid(uid_t *); +SAPI_API int sapi_get_target_gid(gid_t *); +SAPI_API double sapi_get_request_time(void); +SAPI_API void sapi_terminate_process(void); END_EXTERN_C() struct _sapi_module_struct { @@ -224,63 +225,63 @@ struct _sapi_module_struct { int (*startup)(struct _sapi_module_struct *sapi_module); int (*shutdown)(struct _sapi_module_struct *sapi_module); - int (*activate)(TSRMLS_D); - int (*deactivate)(TSRMLS_D); + int (*activate)(void); + int (*deactivate)(void); - int (*ub_write)(const char *str, unsigned int str_length TSRMLS_DC); + size_t (*ub_write)(const char *str, size_t str_length); void (*flush)(void *server_context); - struct stat *(*get_stat)(TSRMLS_D); - char *(*getenv)(char *name, size_t name_len TSRMLS_DC); + zend_stat_t *(*get_stat)(void); + char *(*getenv)(char *name, size_t name_len); void (*sapi_error)(int type, const char *error_msg, ...); - int (*header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC); - int (*send_headers)(sapi_headers_struct *sapi_headers TSRMLS_DC); - void (*send_header)(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC); + int (*header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers); + int (*send_headers)(sapi_headers_struct *sapi_headers); + void (*send_header)(sapi_header_struct *sapi_header, void *server_context); - int (*read_post)(char *buffer, uint count_bytes TSRMLS_DC); - char *(*read_cookies)(TSRMLS_D); + size_t (*read_post)(char *buffer, size_t count_bytes); + char *(*read_cookies)(void); - void (*register_server_variables)(zval *track_vars_array TSRMLS_DC); - void (*log_message)(char *message TSRMLS_DC); - double (*get_request_time)(TSRMLS_D); - void (*terminate_process)(TSRMLS_D); + void (*register_server_variables)(zval *track_vars_array); + void (*log_message)(char *message); + double (*get_request_time)(void); + void (*terminate_process)(void); char *php_ini_path_override; void (*block_interruptions)(void); void (*unblock_interruptions)(void); - void (*default_post_reader)(TSRMLS_D); - void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC); + void (*default_post_reader)(void); + void (*treat_data)(int arg, char *str, zval *destArray); char *executable_location; int php_ini_ignore; int php_ini_ignore_cwd; /* don't look for php.ini in the current directory */ - int (*get_fd)(int *fd TSRMLS_DC); + int (*get_fd)(int *fd); + + int (*force_http_10)(void); - int (*force_http_10)(TSRMLS_D); + int (*get_target_uid)(uid_t *); + int (*get_target_gid)(gid_t *); - int (*get_target_uid)(uid_t * TSRMLS_DC); - int (*get_target_gid)(gid_t * TSRMLS_DC); + unsigned int (*input_filter)(int arg, char *var, char **val, size_t val_len, size_t *new_val_len); - unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC); - void (*ini_defaults)(HashTable *configuration_hash); int phpinfo_as_text; char *ini_entries; const zend_function_entry *additional_functions; - unsigned int (*input_filter_init)(TSRMLS_D); + unsigned int (*input_filter_init)(void); }; struct _sapi_post_entry { char *content_type; uint content_type_len; - void (*post_reader)(TSRMLS_D); - void (*post_handler)(char *content_type_dup, void *arg TSRMLS_DC); + void (*post_reader)(void); + void (*post_handler)(char *content_type_dup, void *arg); }; /* header_handler() constants */ @@ -295,11 +296,11 @@ struct _sapi_post_entry { #define SAPI_DEFAULT_CHARSET PHP_DEFAULT_CHARSET #define SAPI_PHP_VERSION_HEADER "X-Powered-By: PHP/" PHP_VERSION -#define SAPI_POST_READER_FUNC(post_reader) void post_reader(TSRMLS_D) -#define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg TSRMLS_DC) +#define SAPI_POST_READER_FUNC(post_reader) void post_reader(void) +#define SAPI_POST_HANDLER_FUNC(post_handler) void post_handler(char *content_type_dup, void *arg) -#define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray TSRMLS_DC) -#define SAPI_INPUT_FILTER_FUNC(input_filter) unsigned int input_filter(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC) +#define SAPI_TREAT_DATA_FUNC(treat_data) void treat_data(int arg, char *str, zval* destArray) +#define SAPI_INPUT_FILTER_FUNC(input_filter) unsigned int input_filter(int arg, char *var, char **val, size_t val_len, size_t *new_val_len) BEGIN_EXTERN_C() SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data); diff --git a/main/build-defs.h.in b/main/build-defs.h.in index aa1fbf0321..6821b631f5 100644 --- a/main/build-defs.h.in +++ b/main/build-defs.h.in @@ -1,6 +1,6 @@ /* -*- C -*- +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ diff --git a/main/fastcgi.c b/main/fastcgi.c new file mode 100644 index 0000000000..cd8ca4523c --- /dev/null +++ b/main/fastcgi.c @@ -0,0 +1,1760 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2015 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Dmitry Stogov <dmitry@zend.com> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#include "php.h" +#include "php_network.h" + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <errno.h> + +#ifndef MAXFQDNLEN +#define MAXFQDNLEN 255 +#endif + +#ifdef _WIN32 + +#include <windows.h> + +typedef unsigned int in_addr_t; + +struct sockaddr_un { + short sun_family; + char sun_path[MAXPATHLEN]; +}; + +static HANDLE fcgi_accept_mutex = INVALID_HANDLE_VALUE; +static int is_impersonate = 0; + +#define FCGI_LOCK(fd) \ + if (fcgi_accept_mutex != INVALID_HANDLE_VALUE) { \ + DWORD ret; \ + while ((ret = WaitForSingleObject(fcgi_accept_mutex, 1000)) == WAIT_TIMEOUT) { \ + if (in_shutdown) return -1; \ + } \ + if (ret == WAIT_FAILED) { \ + fprintf(stderr, "WaitForSingleObject() failed\n"); \ + return -1; \ + } \ + } + +#define FCGI_UNLOCK(fd) \ + if (fcgi_accept_mutex != INVALID_HANDLE_VALUE) { \ + ReleaseMutex(fcgi_accept_mutex); \ + } + +#else + +# include <sys/types.h> +# include <sys/stat.h> +# include <unistd.h> +# include <fcntl.h> +# include <sys/socket.h> +# include <sys/un.h> +# include <netinet/in.h> +# include <netinet/tcp.h> +# include <arpa/inet.h> +# include <netdb.h> +# include <signal.h> + +# if defined(HAVE_SYS_POLL_H) && defined(HAVE_POLL) +# include <sys/poll.h> +# endif +# if defined(HAVE_SYS_SELECT_H) +# include <sys/select.h> +# endif + +#ifndef INADDR_NONE +#define INADDR_NONE ((unsigned long) -1) +#endif + +# ifndef HAVE_SOCKLEN_T + typedef unsigned int socklen_t; +# endif + +# ifdef USE_LOCKING +# define FCGI_LOCK(fd) \ + do { \ + struct flock lock; \ + lock.l_type = F_WRLCK; \ + lock.l_start = 0; \ + lock.l_whence = SEEK_SET; \ + lock.l_len = 0; \ + if (fcntl(fd, F_SETLKW, &lock) != -1) { \ + break; \ + } else if (errno != EINTR || in_shutdown) { \ + return -1; \ + } \ + } while (1) + +# define FCGI_UNLOCK(fd) \ + do { \ + int orig_errno = errno; \ + while (1) { \ + struct flock lock; \ + lock.l_type = F_UNLCK; \ + lock.l_start = 0; \ + lock.l_whence = SEEK_SET; \ + lock.l_len = 0; \ + if (fcntl(fd, F_SETLK, &lock) != -1) { \ + break; \ + } else if (errno != EINTR) { \ + return -1; \ + } \ + } \ + errno = orig_errno; \ + } while (0) +# else +# define FCGI_LOCK(fd) +# define FCGI_UNLOCK(fd) +# endif + +#endif + +#include "fastcgi.h" + +typedef struct _fcgi_header { + unsigned char version; + unsigned char type; + unsigned char requestIdB1; + unsigned char requestIdB0; + unsigned char contentLengthB1; + unsigned char contentLengthB0; + unsigned char paddingLength; + unsigned char reserved; +} fcgi_header; + +typedef struct _fcgi_begin_request { + unsigned char roleB1; + unsigned char roleB0; + unsigned char flags; + unsigned char reserved[5]; +} fcgi_begin_request; + +typedef struct _fcgi_begin_request_rec { + fcgi_header hdr; + fcgi_begin_request body; +} fcgi_begin_request_rec; + +typedef struct _fcgi_end_request { + unsigned char appStatusB3; + unsigned char appStatusB2; + unsigned char appStatusB1; + unsigned char appStatusB0; + unsigned char protocolStatus; + unsigned char reserved[3]; +} fcgi_end_request; + +typedef struct _fcgi_end_request_rec { + fcgi_header hdr; + fcgi_end_request body; +} fcgi_end_request_rec; + +typedef struct _fcgi_hash_bucket { + unsigned int hash_value; + unsigned int var_len; + char *var; + unsigned int val_len; + char *val; + struct _fcgi_hash_bucket *next; + struct _fcgi_hash_bucket *list_next; +} fcgi_hash_bucket; + +typedef struct _fcgi_hash_buckets { + unsigned int idx; + struct _fcgi_hash_buckets *next; + struct _fcgi_hash_bucket data[FCGI_HASH_TABLE_SIZE]; +} fcgi_hash_buckets; + +typedef struct _fcgi_data_seg { + char *pos; + char *end; + struct _fcgi_data_seg *next; + char data[1]; +} fcgi_data_seg; + +typedef struct _fcgi_hash { + fcgi_hash_bucket *hash_table[FCGI_HASH_TABLE_SIZE]; + fcgi_hash_bucket *list; + fcgi_hash_buckets *buckets; + fcgi_data_seg *data; +} fcgi_hash; + +typedef struct _fcgi_req_hook fcgi_req_hook; + +struct _fcgi_req_hook { + void(*on_accept)(); + void(*on_read)(); + void(*on_close)(); +}; + +struct _fcgi_request { + int listen_socket; + int tcp; + int fd; + int id; + int keep; +#ifdef TCP_NODELAY + int nodelay; +#endif + int closed; + int in_len; + int in_pad; + + fcgi_header *out_hdr; + + unsigned char *out_pos; + unsigned char out_buf[1024*8]; + unsigned char reserved[sizeof(fcgi_end_request_rec)]; + + fcgi_req_hook hook; + + int has_env; + fcgi_hash env; +}; + +/* maybe it's better to use weak name instead */ +#ifndef HAVE_ATTRIBUTE_WEAK +static fcgi_logger fcgi_log; +#endif + +typedef union _sa_t { + struct sockaddr sa; + struct sockaddr_un sa_unix; + struct sockaddr_in sa_inet; + struct sockaddr_in6 sa_inet6; +} sa_t; + +static HashTable fcgi_mgmt_vars; + +static int is_initialized = 0; +static int is_fastcgi = 0; +static int in_shutdown = 0; +static sa_t *allowed_clients = NULL; +static sa_t client_sa; + +/* hash table */ +static void fcgi_hash_init(fcgi_hash *h) +{ + memset(h->hash_table, 0, sizeof(h->hash_table)); + h->list = NULL; + h->buckets = (fcgi_hash_buckets*)malloc(sizeof(fcgi_hash_buckets)); + h->buckets->idx = 0; + h->buckets->next = NULL; + h->data = (fcgi_data_seg*)malloc(sizeof(fcgi_data_seg) - 1 + FCGI_HASH_SEG_SIZE); + h->data->pos = h->data->data; + h->data->end = h->data->pos + FCGI_HASH_SEG_SIZE; + h->data->next = NULL; +} + +static void fcgi_hash_destroy(fcgi_hash *h) +{ + fcgi_hash_buckets *b; + fcgi_data_seg *p; + + b = h->buckets; + while (b) { + fcgi_hash_buckets *q = b; + b = b->next; + free(q); + } + p = h->data; + while (p) { + fcgi_data_seg *q = p; + p = p->next; + free(q); + } +} + +static void fcgi_hash_clean(fcgi_hash *h) +{ + memset(h->hash_table, 0, sizeof(h->hash_table)); + h->list = NULL; + /* delete all bucket blocks except the first one */ + while (h->buckets->next) { + fcgi_hash_buckets *q = h->buckets; + + h->buckets = h->buckets->next; + free(q); + } + h->buckets->idx = 0; + /* delete all data segments except the first one */ + while (h->data->next) { + fcgi_data_seg *q = h->data; + + h->data = h->data->next; + free(q); + } + h->data->pos = h->data->data; +} + +static inline char* fcgi_hash_strndup(fcgi_hash *h, char *str, unsigned int str_len) +{ + char *ret; + + if (UNEXPECTED(h->data->pos + str_len + 1 >= h->data->end)) { + unsigned int seg_size = (str_len + 1 > FCGI_HASH_SEG_SIZE) ? str_len + 1 : FCGI_HASH_SEG_SIZE; + fcgi_data_seg *p = (fcgi_data_seg*)malloc(sizeof(fcgi_data_seg) - 1 + seg_size); + + p->pos = p->data; + p->end = p->pos + seg_size; + p->next = h->data; + h->data = p; + } + ret = h->data->pos; + memcpy(ret, str, str_len); + ret[str_len] = 0; + h->data->pos += str_len + 1; + return ret; +} + +static char* fcgi_hash_set(fcgi_hash *h, unsigned int hash_value, char *var, unsigned int var_len, char *val, unsigned int val_len) +{ + unsigned int idx = hash_value & FCGI_HASH_TABLE_MASK; + fcgi_hash_bucket *p = h->hash_table[idx]; + + while (UNEXPECTED(p != NULL)) { + if (UNEXPECTED(p->hash_value == hash_value) && + p->var_len == var_len && + memcmp(p->var, var, var_len) == 0) { + + p->val_len = val_len; + p->val = fcgi_hash_strndup(h, val, val_len); + return p->val; + } + p = p->next; + } + + if (UNEXPECTED(h->buckets->idx >= FCGI_HASH_TABLE_SIZE)) { + fcgi_hash_buckets *b = (fcgi_hash_buckets*)malloc(sizeof(fcgi_hash_buckets)); + b->idx = 0; + b->next = h->buckets; + h->buckets = b; + } + p = h->buckets->data + h->buckets->idx; + h->buckets->idx++; + p->next = h->hash_table[idx]; + h->hash_table[idx] = p; + p->list_next = h->list; + h->list = p; + p->hash_value = hash_value; + p->var_len = var_len; + p->var = fcgi_hash_strndup(h, var, var_len); + p->val_len = val_len; + p->val = fcgi_hash_strndup(h, val, val_len); + return p->val; +} + +static void fcgi_hash_del(fcgi_hash *h, unsigned int hash_value, char *var, unsigned int var_len) +{ + unsigned int idx = hash_value & FCGI_HASH_TABLE_MASK; + fcgi_hash_bucket **p = &h->hash_table[idx]; + + while (*p != NULL) { + if ((*p)->hash_value == hash_value && + (*p)->var_len == var_len && + memcmp((*p)->var, var, var_len) == 0) { + + (*p)->val = NULL; /* NULL value means deleted */ + (*p)->val_len = 0; + *p = (*p)->next; + return; + } + p = &(*p)->next; + } +} + +static char *fcgi_hash_get(fcgi_hash *h, unsigned int hash_value, char *var, unsigned int var_len, unsigned int *val_len) +{ + unsigned int idx = hash_value & FCGI_HASH_TABLE_MASK; + fcgi_hash_bucket *p = h->hash_table[idx]; + + while (p != NULL) { + if (p->hash_value == hash_value && + p->var_len == var_len && + memcmp(p->var, var, var_len) == 0) { + *val_len = p->val_len; + return p->val; + } + p = p->next; + } + return NULL; +} + +static void fcgi_hash_apply(fcgi_hash *h, fcgi_apply_func func, void *arg) +{ + fcgi_hash_bucket *p = h->list; + + while (p) { + if (EXPECTED(p->val != NULL)) { + func(p->var, p->var_len, p->val, p->val_len, arg); + } + p = p->list_next; + } +} + +#ifdef _WIN32 + +static DWORD WINAPI fcgi_shutdown_thread(LPVOID arg) +{ + HANDLE shutdown_event = (HANDLE) arg; + WaitForSingleObject(shutdown_event, INFINITE); + in_shutdown = 1; + return 0; +} + +#else + +static void fcgi_signal_handler(int signo) +{ + if (signo == SIGUSR1 || signo == SIGTERM) { + in_shutdown = 1; + } +} + +static void fcgi_setup_signals(void) +{ + struct sigaction new_sa, old_sa; + + sigemptyset(&new_sa.sa_mask); + new_sa.sa_flags = 0; + new_sa.sa_handler = fcgi_signal_handler; + sigaction(SIGUSR1, &new_sa, NULL); + sigaction(SIGTERM, &new_sa, NULL); + sigaction(SIGPIPE, NULL, &old_sa); + if (old_sa.sa_handler == SIG_DFL) { + sigaction(SIGPIPE, &new_sa, NULL); + } +} +#endif + +void fcgi_set_in_shutdown(int new_value) +{ + in_shutdown = new_value; +} + +int fcgi_in_shutdown(void) +{ + return in_shutdown; +} + +void fcgi_terminate(void) +{ + in_shutdown = 1; +} + +#ifndef HAVE_ATTRIBUTE_WEAK +void fcgi_set_logger(fcgi_logger lg) { + fcgi_log = lg; +} +#else +void __attribute__((weak)) fcgi_log(int type, const char *format, ...) { + va_list ap; + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); +} +#endif + +int fcgi_init(void) +{ + if (!is_initialized) { +#ifndef _WIN32 + sa_t sa; + socklen_t len = sizeof(sa); +#endif + zend_hash_init(&fcgi_mgmt_vars, 8, NULL, fcgi_free_mgmt_var_cb, 1); + fcgi_set_mgmt_var("FCGI_MPXS_CONNS", sizeof("FCGI_MPXS_CONNS")-1, "0", sizeof("0")-1); + + is_initialized = 1; +#ifdef _WIN32 +# if 0 + /* TODO: Support for TCP sockets */ + WSADATA wsaData; + + if (WSAStartup(MAKEWORD(2,0), &wsaData)) { + fprintf(stderr, "Error starting Windows Sockets. Error: %d", WSAGetLastError()); + return 0; + } +# endif + if ((GetStdHandle(STD_OUTPUT_HANDLE) == INVALID_HANDLE_VALUE) && + (GetStdHandle(STD_ERROR_HANDLE) == INVALID_HANDLE_VALUE) && + (GetStdHandle(STD_INPUT_HANDLE) != INVALID_HANDLE_VALUE)) { + char *str; + DWORD pipe_mode = PIPE_READMODE_BYTE | PIPE_WAIT; + HANDLE pipe = GetStdHandle(STD_INPUT_HANDLE); + + SetNamedPipeHandleState(pipe, &pipe_mode, NULL, NULL); + + str = getenv("_FCGI_SHUTDOWN_EVENT_"); + if (str != NULL) { + zend_long ev; + HANDLE shutdown_event; + + ZEND_ATOL(ev, str); + shutdown_event = (HANDLE) ev; + if (!CreateThread(NULL, 0, fcgi_shutdown_thread, + shutdown_event, 0, NULL)) { + return -1; + } + } + str = getenv("_FCGI_MUTEX_"); + if (str != NULL) { + zend_long mt; + ZEND_ATOL(mt, str); + fcgi_accept_mutex = (HANDLE) mt; + } + return is_fastcgi = 1; + } else { + return is_fastcgi = 0; + } +#else + errno = 0; + if (getpeername(0, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) { + fcgi_setup_signals(); + return is_fastcgi = 1; + } else { + return is_fastcgi = 0; + } +#endif + } + return is_fastcgi; +} + + +int fcgi_is_fastcgi(void) +{ + if (!is_initialized) { + return fcgi_init(); + } else { + return is_fastcgi; + } +} + +void fcgi_shutdown(void) +{ + if (is_initialized) { + zend_hash_destroy(&fcgi_mgmt_vars); + } + is_fastcgi = 0; + if (allowed_clients) { + free(allowed_clients); + } +} + +#ifdef _WIN32 +/* Do some black magic with the NT security API. + * We prepare a DACL (Discretionary Access Control List) so that + * we, the creator, are allowed all access, while "Everyone Else" + * is only allowed to read and write to the pipe. + * This avoids security issues on shared hosts where a luser messes + * with the lower-level pipe settings and screws up the FastCGI service. + */ +static PACL prepare_named_pipe_acl(PSECURITY_DESCRIPTOR sd, LPSECURITY_ATTRIBUTES sa) +{ + DWORD req_acl_size; + char everyone_buf[32], owner_buf[32]; + PSID sid_everyone, sid_owner; + SID_IDENTIFIER_AUTHORITY + siaWorld = SECURITY_WORLD_SID_AUTHORITY, + siaCreator = SECURITY_CREATOR_SID_AUTHORITY; + PACL acl; + + sid_everyone = (PSID)&everyone_buf; + sid_owner = (PSID)&owner_buf; + + req_acl_size = sizeof(ACL) + + (2 * ((sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetSidLengthRequired(1))); + + acl = malloc(req_acl_size); + + if (acl == NULL) { + return NULL; + } + + if (!InitializeSid(sid_everyone, &siaWorld, 1)) { + goto out_fail; + } + *GetSidSubAuthority(sid_everyone, 0) = SECURITY_WORLD_RID; + + if (!InitializeSid(sid_owner, &siaCreator, 1)) { + goto out_fail; + } + *GetSidSubAuthority(sid_owner, 0) = SECURITY_CREATOR_OWNER_RID; + + if (!InitializeAcl(acl, req_acl_size, ACL_REVISION)) { + goto out_fail; + } + + if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_GENERIC_READ | FILE_GENERIC_WRITE, sid_everyone)) { + goto out_fail; + } + + if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_ALL_ACCESS, sid_owner)) { + goto out_fail; + } + + if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) { + goto out_fail; + } + + if (!SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE)) { + goto out_fail; + } + + sa->lpSecurityDescriptor = sd; + + return acl; + +out_fail: + free(acl); + return NULL; +} +#endif + +static int is_port_number(const char *bindpath) +{ + while (*bindpath) { + if (*bindpath < '0' || *bindpath > '9') { + return 0; + } + bindpath++; + } + return 1; +} + +int fcgi_listen(const char *path, int backlog) +{ + char *s; + int tcp = 0; + char host[MAXPATHLEN]; + short port = 0; + int listen_socket; + sa_t sa; + socklen_t sock_len; +#ifdef SO_REUSEADDR +# ifdef _WIN32 + BOOL reuse = 1; +# else + int reuse = 1; +# endif +#endif + + if ((s = strchr(path, ':'))) { + port = atoi(s+1); + if (port != 0 && (s-path) < MAXPATHLEN) { + strncpy(host, path, s-path); + host[s-path] = '\0'; + tcp = 1; + } + } else if (is_port_number(path)) { + port = atoi(path); + if (port != 0) { + host[0] = '\0'; + tcp = 1; + } + } + + /* Prepare socket address */ + if (tcp) { + memset(&sa.sa_inet, 0, sizeof(sa.sa_inet)); + sa.sa_inet.sin_family = AF_INET; + sa.sa_inet.sin_port = htons(port); + sock_len = sizeof(sa.sa_inet); + + if (!*host || !strncmp(host, "*", sizeof("*")-1)) { + sa.sa_inet.sin_addr.s_addr = htonl(INADDR_ANY); + } else { + sa.sa_inet.sin_addr.s_addr = inet_addr(host); + if (sa.sa_inet.sin_addr.s_addr == INADDR_NONE) { + struct hostent *hep; + + if(strlen(host) > MAXFQDNLEN) { + hep = NULL; + } else { + hep = gethostbyname(host); + } + if (!hep || hep->h_addrtype != AF_INET || !hep->h_addr_list[0]) { + fcgi_log(FCGI_ERROR, "Cannot resolve host name '%s'!\n", host); + return -1; + } else if (hep->h_addr_list[1]) { + fcgi_log(FCGI_ERROR, "Host '%s' has multiple addresses. You must choose one explicitly!\n", host); + return -1; + } + sa.sa_inet.sin_addr.s_addr = ((struct in_addr*)hep->h_addr_list[0])->s_addr; + } + } + } else { +#ifdef _WIN32 + SECURITY_DESCRIPTOR sd; + SECURITY_ATTRIBUTES saw; + PACL acl; + HANDLE namedPipe; + + memset(&sa, 0, sizeof(saw)); + saw.nLength = sizeof(saw); + saw.bInheritHandle = FALSE; + acl = prepare_named_pipe_acl(&sd, &saw); + + namedPipe = CreateNamedPipe(path, + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_READMODE_BYTE, + PIPE_UNLIMITED_INSTANCES, + 8192, 8192, 0, &saw); + if (namedPipe == INVALID_HANDLE_VALUE) { + return -1; + } + listen_socket = _open_osfhandle((intptr_t)namedPipe, 0); + if (!is_initialized) { + fcgi_init(); + } + is_fastcgi = 1; + return listen_socket; + +#else + int path_len = strlen(path); + + if (path_len >= sizeof(sa.sa_unix.sun_path)) { + fcgi_log(FCGI_ERROR, "Listening socket's path name is too long.\n"); + return -1; + } + + memset(&sa.sa_unix, 0, sizeof(sa.sa_unix)); + sa.sa_unix.sun_family = AF_UNIX; + memcpy(sa.sa_unix.sun_path, path, path_len + 1); + sock_len = (size_t)(((struct sockaddr_un *)0)->sun_path) + path_len; +#ifdef HAVE_SOCKADDR_UN_SUN_LEN + sa.sa_unix.sun_len = sock_len; +#endif + unlink(path); +#endif + } + + /* Create, bind socket and start listen on it */ + if ((listen_socket = socket(sa.sa.sa_family, SOCK_STREAM, 0)) < 0 || +#ifdef SO_REUSEADDR + setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)) < 0 || +#endif + bind(listen_socket, (struct sockaddr *) &sa, sock_len) < 0 || + listen(listen_socket, backlog) < 0) { + + fcgi_log(FCGI_ERROR, "Cannot bind/listen socket - [%d] %s.\n",errno, strerror(errno)); + return -1; + } + + if (!tcp) { + chmod(path, 0777); + } else { + char *ip = getenv("FCGI_WEB_SERVER_ADDRS"); + char *cur, *end; + int n; + + if (ip) { + ip = strdup(ip); + cur = ip; + n = 0; + while (*cur) { + if (*cur == ',') n++; + cur++; + } + allowed_clients = malloc(sizeof(sa_t) * (n+2)); + n = 0; + cur = ip; + while (cur) { + end = strchr(cur, ','); + if (end) { + *end = 0; + end++; + } + if (inet_pton(AF_INET, cur, &allowed_clients[n].sa_inet.sin_addr)>0) { + allowed_clients[n].sa.sa_family = AF_INET; + n++; +#ifdef HAVE_IPV6 + } else if (inet_pton(AF_INET6, cur, &allowed_clients[n].sa_inet6.sin6_addr)>0) { + allowed_clients[n].sa.sa_family = AF_INET6; + n++; +#endif + } else { + fcgi_log(FCGI_ERROR, "Wrong IP address '%s' in listen.allowed_clients", cur); + } + cur = end; + } + allowed_clients[n].sa.sa_family = 0; + free(ip); + if (!n) { + fcgi_log(FCGI_ERROR, "There are no allowed addresses"); + /* don't clear allowed_clients as it will create an "open for all" security issue */ + } + } + } + + if (!is_initialized) { + fcgi_init(); + } + is_fastcgi = 1; + +#ifdef _WIN32 + if (tcp) { + listen_socket = _open_osfhandle((intptr_t)listen_socket, 0); + } +#else + fcgi_setup_signals(); +#endif + return listen_socket; +} + +void fcgi_set_allowed_clients(char *ip) +{ + char *cur, *end; + int n; + + if (ip) { + ip = strdup(ip); + cur = ip; + n = 0; + while (*cur) { + if (*cur == ',') n++; + cur++; + } + if (allowed_clients) free(allowed_clients); + allowed_clients = malloc(sizeof(sa_t) * (n+2)); + n = 0; + cur = ip; + while (cur) { + end = strchr(cur, ','); + if (end) { + *end = 0; + end++; + } + if (inet_pton(AF_INET, cur, &allowed_clients[n].sa_inet.sin_addr)>0) { + allowed_clients[n].sa.sa_family = AF_INET; + n++; +#ifdef HAVE_IPV6 + } else if (inet_pton(AF_INET6, cur, &allowed_clients[n].sa_inet6.sin6_addr)>0) { + allowed_clients[n].sa.sa_family = AF_INET6; + n++; +#endif + } else { + fcgi_log(FCGI_ERROR, "Wrong IP address '%s' in listen.allowed_clients", cur); + } + cur = end; + } + allowed_clients[n].sa.sa_family = 0; + free(ip); + if (!n) { + fcgi_log(FCGI_ERROR, "There are no allowed addresses"); + /* don't clear allowed_clients as it will create an "open for all" security issue */ + } + } +} + +static void fcgi_hook_dummy() { + return; +} + +fcgi_request *fcgi_init_request(int listen_socket, void(*on_accept)(), void(*on_read)(), void(*on_close)()) +{ + fcgi_request *req = calloc(1, sizeof(fcgi_request)); + req->listen_socket = listen_socket; + req->fd = -1; + req->id = -1; + + /* + req->in_len = 0; + req->in_pad = 0; + + req->out_hdr = NULL; + +#ifdef TCP_NODELAY + req->nodelay = 0; +#endif + + req->env = NULL; + req->has_env = 0; + + */ + req->out_pos = req->out_buf; + req->hook.on_accept = on_accept ? on_accept : fcgi_hook_dummy; + req->hook.on_read = on_read ? on_read : fcgi_hook_dummy; + req->hook.on_close = on_close ? on_close : fcgi_hook_dummy; + +#ifdef _WIN32 + req->tcp = !GetNamedPipeInfo((HANDLE)_get_osfhandle(req->listen_socket), NULL, NULL, NULL, NULL); +#endif + + fcgi_hash_init(&req->env); + + return req; +} + +void fcgi_destroy_request(fcgi_request *req) { + fcgi_hash_destroy(&req->env); + free(req); +} + +static inline ssize_t safe_write(fcgi_request *req, const void *buf, size_t count) +{ + int ret; + size_t n = 0; + + do { +#ifdef _WIN32 + size_t tmp; +#endif + errno = 0; +#ifdef _WIN32 + tmp = count - n; + + if (!req->tcp) { + unsigned int out_len = tmp > UINT_MAX ? UINT_MAX : (unsigned int)tmp; + + ret = write(req->fd, ((char*)buf)+n, out_len); + } else { + int out_len = tmp > INT_MAX ? INT_MAX : (int)tmp; + + ret = send(req->fd, ((char*)buf)+n, out_len, 0); + if (ret <= 0) { + errno = WSAGetLastError(); + } + } +#else + ret = write(req->fd, ((char*)buf)+n, count-n); +#endif + if (ret > 0) { + n += ret; + } else if (ret <= 0 && errno != 0 && errno != EINTR) { + return ret; + } + } while (n != count); + return n; +} + +static inline ssize_t safe_read(fcgi_request *req, const void *buf, size_t count) +{ + int ret; + size_t n = 0; + + do { +#ifdef _WIN32 + size_t tmp; +#endif + errno = 0; +#ifdef _WIN32 + tmp = count - n; + + if (!req->tcp) { + unsigned int in_len = tmp > UINT_MAX ? UINT_MAX : (unsigned int)tmp; + + ret = read(req->fd, ((char*)buf)+n, in_len); + } else { + int in_len = tmp > INT_MAX ? INT_MAX : (int)tmp; + + ret = recv(req->fd, ((char*)buf)+n, in_len, 0); + if (ret <= 0) { + errno = WSAGetLastError(); + } + } +#else + ret = read(req->fd, ((char*)buf)+n, count-n); +#endif + if (ret > 0) { + n += ret; + } else if (ret == 0 && errno == 0) { + return n; + } else if (ret <= 0 && errno != 0 && errno != EINTR) { + return ret; + } + } while (n != count); + return n; +} + +static inline int fcgi_make_header(fcgi_header *hdr, fcgi_request_type type, int req_id, int len) +{ + int pad = ((len + 7) & ~7) - len; + + hdr->contentLengthB0 = (unsigned char)(len & 0xff); + hdr->contentLengthB1 = (unsigned char)((len >> 8) & 0xff); + hdr->paddingLength = (unsigned char)pad; + hdr->requestIdB0 = (unsigned char)(req_id & 0xff); + hdr->requestIdB1 = (unsigned char)((req_id >> 8) & 0xff); + hdr->reserved = 0; + hdr->type = type; + hdr->version = FCGI_VERSION_1; + if (pad) { + memset(((unsigned char*)hdr) + sizeof(fcgi_header) + len, 0, pad); + } + return pad; +} + +static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *end) +{ + unsigned int name_len, val_len; + + while (p < end) { + name_len = *p++; + if (UNEXPECTED(name_len >= 128)) { + if (UNEXPECTED(p + 3 >= end)) return 0; + name_len = ((name_len & 0x7f) << 24); + name_len |= (*p++ << 16); + name_len |= (*p++ << 8); + name_len |= *p++; + } + if (UNEXPECTED(p >= end)) return 0; + val_len = *p++; + if (UNEXPECTED(val_len >= 128)) { + if (UNEXPECTED(p + 3 >= end)) return 0; + val_len = ((val_len & 0x7f) << 24); + val_len |= (*p++ << 16); + val_len |= (*p++ << 8); + val_len |= *p++; + } + if (UNEXPECTED(name_len + val_len > (unsigned int) (end - p))) { + /* Malformated request */ + return 0; + } + fcgi_hash_set(&req->env, FCGI_HASH_FUNC(p, name_len), (char*)p, name_len, (char*)p + name_len, val_len); + p += name_len + val_len; + } + return 1; +} + +static int fcgi_read_request(fcgi_request *req) +{ + fcgi_header hdr; + int len, padding; + unsigned char buf[FCGI_MAX_LENGTH+8]; + + req->keep = 0; + req->closed = 0; + req->in_len = 0; + req->out_hdr = NULL; + req->out_pos = req->out_buf; + req->has_env = 1; + + if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) || + hdr.version < FCGI_VERSION_1) { + return 0; + } + + len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0; + padding = hdr.paddingLength; + + while (hdr.type == FCGI_STDIN && len == 0) { + if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) || + hdr.version < FCGI_VERSION_1) { + return 0; + } + + len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0; + padding = hdr.paddingLength; + } + + if (len + padding > FCGI_MAX_LENGTH) { + return 0; + } + + req->id = (hdr.requestIdB1 << 8) + hdr.requestIdB0; + + if (hdr.type == FCGI_BEGIN_REQUEST && len == sizeof(fcgi_begin_request)) { + if (safe_read(req, buf, len+padding) != len+padding) { + return 0; + } + + req->keep = (((fcgi_begin_request*)buf)->flags & FCGI_KEEP_CONN); +#ifdef TCP_NODELAY + if (req->keep && req->tcp && !req->nodelay) { +# ifdef _WIN32 + BOOL on = 1; +# else + int on = 1; +# endif + + setsockopt(req->fd, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on)); + req->nodelay = 1; + } +#endif + switch ((((fcgi_begin_request*)buf)->roleB1 << 8) + ((fcgi_begin_request*)buf)->roleB0) { + case FCGI_RESPONDER: + fcgi_hash_set(&req->env, FCGI_HASH_FUNC("FCGI_ROLE", sizeof("FCGI_ROLE")-1), "FCGI_ROLE", sizeof("FCGI_ROLE")-1, "RESPONDER", sizeof("RESPONDER")-1); + break; + case FCGI_AUTHORIZER: + fcgi_hash_set(&req->env, FCGI_HASH_FUNC("FCGI_ROLE", sizeof("FCGI_ROLE")-1), "FCGI_ROLE", sizeof("FCGI_ROLE")-1, "AUTHORIZER", sizeof("AUTHORIZER")-1); + break; + case FCGI_FILTER: + fcgi_hash_set(&req->env, FCGI_HASH_FUNC("FCGI_ROLE", sizeof("FCGI_ROLE")-1), "FCGI_ROLE", sizeof("FCGI_ROLE")-1, "FILTER", sizeof("FILTER")-1); + break; + default: + return 0; + } + + if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) || + hdr.version < FCGI_VERSION_1) { + return 0; + } + + len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0; + padding = hdr.paddingLength; + + while (hdr.type == FCGI_PARAMS && len > 0) { + if (len + padding > FCGI_MAX_LENGTH) { + return 0; + } + + if (safe_read(req, buf, len+padding) != len+padding) { + req->keep = 0; + return 0; + } + + if (!fcgi_get_params(req, buf, buf+len)) { + req->keep = 0; + return 0; + } + + if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) || + hdr.version < FCGI_VERSION_1) { + req->keep = 0; + return 0; + } + len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0; + padding = hdr.paddingLength; + } + } else if (hdr.type == FCGI_GET_VALUES) { + unsigned char *p = buf + sizeof(fcgi_header); + zval *value; + unsigned int zlen; + fcgi_hash_bucket *q; + + if (safe_read(req, buf, len+padding) != len+padding) { + req->keep = 0; + return 0; + } + + if (!fcgi_get_params(req, buf, buf+len)) { + req->keep = 0; + return 0; + } + + q = req->env.list; + while (q != NULL) { + if ((value = zend_hash_str_find(&fcgi_mgmt_vars, q->var, q->var_len)) == NULL) { + q = q->list_next; + continue; + } + zlen = (unsigned int)Z_STRLEN_P(value); + if ((p + 4 + 4 + q->var_len + zlen) >= (buf + sizeof(buf))) { + break; + } + if (q->var_len < 0x80) { + *p++ = q->var_len; + } else { + *p++ = ((q->var_len >> 24) & 0xff) | 0x80; + *p++ = (q->var_len >> 16) & 0xff; + *p++ = (q->var_len >> 8) & 0xff; + *p++ = q->var_len & 0xff; + } + if (zlen < 0x80) { + *p++ = zlen; + } else { + *p++ = ((zlen >> 24) & 0xff) | 0x80; + *p++ = (zlen >> 16) & 0xff; + *p++ = (zlen >> 8) & 0xff; + *p++ = zlen & 0xff; + } + memcpy(p, q->var, q->var_len); + p += q->var_len; + memcpy(p, Z_STRVAL_P(value), zlen); + p += zlen; + q = q->list_next; + } + len = (int)(p - buf - sizeof(fcgi_header)); + len += fcgi_make_header((fcgi_header*)buf, FCGI_GET_VALUES_RESULT, 0, len); + if (safe_write(req, buf, sizeof(fcgi_header) + len) != (ssize_t)sizeof(fcgi_header)+len) { + req->keep = 0; + return 0; + } + return 0; + } else { + return 0; + } + + return 1; +} + +int fcgi_read(fcgi_request *req, char *str, int len) +{ + int ret, n, rest; + fcgi_header hdr; + unsigned char buf[255]; + + n = 0; + rest = len; + while (rest > 0) { + if (req->in_len == 0) { + if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) || + hdr.version < FCGI_VERSION_1 || + hdr.type != FCGI_STDIN) { + req->keep = 0; + return 0; + } + req->in_len = (hdr.contentLengthB1 << 8) | hdr.contentLengthB0; + req->in_pad = hdr.paddingLength; + if (req->in_len == 0) { + return n; + } + } + + if (req->in_len >= rest) { + ret = (int)safe_read(req, str, rest); + } else { + ret = (int)safe_read(req, str, req->in_len); + } + if (ret < 0) { + req->keep = 0; + return ret; + } else if (ret > 0) { + req->in_len -= ret; + rest -= ret; + n += ret; + str += ret; + if (req->in_len == 0) { + if (req->in_pad) { + if (safe_read(req, buf, req->in_pad) != req->in_pad) { + req->keep = 0; + return ret; + } + } + } else { + return n; + } + } else { + return n; + } + } + return n; +} + +void fcgi_close(fcgi_request *req, int force, int destroy) +{ + if (destroy && req->has_env) { + fcgi_hash_clean(&req->env); + req->has_env = 0; + } + +#ifdef _WIN32 + if (is_impersonate && !req->tcp) { + RevertToSelf(); + } +#endif + + if ((force || !req->keep) && req->fd >= 0) { +#ifdef _WIN32 + if (!req->tcp) { + HANDLE pipe = (HANDLE)_get_osfhandle(req->fd); + + if (!force) { + FlushFileBuffers(pipe); + } + DisconnectNamedPipe(pipe); + } else { + if (!force) { + fcgi_header buf; + + shutdown(req->fd, 1); + /* read the last FCGI_STDIN header (it may be omitted) */ + recv(req->fd, (char *)(&buf), sizeof(buf), 0); + } + closesocket(req->fd); + } +#else + if (!force) { + fcgi_header buf; + + shutdown(req->fd, 1); + /* read the last FCGI_STDIN header (it may be omitted) */ + recv(req->fd, (char *)(&buf), sizeof(buf), 0); + } + close(req->fd); +#endif +#ifdef TCP_NODELAY + req->nodelay = 0; +#endif + req->fd = -1; + + req->hook.on_close(); + } +} + +int fcgi_is_closed(fcgi_request *req) +{ + return (req->fd < 0); +} + +static int fcgi_is_allowed() { + int i; + + if (client_sa.sa.sa_family == AF_UNIX) { + return 1; + } + if (!allowed_clients) { + return 1; + } + if (client_sa.sa.sa_family == AF_INET) { + for (i = 0; allowed_clients[i].sa.sa_family ; i++) { + if (allowed_clients[i].sa.sa_family == AF_INET + && !memcmp(&client_sa.sa_inet.sin_addr, &allowed_clients[i].sa_inet.sin_addr, 4)) { + return 1; + } + } + } +#ifdef HAVE_IPV6 + if (client_sa.sa.sa_family == AF_INET6) { + for (i = 0; allowed_clients[i].sa.sa_family ; i++) { + if (allowed_clients[i].sa.sa_family == AF_INET6 + && !memcmp(&client_sa.sa_inet6.sin6_addr, &allowed_clients[i].sa_inet6.sin6_addr, 12)) { + return 1; + } +#ifdef IN6_IS_ADDR_V4MAPPED + if (allowed_clients[i].sa.sa_family == AF_INET + && IN6_IS_ADDR_V4MAPPED(&client_sa.sa_inet6.sin6_addr) + && !memcmp(((char *)&client_sa.sa_inet6.sin6_addr)+12, &allowed_clients[i].sa_inet.sin_addr, 4)) { + return 1; + } +#endif + } + } +#endif + + return 0; +} + +int fcgi_accept_request(fcgi_request *req) +{ +#ifdef _WIN32 + HANDLE pipe; + OVERLAPPED ov; +#endif + + while (1) { + if (req->fd < 0) { + while (1) { + if (in_shutdown) { + return -1; + } +#ifdef _WIN32 + if (!req->tcp) { + pipe = (HANDLE)_get_osfhandle(req->listen_socket); + FCGI_LOCK(req->listen_socket); + ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!ConnectNamedPipe(pipe, &ov)) { + errno = GetLastError(); + if (errno == ERROR_IO_PENDING) { + while (WaitForSingleObject(ov.hEvent, 1000) == WAIT_TIMEOUT) { + if (in_shutdown) { + CloseHandle(ov.hEvent); + FCGI_UNLOCK(req->listen_socket); + return -1; + } + } + } else if (errno != ERROR_PIPE_CONNECTED) { + } + } + CloseHandle(ov.hEvent); + req->fd = req->listen_socket; + FCGI_UNLOCK(req->listen_socket); + } else { + SOCKET listen_socket = (SOCKET)_get_osfhandle(req->listen_socket); +#else + { + int listen_socket = req->listen_socket; +#endif + sa_t sa; + socklen_t len = sizeof(sa); + + req->hook.on_accept(); + + FCGI_LOCK(req->listen_socket); + req->fd = accept(listen_socket, (struct sockaddr *)&sa, &len); + FCGI_UNLOCK(req->listen_socket); + + client_sa = sa; + if (req->fd >= 0 && !fcgi_is_allowed()) { + fcgi_log(FCGI_ERROR, "Connection disallowed: IP address '%s' has been dropped.", fcgi_get_last_client_ip()); + closesocket(req->fd); + req->fd = -1; + continue; + } + } + +#ifdef _WIN32 + if (req->fd < 0 && (in_shutdown || errno != EINTR)) { +#else + if (req->fd < 0 && (in_shutdown || (errno != EINTR && errno != ECONNABORTED))) { +#endif + return -1; + } + +#ifdef _WIN32 + break; +#else + if (req->fd >= 0) { +#if defined(HAVE_SYS_POLL_H) && defined(HAVE_POLL) + struct pollfd fds; + int ret; + + req->hook.on_read(); + + fds.fd = req->fd; + fds.events = POLLIN; + fds.revents = 0; + do { + errno = 0; + ret = poll(&fds, 1, 5000); + } while (ret < 0 && errno == EINTR); + if (ret > 0 && (fds.revents & POLLIN)) { + break; + } + fcgi_close(req, 1, 0); +#else + req->hook.on_read(); + + if (req->fd < FD_SETSIZE) { + struct timeval tv = {5,0}; + fd_set set; + int ret; + + FD_ZERO(&set); + FD_SET(req->fd, &set); + do { + errno = 0; + ret = select(req->fd + 1, &set, NULL, NULL, &tv) >= 0; + } while (ret < 0 && errno == EINTR); + if (ret > 0 && FD_ISSET(req->fd, &set)) { + break; + } + fcgi_close(req, 1, 0); + } else { + fcgi_log(FCGI_ERROR, "Too many open file descriptors. FD_SETSIZE limit exceeded."); + fcgi_close(req, 1, 0); + } +#endif + } +#endif + } + } else if (in_shutdown) { + return -1; + } + if (fcgi_read_request(req)) { +#ifdef _WIN32 + if (is_impersonate && !req->tcp) { + pipe = (HANDLE)_get_osfhandle(req->fd); + if (!ImpersonateNamedPipeClient(pipe)) { + fcgi_close(req, 1, 1); + continue; + } + } +#endif + return req->fd; + } else { + fcgi_close(req, 1, 1); + } + } +} + +static inline fcgi_header* open_packet(fcgi_request *req, fcgi_request_type type) +{ + req->out_hdr = (fcgi_header*) req->out_pos; + req->out_hdr->type = type; + req->out_pos += sizeof(fcgi_header); + return req->out_hdr; +} + +static inline void close_packet(fcgi_request *req) +{ + if (req->out_hdr) { + int len = (int)(req->out_pos - ((unsigned char*)req->out_hdr + sizeof(fcgi_header))); + + req->out_pos += fcgi_make_header(req->out_hdr, (fcgi_request_type)req->out_hdr->type, req->id, len); + req->out_hdr = NULL; + } +} + +int fcgi_flush(fcgi_request *req, int close) +{ + int len; + + close_packet(req); + + len = (int)(req->out_pos - req->out_buf); + + if (close) { + fcgi_end_request_rec *rec = (fcgi_end_request_rec*)(req->out_pos); + + fcgi_make_header(&rec->hdr, FCGI_END_REQUEST, req->id, sizeof(fcgi_end_request)); + rec->body.appStatusB3 = 0; + rec->body.appStatusB2 = 0; + rec->body.appStatusB1 = 0; + rec->body.appStatusB0 = 0; + rec->body.protocolStatus = FCGI_REQUEST_COMPLETE; + len += sizeof(fcgi_end_request_rec); + } + + if (safe_write(req, req->out_buf, len) != len) { + req->keep = 0; + req->out_pos = req->out_buf; + return 0; + } + + req->out_pos = req->out_buf; + return 1; +} + +int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len) +{ + int limit, rest; + + if (len <= 0) { + return 0; + } + + if (req->out_hdr && req->out_hdr->type != type) { + close_packet(req); + } +#if 0 + /* Unoptimized, but clear version */ + rest = len; + while (rest > 0) { + limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf); + + if (!req->out_hdr) { + if (limit < sizeof(fcgi_header)) { + if (!fcgi_flush(req, 0)) { + return -1; + } + } + open_packet(req, type); + } + limit = sizeof(req->out_buf) - (req->out_pos - req->out_buf); + if (rest < limit) { + memcpy(req->out_pos, str, rest); + req->out_pos += rest; + return len; + } else { + memcpy(req->out_pos, str, limit); + req->out_pos += limit; + rest -= limit; + str += limit; + if (!fcgi_flush(req, 0)) { + return -1; + } + } + } +#else + /* Optimized version */ + limit = (int)(sizeof(req->out_buf) - (req->out_pos - req->out_buf)); + if (!req->out_hdr) { + limit -= sizeof(fcgi_header); + if (limit < 0) limit = 0; + } + + if (len < limit) { + if (!req->out_hdr) { + open_packet(req, type); + } + memcpy(req->out_pos, str, len); + req->out_pos += len; + } else if (len - limit < sizeof(req->out_buf) - sizeof(fcgi_header)) { + if (!req->out_hdr) { + open_packet(req, type); + } + if (limit > 0) { + memcpy(req->out_pos, str, limit); + req->out_pos += limit; + } + if (!fcgi_flush(req, 0)) { + return -1; + } + if (len > limit) { + open_packet(req, type); + memcpy(req->out_pos, str + limit, len - limit); + req->out_pos += len - limit; + } + } else { + int pos = 0; + int pad; + + close_packet(req); + while ((len - pos) > 0xffff) { + open_packet(req, type); + fcgi_make_header(req->out_hdr, type, req->id, 0xfff8); + req->out_hdr = NULL; + if (!fcgi_flush(req, 0)) { + return -1; + } + if (safe_write(req, str + pos, 0xfff8) != 0xfff8) { + req->keep = 0; + return -1; + } + pos += 0xfff8; + } + + pad = (((len - pos) + 7) & ~7) - (len - pos); + rest = pad ? 8 - pad : 0; + + open_packet(req, type); + fcgi_make_header(req->out_hdr, type, req->id, (len - pos) - rest); + req->out_hdr = NULL; + if (!fcgi_flush(req, 0)) { + return -1; + } + if (safe_write(req, str + pos, (len - pos) - rest) != (len - pos) - rest) { + req->keep = 0; + return -1; + } + if (pad) { + open_packet(req, type); + memcpy(req->out_pos, str + len - rest, rest); + req->out_pos += rest; + } + } +#endif + return len; +} + +int fcgi_finish_request(fcgi_request *req, int force_close) +{ + int ret = 1; + + if (req->fd >= 0) { + if (!req->closed) { + ret = fcgi_flush(req, 1); + req->closed = 1; + } + fcgi_close(req, force_close, 1); + } + return ret; +} + +int fcgi_has_env(fcgi_request *req) +{ + return req && req->has_env; +} + +char* fcgi_getenv(fcgi_request *req, const char* var, int var_len) +{ + unsigned int val_len; + + if (!req) return NULL; + + return fcgi_hash_get(&req->env, FCGI_HASH_FUNC(var, var_len), (char*)var, var_len, &val_len); +} + +char* fcgi_quick_getenv(fcgi_request *req, const char* var, int var_len, unsigned int hash_value) +{ + unsigned int val_len; + + return fcgi_hash_get(&req->env, hash_value, (char*)var, var_len, &val_len); +} + +char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val) +{ + if (!req) return NULL; + if (val == NULL) { + fcgi_hash_del(&req->env, FCGI_HASH_FUNC(var, var_len), var, var_len); + return NULL; + } else { + return fcgi_hash_set(&req->env, FCGI_HASH_FUNC(var, var_len), var, var_len, val, (unsigned int)strlen(val)); + } +} + +char* fcgi_quick_putenv(fcgi_request *req, char* var, int var_len, unsigned int hash_value, char* val) +{ + if (val == NULL) { + fcgi_hash_del(&req->env, hash_value, var, var_len); + return NULL; + } else { + return fcgi_hash_set(&req->env, hash_value, var, var_len, val, (unsigned int)strlen(val)); + } +} + +void fcgi_loadenv(fcgi_request *req, fcgi_apply_func func, zval *array) +{ + fcgi_hash_apply(&req->env, func, array); +} + +#ifdef _WIN32 +void fcgi_impersonate(void) +{ + char *os_name; + + os_name = getenv("OS"); + if (os_name && stricmp(os_name, "Windows_NT") == 0) { + is_impersonate = 1; + } +} +#endif + +void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len) +{ + zval zvalue; + ZVAL_NEW_STR(&zvalue, zend_string_init(value, value_len, 1)); + zend_hash_str_add(&fcgi_mgmt_vars, name, name_len, &zvalue); +} + +void fcgi_free_mgmt_var_cb(zval *zv) +{ + pefree(Z_STR_P(zv), 1); +} + +const char *fcgi_get_last_client_ip() +{ + static char str[INET6_ADDRSTRLEN]; + + /* Ipv4 */ + if (client_sa.sa.sa_family == AF_INET) { + return inet_ntop(client_sa.sa.sa_family, &client_sa.sa_inet.sin_addr, str, INET6_ADDRSTRLEN); + } +#ifdef HAVE_IPV6 +#ifdef IN6_IS_ADDR_V4MAPPED + /* Ipv4-Mapped-Ipv6 */ + if (client_sa.sa.sa_family == AF_INET6 + && IN6_IS_ADDR_V4MAPPED(&client_sa.sa_inet6.sin6_addr)) { + return inet_ntop(AF_INET, ((char *)&client_sa.sa_inet6.sin6_addr)+12, str, INET6_ADDRSTRLEN); + } +#endif + /* Ipv6 */ + if (client_sa.sa.sa_family == AF_INET6) { + return inet_ntop(client_sa.sa.sa_family, &client_sa.sa_inet6.sin6_addr, str, INET6_ADDRSTRLEN); + } +#endif + /* Unix socket */ + return NULL; +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/main/fastcgi.h b/main/fastcgi.h new file mode 100644 index 0000000000..df7d9ed314 --- /dev/null +++ b/main/fastcgi.h @@ -0,0 +1,137 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2015 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Dmitry Stogov <dmitry@zend.com> | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +/* FastCGI protocol */ + +#define FCGI_VERSION_1 1 + +#define FCGI_MAX_LENGTH 0xffff + +#define FCGI_KEEP_CONN 1 + +/* this is near the perfect hash function for most useful FastCGI variables + * which combines efficiency and minimal hash collisions + */ + +#define FCGI_HASH_FUNC(var, var_len) \ + (UNEXPECTED(var_len < 3) ? var_len : \ + (((unsigned int)var[3]) << 2) + \ + (((unsigned int)var[var_len-2]) << 4) + \ + (((unsigned int)var[var_len-1]) << 2) + \ + var_len) + +#define FCGI_GETENV(request, name) \ + fcgi_quick_getenv(request, name, sizeof(name)-1, FCGI_HASH_FUNC(name, sizeof(name)-1)) + +#define FCGI_PUTENV(request, name, value) \ + fcgi_quick_putenv(request, name, sizeof(name)-1, FCGI_HASH_FUNC(name, sizeof(name)-1), value) + +typedef enum _fcgi_role { + FCGI_RESPONDER = 1, + FCGI_AUTHORIZER = 2, + FCGI_FILTER = 3 +} fcgi_role; + +enum { + FCGI_DEBUG = 1, + FCGI_NOTICE = 2, + FCGI_WARNING = 3, + FCGI_ERROR = 4, + FCGI_ALERT = 5, +}; + +typedef enum _fcgi_request_type { + FCGI_BEGIN_REQUEST = 1, /* [in] */ + FCGI_ABORT_REQUEST = 2, /* [in] (not supported) */ + FCGI_END_REQUEST = 3, /* [out] */ + FCGI_PARAMS = 4, /* [in] environment variables */ + FCGI_STDIN = 5, /* [in] post data */ + FCGI_STDOUT = 6, /* [out] response */ + FCGI_STDERR = 7, /* [out] errors */ + FCGI_DATA = 8, /* [in] filter data (not supported) */ + FCGI_GET_VALUES = 9, /* [in] */ + FCGI_GET_VALUES_RESULT = 10 /* [out] */ +} fcgi_request_type; + +typedef enum _fcgi_protocol_status { + FCGI_REQUEST_COMPLETE = 0, + FCGI_CANT_MPX_CONN = 1, + FCGI_OVERLOADED = 2, + FCGI_UNKNOWN_ROLE = 3 +} dcgi_protocol_status; + +/* FastCGI client API */ + +typedef void (*fcgi_apply_func)(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg); + +#define FCGI_HASH_TABLE_SIZE 128 +#define FCGI_HASH_TABLE_MASK (FCGI_HASH_TABLE_SIZE - 1) +#define FCGI_HASH_SEG_SIZE 4096 + +typedef struct _fcgi_request fcgi_request; + +int fcgi_init(void); +void fcgi_shutdown(void); +int fcgi_is_fastcgi(void); +int fcgi_is_closed(fcgi_request *req); +void fcgi_close(fcgi_request *req, int force, int destroy); +int fcgi_in_shutdown(void); +void fcgi_terminate(void); +int fcgi_listen(const char *path, int backlog); +fcgi_request* fcgi_init_request(int listen_socket, void(*on_accept)(), void(*on_read)(), void(*on_close)()); +void fcgi_destroy_request(fcgi_request *req); +void fcgi_set_allowed_clients(char *ip); +int fcgi_accept_request(fcgi_request *req); +int fcgi_finish_request(fcgi_request *req, int force_close); +const char *fcgi_get_last_client_ip(); +void fcgi_set_in_shutdown(int new_value); + +#ifndef HAVE_ATTRIBUTE_WEAK +typedef void (*fcgi_logger)(int type, const char *fmt, ...); +void fcgi_set_logger(fcgi_logger lg); +#endif + +int fcgi_has_env(fcgi_request *req); +char* fcgi_getenv(fcgi_request *req, const char* var, int var_len); +char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val); +char* fcgi_quick_getenv(fcgi_request *req, const char* var, int var_len, unsigned int hash_value); +char* fcgi_quick_putenv(fcgi_request *req, char* var, int var_len, unsigned int hash_value, char* val); +void fcgi_loadenv(fcgi_request *req, fcgi_apply_func load_func, zval *array); + +int fcgi_read(fcgi_request *req, char *str, int len); + +int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int len); +int fcgi_flush(fcgi_request *req, int close); + +#ifdef PHP_WIN32 +void fcgi_impersonate(void); +#endif + +void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len); +void fcgi_free_mgmt_var_cb(zval *zv); + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 25460b38b0..09a07f4f6f 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -53,10 +53,6 @@ #include <sys/socket.h> #endif -#ifndef S_ISREG -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif - #ifdef PHP_WIN32 #include <winsock2.h> #elif defined(NETWARE) && defined(USE_WINSOCK) @@ -94,31 +90,31 @@ PHPAPI ZEND_INI_MH(OnUpdateBaseDir) if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN || stage == PHP_INI_STAGE_ACTIVATE || stage == PHP_INI_STAGE_DEACTIVATE) { /* We're in a PHP_INI_SYSTEM context, no restrictions */ - *p = new_value; + *p = new_value ? ZSTR_VAL(new_value) : NULL; return SUCCESS; } /* Otherwise we're in runtime */ if (!*p || !**p) { /* open_basedir not set yet, go ahead and give it a value */ - *p = new_value; + *p = ZSTR_VAL(new_value); return SUCCESS; } /* Shortcut: When we have a open_basedir and someone tries to unset, we know it'll fail */ - if (!new_value || !*new_value) { + if (!new_value || !*ZSTR_VAL(new_value)) { return FAILURE; } /* Is the proposed open_basedir at least as restrictive as the current setting? */ - ptr = pathbuf = estrdup(new_value); + ptr = pathbuf = estrdup(ZSTR_VAL(new_value)); while (ptr && *ptr) { end = strchr(ptr, DEFAULT_DIR_SEPARATOR); if (end != NULL) { *end = '\0'; end++; } - if (php_check_open_basedir_ex(ptr, 0 TSRMLS_CC) != 0) { + if (php_check_open_basedir_ex(ptr, 0) != 0) { /* At least one portion of this open_basedir is less restrictive than the prior one, FAIL */ efree(pathbuf); return FAILURE; @@ -128,7 +124,7 @@ PHPAPI ZEND_INI_MH(OnUpdateBaseDir) efree(pathbuf); /* Everything checks out, set it */ - *p = new_value; + *p = ZSTR_VAL(new_value); return SUCCESS; } @@ -139,7 +135,7 @@ PHPAPI ZEND_INI_MH(OnUpdateBaseDir) open_basedir. Returns -1 if error or not in the open_basedir, else 0. When open_basedir is NULL, always return 0. */ -PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path TSRMLS_DC) +PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path) { char resolved_name[MAXPATHLEN]; char resolved_basedir[MAXPATHLEN]; @@ -157,42 +153,36 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path strlcpy(local_open_basedir, basedir, sizeof(local_open_basedir)); } - path_len = strlen(path); + path_len = (int)strlen(path); if (path_len > (MAXPATHLEN - 1)) { /* empty and too long paths are invalid */ return -1; } /* normalize and expand path */ - if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) { + if (expand_filepath(path, resolved_name) == NULL) { return -1; } - path_len = strlen(resolved_name); + path_len = (int)strlen(resolved_name); memcpy(path_tmp, resolved_name, path_len + 1); /* safe */ while (VCWD_REALPATH(path_tmp, resolved_name) == NULL) { #if defined(PHP_WIN32) || defined(HAVE_SYMLINK) -#if defined(PHP_WIN32) - if (EG(windows_version_info).dwMajorVersion > 5) { -#endif - if (nesting_level == 0) { - int ret; - char buf[MAXPATHLEN]; + if (nesting_level == 0) { + int ret; + char buf[MAXPATHLEN]; - ret = php_sys_readlink(path_tmp, buf, MAXPATHLEN - 1); - if (ret < 0) { - /* not a broken symlink, move along.. */ - } else { - /* put the real path into the path buffer */ - memcpy(path_tmp, buf, ret); - path_tmp[ret] = '\0'; - } + ret = php_sys_readlink(path_tmp, buf, MAXPATHLEN - 1); + if (ret < 0) { + /* not a broken symlink, move along.. */ + } else { + /* put the real path into the path buffer */ + memcpy(path_tmp, buf, ret); + path_tmp[ret] = '\0'; } -#if defined(PHP_WIN32) } #endif -#endif #if defined(PHP_WIN32) || defined(NETWARE) path_file = strrchr(path_tmp, DEFAULT_SLASH); @@ -211,7 +201,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path if (path_len > 1 && path_tmp[path_len - 2] == ':') { if (path_len != 3) { return -1; - } + } /* this is c:\ */ path_tmp[path_len] = '\0'; } else { @@ -225,13 +215,14 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path } /* Resolve open_basedir to resolved_basedir */ - if (expand_filepath(local_open_basedir, resolved_basedir TSRMLS_CC) != NULL) { + if (expand_filepath(local_open_basedir, resolved_basedir) != NULL) { + int basedir_len = (int)strlen(basedir); /* Handler for basedirs that end with a / */ - resolved_basedir_len = strlen(resolved_basedir); + resolved_basedir_len = (int)strlen(resolved_basedir); #if defined(PHP_WIN32) || defined(NETWARE) - if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR || basedir[strlen(basedir) - 1] == '/') { + if (basedir[basedir_len - 1] == PHP_DIR_SEPARATOR || basedir[basedir_len - 1] == '/') { #else - if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) { + if (basedir[basedir_len - 1] == PHP_DIR_SEPARATOR) { #endif if (resolved_basedir[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) { resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR; @@ -242,7 +233,7 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path resolved_basedir[resolved_basedir_len] = '\0'; } - resolved_name_len = strlen(resolved_name); + resolved_name_len = (int)strlen(resolved_name); if (path_tmp[path_len - 1] == PHP_DIR_SEPARATOR) { if (resolved_name[resolved_name_len - 1] != PHP_DIR_SEPARATOR) { resolved_name[resolved_name_len] = PHP_DIR_SEPARATOR; @@ -283,14 +274,14 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path } /* }}} */ -PHPAPI int php_check_open_basedir(const char *path TSRMLS_DC) +PHPAPI int php_check_open_basedir(const char *path) { - return php_check_open_basedir_ex(path, 1 TSRMLS_CC); + return php_check_open_basedir_ex(path, 1); } /* {{{ php_check_open_basedir */ -PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC) +PHPAPI int php_check_open_basedir_ex(const char *path, int warn) { /* Only check when open_basedir is available */ if (PG(open_basedir) && *PG(open_basedir)) { @@ -301,7 +292,7 @@ PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC) /* Check if the path is too long so we can give a more useful error * message. */ if (strlen(path) > (MAXPATHLEN - 1)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "File name is longer than the maximum allowed path length on this platform (%d): %s", MAXPATHLEN, path); + php_error_docref(NULL, E_WARNING, "File name is longer than the maximum allowed path length on this platform (%d): %s", MAXPATHLEN, path); errno = EINVAL; return -1; } @@ -317,7 +308,7 @@ PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC) end++; } - if (php_check_specific_open_basedir(ptr, path TSRMLS_CC) == 0) { + if (php_check_specific_open_basedir(ptr, path) == 0) { efree(pathbuf); return 0; } @@ -325,7 +316,7 @@ PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC) ptr = end; } if (warn) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s)", path, PG(open_basedir)); + php_error_docref(NULL, E_WARNING, "open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s)", path, PG(open_basedir)); } efree(pathbuf); errno = EPERM; /* we deny permission to open it */ @@ -339,16 +330,21 @@ PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC) /* {{{ php_fopen_and_set_opened_path */ -static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, char **opened_path TSRMLS_DC) +static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, zend_string **opened_path) { FILE *fp; - if (php_check_open_basedir((char *)path TSRMLS_CC)) { + if (php_check_open_basedir((char *)path)) { return NULL; } fp = VCWD_FOPEN(path, mode); if (fp && opened_path) { - *opened_path = expand_filepath_with_mode(path, NULL, NULL, 0, CWD_EXPAND TSRMLS_CC); + //TODO :avoid reallocation + char *tmp = expand_filepath_with_mode(path, NULL, NULL, 0, CWD_EXPAND); + if (tmp) { + *opened_path = zend_string_init(tmp, strlen(tmp), 0); + efree(tmp); + } } return fp; } @@ -356,11 +352,11 @@ static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, c /* {{{ php_fopen_primary_script */ -PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) +PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle) { char *path_info; char *filename = NULL; - char *resolved_path = NULL; + zend_string *resolved_path = NULL; int length; zend_bool orig_display_errors; @@ -401,16 +397,16 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) spprintf(&filename, 0, "%s%c%s%c%s", pw->pw_dir, PHP_DIR_SEPARATOR, PG(user_dir), PHP_DIR_SEPARATOR, s + 1); /* Safe */ } else { filename = SG(request_info).path_translated; - } + } #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) efree(pwbuf); #endif } } else #endif - if (PG(doc_root) && path_info && (length = strlen(PG(doc_root))) && + if (PG(doc_root) && path_info && (length = (int)strlen(PG(doc_root))) && IS_ABSOLUTE_PATH(PG(doc_root), length)) { - int path_len = strlen(path_info); + int path_len = (int)strlen(path_info); filename = emalloc(length + path_len + 2); if (filename) { memcpy(filename, PG(doc_root), length); @@ -428,38 +424,48 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) if (filename) { - resolved_path = zend_resolve_path(filename, strlen(filename) TSRMLS_CC); + resolved_path = zend_resolve_path(filename, (int)strlen(filename)); } if (!resolved_path) { if (SG(request_info).path_translated != filename) { - STR_FREE(filename); + if (filename) { + efree(filename); + } } /* we have to free SG(request_info).path_translated here because * php_destroy_request_info assumes that it will get * freed when the include_names hash is emptied, but * we're not adding it in this case */ - STR_FREE(SG(request_info).path_translated); - SG(request_info).path_translated = NULL; + if (SG(request_info).path_translated) { + efree(SG(request_info).path_translated); + SG(request_info).path_translated = NULL; + } return FAILURE; } - efree(resolved_path); + zend_string_release(resolved_path); orig_display_errors = PG(display_errors); PG(display_errors) = 0; - if (zend_stream_open(filename, file_handle TSRMLS_CC) == FAILURE) { + if (zend_stream_open(filename, file_handle) == FAILURE) { PG(display_errors) = orig_display_errors; if (SG(request_info).path_translated != filename) { - STR_FREE(filename); + if (filename) { + efree(filename); + } + } + if (SG(request_info).path_translated) { + efree(SG(request_info).path_translated); + SG(request_info).path_translated = NULL; } - STR_FREE(SG(request_info).path_translated); /* for same reason as above */ - SG(request_info).path_translated = NULL; return FAILURE; } PG(display_errors) = orig_display_errors; if (SG(request_info).path_translated != filename) { - STR_FREE(SG(request_info).path_translated); /* for same reason as above */ + if (SG(request_info).path_translated) { + efree(SG(request_info).path_translated); + } SG(request_info).path_translated = filename; } @@ -470,13 +476,14 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) /* {{{ php_resolve_path * Returns the realpath for given filename according to include path */ -PHPAPI char *php_resolve_path(const char *filename, int filename_length, const char *path TSRMLS_DC) +PHPAPI zend_string *php_resolve_path(const char *filename, int filename_length, const char *path) { char resolved_path[MAXPATHLEN]; char trypath[MAXPATHLEN]; const char *ptr, *end, *p; const char *actual_path; php_stream_wrapper *wrapper; + zend_string *exec_filename; if (!filename || CHECK_NULL_PATH(filename, filename_length)) { return NULL; @@ -485,23 +492,23 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c /* Don't resolve paths which contain protocol (except of file://) */ for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); if ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/')) { - wrapper = php_stream_locate_url_wrapper(filename, &actual_path, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(filename, &actual_path, STREAM_OPEN_FOR_INCLUDE); if (wrapper == &php_plain_files_wrapper) { - if (tsrm_realpath(actual_path, resolved_path TSRMLS_CC)) { - return estrdup(resolved_path); + if (tsrm_realpath(actual_path, resolved_path)) { + return zend_string_init(resolved_path, strlen(resolved_path), 0); } } return NULL; } - if ((*filename == '.' && - (IS_SLASH(filename[1]) || + if ((*filename == '.' && + (IS_SLASH(filename[1]) || ((filename[1] == '.') && IS_SLASH(filename[2])))) || IS_ABSOLUTE_PATH(filename, filename_length) || !path || !*path) { - if (tsrm_realpath(filename, resolved_path TSRMLS_CC)) { - return estrdup(resolved_path); + if (tsrm_realpath(filename, resolved_path)) { + return zend_string_init(resolved_path, strlen(resolved_path), 0); } else { return NULL; } @@ -531,7 +538,7 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c memcpy(trypath+(end-ptr)+1, filename, filename_length+1); ptr = end+1; } else { - int len = strlen(ptr); + int len = (int)strlen(ptr); if (len + 1 + filename_length + 1 >= MAXPATHLEN) { break; @@ -543,34 +550,34 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c } actual_path = trypath; if (is_stream_wrapper) { - wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE); if (!wrapper) { continue; } else if (wrapper != &php_plain_files_wrapper) { if (wrapper->wops->url_stat) { php_stream_statbuf ssb; - if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) { - return estrdup(trypath); + if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL)) { + return zend_string_init(trypath, strlen(trypath), 0); } } continue; } } - if (tsrm_realpath(actual_path, resolved_path TSRMLS_CC)) { - return estrdup(resolved_path); + if (tsrm_realpath(actual_path, resolved_path)) { + return zend_string_init(resolved_path, strlen(resolved_path), 0); } } /* end provided path */ /* check in calling scripts' current working directory as a fall back case */ - if (zend_is_executing(TSRMLS_C)) { - const char *exec_fname = zend_get_executed_filename(TSRMLS_C); - int exec_fname_length = strlen(exec_fname); + if (zend_is_executing() && + (exec_filename = zend_get_executed_filename_ex()) != NULL) { + const char *exec_fname = ZSTR_VAL(exec_filename); + size_t exec_fname_length = ZSTR_LEN(exec_filename); - while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); - if (exec_fname && exec_fname[0] != '[' && - exec_fname_length > 0 && + while ((--exec_fname_length < SIZE_MAX) && !IS_SLASH(exec_fname[exec_fname_length])); + if (exec_fname_length > 0 && exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) { memcpy(trypath, exec_fname, exec_fname_length + 1); memcpy(trypath+exec_fname_length + 1, filename, filename_length+1); @@ -579,23 +586,23 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c /* Check for stream wrapper */ for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++); if ((*p == ':') && (p - trypath > 1) && (p[1] == '/') && (p[2] == '/')) { - wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(trypath, &actual_path, STREAM_OPEN_FOR_INCLUDE); if (!wrapper) { return NULL; } else if (wrapper != &php_plain_files_wrapper) { if (wrapper->wops->url_stat) { php_stream_statbuf ssb; - if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) { - return estrdup(trypath); + if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL)) { + return zend_string_init(trypath, strlen(trypath), 0); } } return NULL; } } - if (tsrm_realpath(actual_path, resolved_path TSRMLS_CC)) { - return estrdup(resolved_path); + if (tsrm_realpath(actual_path, resolved_path)) { + return zend_string_init(resolved_path, strlen(resolved_path), 0); } } } @@ -608,15 +615,13 @@ PHPAPI char *php_resolve_path(const char *filename, int filename_length, const c * Tries to open a file with a PATH-style list of directories. * If the filename starts with "." or "/", the path is ignored. */ -PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path TSRMLS_DC) +PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path) { char *pathbuf, *ptr, *end; - const char *exec_fname; char trypath[MAXPATHLEN]; FILE *fp; - int path_length; int filename_length; - int exec_fname_length; + zend_string *exec_filename; if (opened_path) { *opened_path = NULL; @@ -626,7 +631,10 @@ PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const c return NULL; } - filename_length = strlen(filename); + filename_length = (int)strlen(filename); +#ifndef PHP_WIN32 + (void) filename_length; +#endif /* Relative path open */ if ((*filename == '.') @@ -634,23 +642,25 @@ PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const c || IS_ABSOLUTE_PATH(filename, filename_length) || (!path || (path && !*path)) ) { - return php_fopen_and_set_opened_path(filename, mode, opened_path TSRMLS_CC); + return php_fopen_and_set_opened_path(filename, mode, opened_path); } /* check in provided path */ /* append the calling scripts' current working directory * as a fall back case */ - if (zend_is_executing(TSRMLS_C)) { - exec_fname = zend_get_executed_filename(TSRMLS_C); - exec_fname_length = strlen(exec_fname); - path_length = strlen(path); + if (zend_is_executing() && + (exec_filename = zend_get_executed_filename_ex()) != NULL) { + const char *exec_fname = ZSTR_VAL(exec_filename); + size_t exec_fname_length = ZSTR_LEN(exec_filename); - while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); + while ((--exec_fname_length < SIZE_MAX) && !IS_SLASH(exec_fname[exec_fname_length])); if ((exec_fname && exec_fname[0] == '[') || exec_fname_length <= 0) { /* [no active file] or no path */ pathbuf = estrdup(path); } else { + size_t path_length = strlen(path); + pathbuf = (char *) emalloc(exec_fname_length + path_length + 1 + 1); memcpy(pathbuf, path, path_length); pathbuf[path_length] = DEFAULT_DIR_SEPARATOR; @@ -670,9 +680,9 @@ PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const c end++; } if (snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename) >= MAXPATHLEN) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN); + php_error_docref(NULL, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN); } - fp = php_fopen_and_set_opened_path(trypath, mode, opened_path TSRMLS_CC); + fp = php_fopen_and_set_opened_path(trypath, mode, opened_path); if (fp) { efree(pathbuf); return fp; @@ -727,31 +737,36 @@ PHPAPI char *php_strip_url_passwd(char *url) /* {{{ expand_filepath */ -PHPAPI char *expand_filepath(const char *filepath, char *real_path TSRMLS_DC) +PHPAPI char *expand_filepath(const char *filepath, char *real_path) { - return expand_filepath_ex(filepath, real_path, NULL, 0 TSRMLS_CC); + return expand_filepath_ex(filepath, real_path, NULL, 0); } /* }}} */ /* {{{ expand_filepath_ex */ -PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len TSRMLS_DC) +PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len) { - return expand_filepath_with_mode(filepath, real_path, relative_to, relative_to_len, CWD_FILEPATH TSRMLS_CC); + return expand_filepath_with_mode(filepath, real_path, relative_to, relative_to_len, CWD_FILEPATH); } /* }}} */ /* {{{ expand_filepath_use_realpath */ -PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int realpath_mode TSRMLS_DC) +PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int realpath_mode) { cwd_state new_state; char cwd[MAXPATHLEN]; int copy_len; + int path_len; if (!filepath[0]) { return NULL; - } else if (IS_ABSOLUTE_PATH(filepath, strlen(filepath))) { + } + + path_len = (int)strlen(filepath); + + if (IS_ABSOLUTE_PATH(filepath, path_len)) { cwd[0] = '\0'; } else { const char *iam = SG(request_info).path_translated; @@ -774,7 +789,7 @@ PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, co /* return a relative file path if for any reason * we cannot cannot getcwd() and the requested, * relatively referenced file is accessible */ - copy_len = strlen(filepath) > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : strlen(filepath); + copy_len = path_len > MAXPATHLEN - 1 ? MAXPATHLEN - 1 : path_len; if (real_path) { memcpy(real_path, filepath, copy_len); real_path[copy_len] = '\0'; @@ -792,9 +807,9 @@ PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, co } new_state.cwd = estrdup(cwd); - new_state.cwd_length = strlen(cwd); + new_state.cwd_length = (int)strlen(cwd); - if (virtual_file_ex(&new_state, filepath, NULL, realpath_mode TSRMLS_CC)) { + if (virtual_file_ex(&new_state, filepath, NULL, realpath_mode)) { efree(new_state.cwd); return NULL; } diff --git a/main/fopen_wrappers.h b/main/fopen_wrappers.h index 8d7dc59bc7..e693b03dba 100644 --- a/main/fopen_wrappers.h +++ b/main/fopen_wrappers.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -25,30 +25,30 @@ BEGIN_EXTERN_C() #include "php_globals.h" #include "php_ini.h" -PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC); -PHPAPI char *expand_filepath(const char *filepath, char *real_path TSRMLS_DC); -PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len TSRMLS_DC); -PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int use_realpath TSRMLS_DC); +PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle); +PHPAPI char *expand_filepath(const char *filepath, char *real_path); +PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len); +PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int use_realpath); -PHPAPI int php_check_open_basedir(const char *path TSRMLS_DC); -PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC); -PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path TSRMLS_DC); +PHPAPI int php_check_open_basedir(const char *path); +PHPAPI int php_check_open_basedir_ex(const char *path, int warn); +PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path); /* {{{ OPENBASEDIR_CHECKPATH(filename) to ease merge between 6.x and 5.x */ #if PHP_API_VERSION < 20100412 # define OPENBASEDIR_CHECKPATH(filename) \ - (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename TSRMLS_CC) + (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) || php_check_open_basedir(filename) #else #define OPENBASEDIR_CHECKPATH(filename) \ - php_check_open_basedir(filename TSRMLS_CC) + php_check_open_basedir(filename) #endif /* }}} */ -PHPAPI int php_check_safe_mode_include_dir(const char *path TSRMLS_DC); +PHPAPI int php_check_safe_mode_include_dir(const char *path); -PHPAPI char *php_resolve_path(const char *filename, int filename_len, const char *path TSRMLS_DC); +PHPAPI zend_string *php_resolve_path(const char *filename, int filename_len, const char *path); -PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path TSRMLS_DC); +PHPAPI FILE *php_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path); PHPAPI char *php_strip_url_passwd(char *path); diff --git a/main/getopt.c b/main/getopt.c index 98aac5326e..4174ec21f2 100644 --- a/main/getopt.c +++ b/main/getopt.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -88,8 +88,8 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char } } if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) { - char *pos; - int arg_end = strlen(argv[*optind])-1; + const char *pos; + int arg_end = (int)strlen(argv[*optind])-1; /* '--' indicates end of args if not followed by a known long option name */ if (argv[*optind][2] == '\0') { @@ -119,7 +119,7 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char optchr = 0; dash = 0; - arg_start += strlen(opts[php_optidx].opt_name); + arg_start += (int)strlen(opts[php_optidx].opt_name); } else { if (!dash) { dash = 1; diff --git a/main/http_status_codes.h b/main/http_status_codes.h new file mode 100644 index 0000000000..4567fb4f3d --- /dev/null +++ b/main/http_status_codes.h @@ -0,0 +1,83 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2015 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Andrea Faulds <ajf@ajf.me> | + +----------------------------------------------------------------------+ +*/ + +/* $Id: $ */ + +#ifndef HTTP_STATUS_CODES_H +#define HTTP_STATUS_CODES_H + +typedef struct _http_response_status_code_pair { + const int code; + const char *str; +} http_response_status_code_pair; + +static http_response_status_code_pair http_status_map[] = { + { 100, "Continue" }, + { 101, "Switching Protocols" }, + { 200, "OK" }, + { 201, "Created" }, + { 202, "Accepted" }, + { 203, "Non-Authoritative Information" }, + { 204, "No Content" }, + { 205, "Reset Content" }, + { 206, "Partial Content" }, + { 300, "Multiple Choices" }, + { 301, "Moved Permanently" }, + { 302, "Found" }, + { 303, "See Other" }, + { 304, "Not Modified" }, + { 305, "Use Proxy" }, + { 307, "Temporary Redirect" }, + { 308, "Permanent Redirect" }, + { 400, "Bad Request" }, + { 401, "Unauthorized" }, + { 402, "Payment Required" }, + { 403, "Forbidden" }, + { 404, "Not Found" }, + { 405, "Method Not Allowed" }, + { 406, "Not Acceptable" }, + { 407, "Proxy Authentication Required" }, + { 408, "Request Timeout" }, + { 409, "Conflict" }, + { 410, "Gone" }, + { 411, "Length Required" }, + { 412, "Precondition Failed" }, + { 413, "Request Entity Too Large" }, + { 414, "Request-URI Too Long" }, + { 415, "Unsupported Media Type" }, + { 416, "Requested Range Not Satisfiable" }, + { 417, "Expectation Failed" }, + { 426, "Upgrade Required" }, + { 428, "Precondition Required" }, + { 429, "Too Many Requests" }, + { 431, "Request Header Fields Too Large" }, + { 500, "Internal Server Error" }, + { 501, "Not Implemented" }, + { 502, "Bad Gateway" }, + { 503, "Service Unavailable" }, + { 504, "Gateway Timeout" }, + { 505, "HTTP Version Not Supported" }, + { 506, "Variant Also Negotiates" }, + { 511, "Network Authentication Required" }, + /* to allow search with while() loop */ + { 0, NULL } +}; + +static const size_t http_status_map_len = (sizeof(http_status_map) / sizeof(http_response_status_code_pair)) - 1; + +#endif /* HTTP_STATUS_CODES_H */ diff --git a/main/internal_functions.c.in b/main/internal_functions.c.in index f1e66b160a..d04eea3103 100644 --- a/main/internal_functions.c.in +++ b/main/internal_functions.c.in @@ -1,6 +1,6 @@ /* -*- C -*- +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ @@ -35,9 +35,9 @@ static zend_module_entry *php_builtin_extensions[] = { #define EXTCOUNT (sizeof(php_builtin_extensions)/sizeof(zend_module_entry *)) -PHPAPI int php_register_internal_extensions(TSRMLS_D) +PHPAPI int php_register_internal_extensions(void) { - return php_register_extensions(php_builtin_extensions, EXTCOUNT TSRMLS_CC); + return php_register_extensions(php_builtin_extensions, EXTCOUNT); } /* diff --git a/main/internal_functions_nw.c b/main/internal_functions_nw.c index 4487310128..9d5db7d843 100644 --- a/main/internal_functions_nw.c +++ b/main/internal_functions_nw.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -84,9 +84,9 @@ static zend_module_entry *php_builtin_extensions[] = { #define EXTCOUNT (sizeof(php_builtin_extensions)/sizeof(zend_module_entry *)) -PHPAPI int php_register_internal_extensions(TSRMLS_D) +PHPAPI int php_register_internal_extensions(void) { - return php_register_extensions(php_builtin_extensions, EXTCOUNT TSRMLS_CC); + return php_register_extensions(php_builtin_extensions, EXTCOUNT); } diff --git a/main/internal_functions_win32.c b/main/internal_functions_win32.c index 6c8cf41658..45baf802c0 100644 --- a/main/internal_functions_win32.c +++ b/main/internal_functions_win32.c @@ -1,6 +1,6 @@ -/* +/* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -29,10 +29,6 @@ #include <stdlib.h> #include <stdio.h> -#ifndef ZEND_ENGINE_2 -#error HEAD does not work with ZendEngine1 anymore -#endif - #include "ext/standard/dl.h" #include "ext/standard/file.h" #include "ext/standard/fsock.h" @@ -192,10 +188,10 @@ static zend_module_entry *php_builtin_extensions[] = { /* }}} */ #define EXTCOUNT (sizeof(php_builtin_extensions)/sizeof(zend_module_entry *)) - -PHPAPI int php_register_internal_extensions(TSRMLS_D) + +PHPAPI int php_register_internal_extensions(void) { - return php_register_extensions(php_builtin_extensions, EXTCOUNT TSRMLS_CC); + return php_register_extensions(php_builtin_extensions, EXTCOUNT); } /* diff --git a/main/main.c b/main/main.c index 4bf20966e0..149a1ac951 100644 --- a/main/main.c +++ b/main/main.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -53,6 +53,7 @@ #include <locale.h> #endif #include "zend.h" +#include "zend_types.h" #include "zend_extensions.h" #include "php_ini.h" #include "php_globals.h" @@ -79,7 +80,6 @@ #include "zend_compile.h" #include "zend_execute.h" #include "zend_highlight.h" -#include "zend_indent.h" #include "zend_extensions.h" #include "zend_ini.h" #include "zend_dtrace.h" @@ -114,11 +114,7 @@ #endif /* }}} */ -#ifndef S_ISREG -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif - -PHPAPI int (*php_register_internal_extensions_func)(TSRMLS_D) = php_register_internal_extensions; +PHPAPI int (*php_register_internal_extensions_func)(void) = php_register_internal_extensions; #ifndef ZTS php_core_globals core_globals; @@ -126,41 +122,15 @@ php_core_globals core_globals; PHPAPI int core_globals_id; #endif -#ifdef PHP_WIN32 -#include "win32_internal_function_disabled.h" - -static php_win32_disable_functions(TSRMLS_D) -{ - int i; - - if (EG(windows_version_info).dwMajorVersion < 5) { - for (i = 0; i < function_name_cnt_5; i++) { - if (zend_hash_del(CG(function_table), function_name_5[i], strlen(function_name_5[i]) + 1)==FAILURE) { - php_printf("Unable to disable function '%s'\n", function_name_5[i]); - return FAILURE; - } - } - } - - if (EG(windows_version_info).dwMajorVersion < 6) { - for (i = 0; i < function_name_cnt_6; i++) { - if (zend_hash_del(CG(function_table), function_name_6[i], strlen(function_name_6[i]) + 1)==FAILURE) { - php_printf("Unable to disable function '%s'\n", function_name_6[i]); - return FAILURE; - } - } - } - return SUCCESS; -} -#endif - #define SAFE_FILENAME(f) ((f)?(f):"-") /* {{{ PHP_INI_MH */ static PHP_INI_MH(OnSetPrecision) { - int i = atoi(new_value); + zend_long i; + + ZEND_ATOL(i, ZSTR_VAL(new_value)); if (i >= 0) { EG(precision) = i; return SUCCESS; @@ -175,7 +145,7 @@ static PHP_INI_MH(OnSetPrecision) static PHP_INI_MH(OnChangeMemoryLimit) { if (new_value) { - PG(memory_limit) = zend_atol(new_value, new_value_length); + PG(memory_limit) = zend_atol(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value)); } else { PG(memory_limit) = 1<<30; /* effectively, no limit */ } @@ -186,7 +156,7 @@ static PHP_INI_MH(OnChangeMemoryLimit) /* {{{ php_disable_functions */ -static void php_disable_functions(TSRMLS_D) +static void php_disable_functions(void) { char *s = NULL, *e; @@ -204,7 +174,7 @@ static void php_disable_functions(TSRMLS_D) case ',': if (s) { *e = '\0'; - zend_disable_function(s, e-s TSRMLS_CC); + zend_disable_function(s, e-s); s = NULL; } break; @@ -217,14 +187,14 @@ static void php_disable_functions(TSRMLS_D) e++; } if (s) { - zend_disable_function(s, e-s TSRMLS_CC); + zend_disable_function(s, e-s); } } /* }}} */ /* {{{ php_disable_classes */ -static void php_disable_classes(TSRMLS_D) +static void php_disable_classes(void) { char *s = NULL, *e; @@ -240,7 +210,7 @@ static void php_disable_classes(TSRMLS_D) case ',': if (s) { *e = '\0'; - zend_disable_class(s, e-s TSRMLS_CC); + zend_disable_class(s, e-s); s = NULL; } break; @@ -253,14 +223,14 @@ static void php_disable_classes(TSRMLS_D) e++; } if (s) { - zend_disable_class(s, e-s TSRMLS_CC); + zend_disable_class(s, e-s); } } /* }}} */ /* {{{ php_binary_init */ -static void php_binary_init(TSRMLS_D) +static void php_binary_init(void) { char *binary_location; #ifdef PHP_WIN32 @@ -279,7 +249,7 @@ static void php_binary_init(TSRMLS_D) if ((envpath = getenv("PATH")) != NULL) { char *search_dir, search_path[MAXPATHLEN]; char *last = NULL; - struct stat s; + zend_stat_t s; path = estrdup(envpath); search_dir = php_strtok_r(path, ":", &last); @@ -316,11 +286,11 @@ static PHP_INI_MH(OnUpdateTimeout) { if (stage==PHP_INI_STAGE_STARTUP) { /* Don't set a timeout on startup, only per-request */ - EG(timeout_seconds) = atoi(new_value); + ZEND_ATOL(EG(timeout_seconds), ZSTR_VAL(new_value)); return SUCCESS; } - zend_unset_timeout(TSRMLS_C); - EG(timeout_seconds) = atoi(new_value); + zend_unset_timeout(); + ZEND_ATOL(EG(timeout_seconds), ZSTR_VAL(new_value)); zend_set_timeout(EG(timeout_seconds), 0); return SUCCESS; } @@ -347,7 +317,7 @@ static int php_get_display_errors_mode(char *value, int value_length) } else if (value_length == 6 && !strcasecmp(value, "stdout")) { mode = PHP_DISPLAY_ERRORS_STDOUT; } else { - mode = atoi(value); + ZEND_ATOL(mode, value); if (mode && mode != PHP_DISPLAY_ERRORS_STDOUT && mode != PHP_DISPLAY_ERRORS_STDERR) { mode = PHP_DISPLAY_ERRORS_STDOUT; } @@ -361,7 +331,7 @@ static int php_get_display_errors_mode(char *value, int value_length) */ static PHP_INI_MH(OnUpdateDisplayErrors) { - PG(display_errors) = (zend_bool) php_get_display_errors_mode(new_value, new_value_length); + PG(display_errors) = (zend_bool) php_get_display_errors_mode(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value)); return SUCCESS; } @@ -373,14 +343,13 @@ static PHP_INI_DISP(display_errors_mode) { int mode, tmp_value_length, cgi_or_cli; char *tmp_value; - TSRMLS_FETCH(); if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) { - tmp_value = (ini_entry->orig_value ? ini_entry->orig_value : NULL ); - tmp_value_length = ini_entry->orig_value_length; + tmp_value = (ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : NULL ); + tmp_value_length = (int)(ini_entry->orig_value? ZSTR_LEN(ini_entry->orig_value) : 0); } else if (ini_entry->value) { - tmp_value = ini_entry->value; - tmp_value_length = ini_entry->value_length; + tmp_value = ZSTR_VAL(ini_entry->value); + tmp_value_length = (int)ZSTR_LEN(ini_entry->value); } else { tmp_value = NULL; tmp_value_length = 0; @@ -420,7 +389,7 @@ static PHP_INI_DISP(display_errors_mode) static PHP_INI_MH(OnUpdateInternalEncoding) { if (new_value) { - OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); + OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } return SUCCESS; } @@ -431,7 +400,7 @@ static PHP_INI_MH(OnUpdateInternalEncoding) static PHP_INI_MH(OnUpdateInputEncoding) { if (new_value) { - OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); + OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } return SUCCESS; } @@ -442,7 +411,7 @@ static PHP_INI_MH(OnUpdateInputEncoding) static PHP_INI_MH(OnUpdateOutputEncoding) { if (new_value) { - OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); + OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } return SUCCESS; } @@ -453,12 +422,12 @@ static PHP_INI_MH(OnUpdateOutputEncoding) static PHP_INI_MH(OnUpdateErrorLog) { /* Only do the safemode/open_basedir check at runtime */ - if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && new_value && strcmp(new_value, "syslog")) { - if (PG(open_basedir) && php_check_open_basedir(new_value TSRMLS_CC)) { + if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && new_value && strcmp(ZSTR_VAL(new_value), "syslog")) { + if (PG(open_basedir) && php_check_open_basedir(ZSTR_VAL(new_value))) { return FAILURE; } } - OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); + OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); return SUCCESS; } /* }}} */ @@ -469,11 +438,11 @@ static PHP_INI_MH(OnUpdateMailLog) { /* Only do the safemode/open_basedir check at runtime */ if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && new_value) { - if (PG(open_basedir) && php_check_open_basedir(new_value TSRMLS_CC)) { + if (PG(open_basedir) && php_check_open_basedir(ZSTR_VAL(new_value))) { return FAILURE; } } - OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); + OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); return SUCCESS; } /* }}} */ @@ -493,40 +462,6 @@ static PHP_INI_MH(OnChangeMailForceExtra) /* defined in browscap.c */ PHP_INI_MH(OnChangeBrowscap); -/* {{{ PHP_INI_MH - */ -static PHP_INI_MH(OnChangeAlwaysPopulateRawPostData) -{ - signed char *p; -#ifndef ZTS - char *base = (char *) mh_arg2; -#else - char *base; - - base = (char *) ts_resource(*((int *) mh_arg2)); -#endif - - p = (signed char *) (base+(size_t) mh_arg1); - - *p = zend_atol(new_value, new_value_length); - if (new_value_length == 2 && strcasecmp("on", new_value) == 0) { - *p = (signed char) 1; - } - else if (new_value_length == 3 && strcasecmp("yes", new_value) == 0) { - *p = (signed char) 1; - } - else if (new_value_length == 4 && strcasecmp("true", new_value) == 0) { - *p = (signed char) 1; - } - else if (new_value_length == 5 && strcasecmp("never", new_value) == 0) { - *p = (signed char) -1; - } - else { - *p = (signed char) atoi(new_value); - } - return SUCCESS; -} -/* }}} */ /* Need to be read from the environment (?): * PHP_AUTO_PREPEND_FILE @@ -554,7 +489,6 @@ PHP_INI_BEGIN() PHP_INI_ENTRY_EX("highlight.keyword", HL_KEYWORD_COLOR, PHP_INI_ALL, NULL, php_ini_color_displayer_cb) PHP_INI_ENTRY_EX("highlight.string", HL_STRING_COLOR, PHP_INI_ALL, NULL, php_ini_color_displayer_cb) - STD_PHP_INI_BOOLEAN("asp_tags", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, asp_tags, zend_compiler_globals, compiler_globals) STD_PHP_INI_ENTRY_EX("display_errors", "1", PHP_INI_ALL, OnUpdateDisplayErrors, display_errors, php_core_globals, core_globals, display_errors_mode) STD_PHP_INI_BOOLEAN("display_startup_errors", "0", PHP_INI_ALL, OnUpdateBool, display_startup_errors, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("enable_dl", "1", PHP_INI_SYSTEM, OnUpdateBool, enable_dl, php_core_globals, core_globals) @@ -632,7 +566,6 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("allow_url_include", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_url_include, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("enable_post_data_reading", "1", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, enable_post_data_reading, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("always_populate_raw_post_data", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnChangeAlwaysPopulateRawPostData, always_populate_raw_post_data, php_core_globals, core_globals) STD_PHP_INI_ENTRY("realpath_cache_size", "16K", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_size_limit, virtual_cwd_globals, cwd_globals) STD_PHP_INI_ENTRY("realpath_cache_ttl", "120", PHP_INI_SYSTEM, OnUpdateLong, realpath_cache_ttl, virtual_cwd_globals, cwd_globals) @@ -676,7 +609,7 @@ PHPAPI int php_get_module_initialized(void) /* {{{ php_log_err */ -PHPAPI void php_log_err(char *log_message TSRMLS_DC) +PHPAPI ZEND_COLD void php_log_err(char *log_message) { int fd = -1; time_t error_time; @@ -699,26 +632,29 @@ PHPAPI void php_log_err(char *log_message TSRMLS_DC) fd = VCWD_OPEN_MODE(PG(error_log), O_CREAT | O_APPEND | O_WRONLY, 0644); if (fd != -1) { char *tmp; - int len; - char *error_time_str; + size_t len; + zend_string *error_time_str; time(&error_time); #ifdef ZTS if (!php_during_module_startup()) { - error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1 TSRMLS_CC); + error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1); } else { - error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 0 TSRMLS_CC); + error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 0); } #else - error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1 TSRMLS_CC); + error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1); #endif - len = spprintf(&tmp, 0, "[%s] %s%s", error_time_str, log_message, PHP_EOL); + len = spprintf(&tmp, 0, "[%s] %s%s", ZSTR_VAL(error_time_str), log_message, PHP_EOL); #ifdef PHP_WIN32 php_flock(fd, 2); -#endif + /* XXX should eventually write in a loop if len > UINT_MAX */ + php_ignore_value(write(fd, tmp, (unsigned)len)); +#else php_ignore_value(write(fd, tmp, len)); +#endif efree(tmp); - efree(error_time_str); + zend_string_free(error_time_str); close(fd); PG(in_error_log) = 0; return; @@ -728,7 +664,7 @@ PHPAPI void php_log_err(char *log_message TSRMLS_DC) /* Otherwise fall back to the default logging location, if we have one */ if (sapi_module.log_message) { - sapi_module.log_message(log_message TSRMLS_CC); + sapi_module.log_message(log_message); } PG(in_error_log) = 0; } @@ -736,7 +672,7 @@ PHPAPI void php_log_err(char *log_message TSRMLS_DC) /* {{{ php_write wrapper for modules to use PHPWRITE */ -PHPAPI int php_write(void *buf, uint size TSRMLS_DC) +PHPAPI size_t php_write(void *buf, size_t size) { return PHPWRITE(buf, size); } @@ -744,13 +680,12 @@ PHPAPI int php_write(void *buf, uint size TSRMLS_DC) /* {{{ php_printf */ -PHPAPI int php_printf(const char *format, ...) +PHPAPI size_t php_printf(const char *format, ...) { va_list args; - int ret; + size_t ret; char *buffer; - int size; - TSRMLS_FETCH(); + size_t size; va_start(args, format); size = vspprintf(&buffer, 0, format, args); @@ -768,8 +703,9 @@ PHPAPI int php_printf(const char *format, ...) * html error messages if correcponding ini setting (html_errors) is activated. * See: CODING_STANDARDS for details. */ -PHPAPI void php_verror(const char *docref, const char *params, int type, const char *format, va_list args TSRMLS_DC) +PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int type, const char *format, va_list args) { + zend_string *replace_buffer = NULL, *replace_origin = NULL; char *buffer = NULL, *docref_buf = NULL, *target = NULL; char *docref_target = "", *docref_root = ""; char *p; @@ -783,14 +719,13 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c int is_function = 0; /* get error text into buffer and escape for html if necessary */ - buffer_len = vspprintf(&buffer, 0, format, args); + buffer_len = (int)vspprintf(&buffer, 0, format, args); if (PG(html_errors)) { - size_t len; - char *replace = php_escape_html_entities(buffer, buffer_len, &len, 0, ENT_COMPAT, NULL TSRMLS_CC); + replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, NULL); efree(buffer); - buffer = replace; - buffer_len = len; + buffer = ZSTR_VAL(replace_buffer); + buffer_len = (int)ZSTR_LEN(replace_buffer); } /* which function caused the problem if any at all */ @@ -799,6 +734,8 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c } else if (php_during_module_shutdown()) { function = "PHP Shutdown"; } else if (EG(current_execute_data) && + EG(current_execute_data)->func && + ZEND_USER_CODE(EG(current_execute_data)->func->common.type) && EG(current_execute_data)->opline && EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL ) { @@ -827,27 +764,26 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c function = "Unknown"; } } else { - function = get_active_function_name(TSRMLS_C); + function = get_active_function_name(); if (!function || !strlen(function)) { function = "Unknown"; } else { is_function = 1; - class_name = get_active_class_name(&space TSRMLS_CC); + class_name = get_active_class_name(&space); } } /* if we still have memory then format the origin */ if (is_function) { - origin_len = spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, params); + origin_len = (int)spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, params); } else { - origin_len = spprintf(&origin, 0, "%s", function); + origin_len = (int)spprintf(&origin, 0, "%s", function); } if (PG(html_errors)) { - size_t len; - char *replace = php_escape_html_entities(origin, origin_len, &len, 0, ENT_COMPAT, NULL TSRMLS_CC); + replace_origin = php_escape_html_entities((unsigned char*)origin, origin_len, 0, ENT_COMPAT, NULL); efree(origin); - origin = replace; + origin = ZSTR_VAL(replace_origin); } /* origin and buffer available, so lets come up with the error message */ @@ -863,9 +799,9 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c function++; } if (space[0] == '\0') { - doclen = spprintf(&docref_buf, 0, "function.%s", function); + doclen = (int)spprintf(&docref_buf, 0, "function.%s", function); } else { - doclen = spprintf(&docref_buf, 0, "%s.%s", class_name, function); + doclen = (int)spprintf(&docref_buf, 0, "%s.%s", class_name, function); } while((p = strchr(docref_buf, '_')) != NULL) { *p = '-'; @@ -918,24 +854,32 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c } else { spprintf(&message, 0, "%s: %s", origin, buffer); } - str_efree(origin); + if (replace_origin) { + zend_string_free(replace_origin); + } else { + efree(origin); + } if (docref_buf) { efree(docref_buf); } - if (PG(track_errors) && module_initialized && - (!EG(user_error_handler) || !(EG(user_error_handler_error_reporting) & type))) { - if (!EG(active_symbol_table)) { - zend_rebuild_symbol_table(TSRMLS_C); - } - if (EG(active_symbol_table)) { - zval *tmp; - ALLOC_INIT_ZVAL(tmp); - ZVAL_STRINGL(tmp, buffer, buffer_len, 1); - zend_hash_update(EG(active_symbol_table), "php_errormsg", sizeof("php_errormsg"), (void **) &tmp, sizeof(zval *), NULL); + if (PG(track_errors) && module_initialized && EG(valid_symbol_table) && + (Z_TYPE(EG(user_error_handler)) == IS_UNDEF || !(EG(user_error_handler_error_reporting) & type))) { + zval tmp; + ZVAL_STRINGL(&tmp, buffer, buffer_len); + if (EG(current_execute_data)) { + if (zend_set_local_var_str("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0) == FAILURE) { + zval_ptr_dtor(&tmp); + } + } else { + zend_hash_str_update_ind(&EG(symbol_table), "php_errormsg", sizeof("php_errormsg")-1, &tmp); } } - str_efree(buffer); + if (replace_buffer) { + zend_string_free(replace_buffer); + } else { + efree(buffer); + } php_error(type, "%s", message); efree(message); @@ -944,38 +888,38 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c /* {{{ php_error_docref0 */ /* See: CODING_STANDARDS for details. */ -PHPAPI void php_error_docref0(const char *docref TSRMLS_DC, int type, const char *format, ...) +PHPAPI ZEND_COLD void php_error_docref0(const char *docref, int type, const char *format, ...) { va_list args; va_start(args, format); - php_verror(docref, "", type, format, args TSRMLS_CC); + php_verror(docref, "", type, format, args); va_end(args); } /* }}} */ /* {{{ php_error_docref1 */ /* See: CODING_STANDARDS for details. */ -PHPAPI void php_error_docref1(const char *docref TSRMLS_DC, const char *param1, int type, const char *format, ...) +PHPAPI ZEND_COLD void php_error_docref1(const char *docref, const char *param1, int type, const char *format, ...) { va_list args; va_start(args, format); - php_verror(docref, param1, type, format, args TSRMLS_CC); + php_verror(docref, param1, type, format, args); va_end(args); } /* }}} */ /* {{{ php_error_docref2 */ /* See: CODING_STANDARDS for details. */ -PHPAPI void php_error_docref2(const char *docref TSRMLS_DC, const char *param1, const char *param2, int type, const char *format, ...) +PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format, ...) { char *params; va_list args; spprintf(¶ms, 0, "%s,%s", param1, param2); va_start(args, format); - php_verror(docref, params ? params : "...", type, format, args TSRMLS_CC); + php_verror(docref, params ? params : "...", type, format, args); va_end(args); if (params) { efree(params); @@ -985,41 +929,40 @@ PHPAPI void php_error_docref2(const char *docref TSRMLS_DC, const char *param1, #ifdef PHP_WIN32 #define PHP_WIN32_ERROR_MSG_BUFFER_SIZE 512 -PHPAPI void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2 TSRMLS_DC) { +PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2) { if (error == 0) { - php_error_docref2(NULL TSRMLS_CC, param1, param2, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, param1, param2, E_WARNING, "%s", strerror(errno)); } else { char buf[PHP_WIN32_ERROR_MSG_BUFFER_SIZE + 1]; int buf_len; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buf, PHP_WIN32_ERROR_MSG_BUFFER_SIZE, NULL); - buf_len = strlen(buf); + buf_len = (int)strlen(buf); if (buf_len >= 2) { buf[buf_len - 1] = '\0'; buf[buf_len - 2] = '\0'; } - php_error_docref2(NULL TSRMLS_CC, param1, param2, E_WARNING, "%s (code: %lu)", (char *)buf, error); + php_error_docref2(NULL, param1, param2, E_WARNING, "%s (code: %lu)", (char *)buf, error); } } #undef PHP_WIN32_ERROR_MSG_BUFFER_SIZE #endif /* {{{ php_html_puts */ -PHPAPI void php_html_puts(const char *str, uint size TSRMLS_DC) +PHPAPI void php_html_puts(const char *str, size_t size) { - zend_html_puts(str, size TSRMLS_CC); + zend_html_puts(str, size); } /* }}} */ /* {{{ php_error_cb extended error handling function */ -static void php_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) +static ZEND_COLD void php_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) { char *buffer; int buffer_len, display; - TSRMLS_FETCH(); - buffer_len = vspprintf(&buffer, PG(log_errors_max_len), format, args); + buffer_len = (int)vspprintf(&buffer, PG(log_errors_max_len), format, args); /* check for repeated errors to be ignored */ if (PG(ignore_repeated_errors) && PG(last_error_message)) { @@ -1039,20 +982,16 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ /* store the error if it has changed */ if (display) { -#ifdef ZEND_SIGNALS - HANDLE_BLOCK_INTERRUPTIONS(); -#endif if (PG(last_error_message)) { - free(PG(last_error_message)); + char *s = PG(last_error_message); PG(last_error_message) = NULL; + free(s); } if (PG(last_error_file)) { - free(PG(last_error_file)); + char *s = PG(last_error_file); PG(last_error_file) = NULL; + free(s); } -#ifdef ZEND_SIGNALS - HANDLE_UNBLOCK_INTERRUPTIONS(); -#endif if (!error_filename) { error_filename = "Unknown"; } @@ -1086,7 +1025,7 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ * but DO NOT overwrite a pending exception */ if (EG(error_handling) == EH_THROW && !EG(exception)) { - zend_throw_error_exception(EG(exception_class), buffer, 0, type TSRMLS_CC); + zend_throw_error_exception(EG(exception_class), buffer, 0, type); } efree(buffer); return; @@ -1141,23 +1080,22 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ } #endif spprintf(&log_buffer, 0, "PHP %s: %s in %s on line %d", error_type_str, buffer, error_filename, error_lineno); - php_log_err(log_buffer TSRMLS_CC); + php_log_err(log_buffer); efree(log_buffer); } if (PG(display_errors) && ((module_initialized && !PG(during_request_startup)) || (PG(display_startup_errors)))) { if (PG(xmlrpc_errors)) { - php_printf("<?xml version=\"1.0\"?><methodResponse><fault><value><struct><member><name>faultCode</name><value><int>%ld</int></value></member><member><name>faultString</name><value><string>%s:%s in %s on line %d</string></value></member></struct></value></fault></methodResponse>", PG(xmlrpc_error_number), error_type_str, buffer, error_filename, error_lineno); + php_printf("<?xml version=\"1.0\"?><methodResponse><fault><value><struct><member><name>faultCode</name><value><int>%pd</int></value></member><member><name>faultString</name><value><string>%s:%s in %s on line %d</string></value></member></struct></value></fault></methodResponse>", PG(xmlrpc_error_number), error_type_str, buffer, error_filename, error_lineno); } else { char *prepend_string = INI_STR("error_prepend_string"); char *append_string = INI_STR("error_append_string"); if (PG(html_errors)) { if (type == E_ERROR || type == E_PARSE) { - size_t len; - char *buf = php_escape_html_entities(buffer, buffer_len, &len, 0, ENT_COMPAT, NULL TSRMLS_CC); - php_printf("%s<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, buf, error_filename, error_lineno, STR_PRINT(append_string)); - str_efree(buf); + zend_string *buf = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, NULL); + php_printf("%s<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, ZSTR_VAL(buf), error_filename, error_lineno, STR_PRINT(append_string)); + zend_string_free(buf); } else { php_printf("%s<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string)); } @@ -1167,10 +1105,10 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ PG(display_errors) == PHP_DISPLAY_ERRORS_STDERR ) { #ifdef PHP_WIN32 - fprintf(stderr, "%s: %s in %s on line %d\n", error_type_str, buffer, error_filename, error_lineno); + fprintf(stderr, "%s: %s in %s on line %u\n", error_type_str, buffer, error_filename, error_lineno); fflush(stderr); #else - fprintf(stderr, "%s: %s in %s on line %d\n", error_type_str, buffer, error_filename, error_lineno); + fprintf(stderr, "%s: %s in %s on line %u\n", error_type_str, buffer, error_filename, error_lineno); #endif } else { php_printf("%s\n%s: %s in %s on line %d\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string)); @@ -1211,26 +1149,17 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ case E_PARSE: case E_COMPILE_ERROR: case E_USER_ERROR: - { /* new block to allow variable definition */ - /* eval() errors do not affect exit_status or response code */ - zend_bool during_eval = (type == E_PARSE) && (EG(current_execute_data) && - EG(current_execute_data)->opline && - EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL && - EG(current_execute_data)->opline->extended_value == ZEND_EVAL); - if (!during_eval) { - EG(exit_status) = 255; - } + EG(exit_status) = 255; if (module_initialized) { if (!PG(display_errors) && !SG(headers_sent) && - SG(sapi_headers).http_response_code == 200 && - !during_eval + SG(sapi_headers).http_response_code == 200 ) { sapi_header_line ctr = {0}; ctr.line = "HTTP/1.0 500 Internal Server Error"; ctr.line_len = sizeof("HTTP/1.0 500 Internal Server Error") - 1; - sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); + sapi_header_op(SAPI_HEADER_REPLACE, &ctr); } /* the parser would return 1 (failure), we can bail out nicely */ if (type == E_PARSE) { @@ -1239,13 +1168,12 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ /* restore memory limit */ zend_set_memory_limit(PG(memory_limit)); efree(buffer); - zend_objects_store_mark_destructed(&EG(objects_store) TSRMLS_CC); + zend_objects_store_mark_destructed(&EG(objects_store)); zend_bailout(); return; } } break; - } } /* Log if necessary */ @@ -1254,15 +1182,16 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ return; } - if (PG(track_errors) && module_initialized) { - if (!EG(active_symbol_table)) { - zend_rebuild_symbol_table(TSRMLS_C); - } - if (EG(active_symbol_table)) { - zval *tmp; - ALLOC_INIT_ZVAL(tmp); - ZVAL_STRINGL(tmp, buffer, buffer_len, 1); - zend_hash_update(EG(active_symbol_table), "php_errormsg", sizeof("php_errormsg"), (void **) & tmp, sizeof(zval *), NULL); + if (PG(track_errors) && module_initialized && EG(valid_symbol_table)) { + zval tmp; + + ZVAL_STRINGL(&tmp, buffer, buffer_len); + if (EG(current_execute_data)) { + if (zend_set_local_var_str("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0) == FAILURE) { + zval_ptr_dtor(&tmp); + } + } else { + zend_hash_str_update_ind(&EG(symbol_table), "php_errormsg", sizeof("php_errormsg")-1, &tmp); } } @@ -1272,9 +1201,9 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ /* {{{ php_get_current_user */ -PHPAPI char *php_get_current_user(TSRMLS_D) +PHPAPI char *php_get_current_user(void) { - struct stat *pstat; + zend_stat_t *pstat; if (SG(request_info).current_user) { return SG(request_info).current_user; @@ -1284,7 +1213,7 @@ PHPAPI char *php_get_current_user(TSRMLS_D) USE_SAPI is defined, because cgi will also be interfaced in USE_SAPI */ - pstat = sapi_get_stat(TSRMLS_C); + pstat = sapi_get_stat(); if (!pstat) { return ""; @@ -1341,47 +1270,50 @@ PHPAPI char *php_get_current_user(TSRMLS_D) Sets the maximum time a script can run */ PHP_FUNCTION(set_time_limit) { - long new_timeout; + zend_long new_timeout; char *new_timeout_str; int new_timeout_strlen; + zend_string *key; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &new_timeout) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &new_timeout) == FAILURE) { return; } - new_timeout_strlen = zend_spprintf(&new_timeout_str, 0, "%ld", new_timeout); + new_timeout_strlen = (int)zend_spprintf(&new_timeout_str, 0, ZEND_LONG_FMT, new_timeout); - if (zend_alter_ini_entry_ex("max_execution_time", sizeof("max_execution_time"), new_timeout_str, new_timeout_strlen, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC) == SUCCESS) { + key = zend_string_init("max_execution_time", sizeof("max_execution_time")-1, 0); + if (zend_alter_ini_entry_chars_ex(key, new_timeout_str, new_timeout_strlen, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == SUCCESS) { RETVAL_TRUE; } else { RETVAL_FALSE; } + zend_string_release(key); efree(new_timeout_str); } /* }}} */ /* {{{ php_fopen_wrapper_for_zend */ -static FILE *php_fopen_wrapper_for_zend(const char *filename, char **opened_path TSRMLS_DC) +static FILE *php_fopen_wrapper_for_zend(const char *filename, zend_string **opened_path) { return php_stream_open_wrapper_as_file((char *)filename, "rb", USE_PATH|IGNORE_URL_WIN|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE, opened_path); } /* }}} */ -static void php_zend_stream_closer(void *handle TSRMLS_DC) /* {{{ */ +static void php_zend_stream_closer(void *handle) /* {{{ */ { php_stream_close((php_stream*)handle); } /* }}} */ -static void php_zend_stream_mmap_closer(void *handle TSRMLS_DC) /* {{{ */ +static void php_zend_stream_mmap_closer(void *handle) /* {{{ */ { php_stream_mmap_unmap((php_stream*)handle); - php_zend_stream_closer(handle TSRMLS_CC); + php_zend_stream_closer(handle); } /* }}} */ -static size_t php_zend_stream_fsizer(void *handle TSRMLS_DC) /* {{{ */ +static size_t php_zend_stream_fsizer(void *handle) /* {{{ */ { php_stream_statbuf ssb; if (php_stream_stat((php_stream*)handle, &ssb) == 0) { @@ -1391,13 +1323,13 @@ static size_t php_zend_stream_fsizer(void *handle TSRMLS_DC) /* {{{ */ } /* }}} */ -static int php_stream_open_for_zend(const char *filename, zend_file_handle *handle TSRMLS_DC) /* {{{ */ +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 TSRMLS_CC); + return php_stream_open_for_zend_ex(filename, handle, USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE); } /* }}} */ -PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode TSRMLS_DC) /* {{{ */ +PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode) /* {{{ */ { char *p; size_t len, mapped_len; @@ -1416,7 +1348,7 @@ PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *h handle->handle.stream.isatty = 0; /* can we mmap immediately? */ memset(&handle->handle.stream.mmap, 0, sizeof(handle->handle.stream.mmap)); - len = php_zend_stream_fsizer(stream TSRMLS_CC); + len = php_zend_stream_fsizer(stream); if (len != 0 #if HAVE_MMAP || defined(PHP_WIN32) && ((len - 1) % page_size) <= page_size - ZEND_MMAP_AHEAD @@ -1440,40 +1372,52 @@ PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *h } /* }}} */ -static char *php_resolve_path_for_zend(const char *filename, int filename_len TSRMLS_DC) /* {{{ */ +static zend_string *php_resolve_path_for_zend(const char *filename, int filename_len) /* {{{ */ { - return php_resolve_path(filename, filename_len, PG(include_path) TSRMLS_CC); + return php_resolve_path(filename, filename_len, PG(include_path)); } /* }}} */ /* {{{ php_get_configuration_directive_for_zend */ -static int php_get_configuration_directive_for_zend(const char *name, uint name_length, zval *contents) +static zval *php_get_configuration_directive_for_zend(zend_string *name) { - zval *retval = cfg_get_entry(name, name_length); + return cfg_get_entry_ex(name); +} +/* }}} */ - if (retval) { - *contents = *retval; - return SUCCESS; - } else { - return FAILURE; +/* {{{ php_free_request_globals + */ +static void php_free_request_globals(void) +{ + if (PG(last_error_message)) { + free(PG(last_error_message)); + PG(last_error_message) = NULL; + } + if (PG(last_error_file)) { + free(PG(last_error_file)); + PG(last_error_file) = NULL; + } + if (PG(php_sys_temp_dir)) { + efree(PG(php_sys_temp_dir)); + PG(php_sys_temp_dir) = NULL; } } /* }}} */ /* {{{ php_message_handler_for_zend */ -static void php_message_handler_for_zend(long message, const void *data TSRMLS_DC) +static ZEND_COLD void php_message_handler_for_zend(zend_long message, const void *data) { switch (message) { case ZMSG_FAILED_INCLUDE_FOPEN: - php_error_docref("function.include" TSRMLS_CC, E_WARNING, "Failed opening '%s' for inclusion (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path))); + php_error_docref("function.include", E_WARNING, "Failed opening '%s' for inclusion (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path))); break; case ZMSG_FAILED_REQUIRE_FOPEN: - php_error_docref("function.require" TSRMLS_CC, E_COMPILE_ERROR, "Failed opening required '%s' (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path))); + php_error_docref("function.require", E_COMPILE_ERROR, "Failed opening required '%s' (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path))); break; case ZMSG_FAILED_HIGHLIGHT_FOPEN: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed opening '%s' for highlighting", php_strip_url_passwd((char *) data)); + php_error_docref(NULL, E_WARNING, "Failed opening '%s' for highlighting", php_strip_url_passwd((char *) data)); break; case ZMSG_MEMORY_LEAK_DETECTED: case ZMSG_MEMORY_LEAK_REPEATED: @@ -1509,7 +1453,7 @@ static void php_message_handler_for_zend(long message, const void *data TSRMLS_D if (EG(error_reporting) & E_WARNING) { char memory_leak_buf[512]; - snprintf(memory_leak_buf, 512, "=== Total %d memory leaks detected ===\n", *((zend_uint *) data)); + snprintf(memory_leak_buf, 512, "=== Total %d memory leaks detected ===\n", *((uint32_t *) data)); # if defined(PHP_WIN32) OutputDebugString(memory_leak_buf); # else @@ -1545,11 +1489,11 @@ static void php_message_handler_for_zend(long message, const void *data TSRMLS_D /* }}} */ -void php_on_timeout(int seconds TSRMLS_DC) +void php_on_timeout(int seconds) { PG(connection_status) |= PHP_CONNECTION_TIMEOUT; zend_set_timeout(EG(timeout_seconds), 1); - if(PG(exit_on_timeout)) sapi_terminate_process(TSRMLS_C); + if(PG(exit_on_timeout)) sapi_terminate_process(); } #if PHP_SIGCHILD @@ -1569,7 +1513,7 @@ static void sigchld_handler(int apar) /* {{{ php_start_sapi() */ -static int php_start_sapi(TSRMLS_D) +static int php_start_sapi(void) { int retval = SUCCESS; @@ -1582,9 +1526,9 @@ static int php_start_sapi(TSRMLS_D) PG(header_is_being_sent) = 0; PG(connection_status) = PHP_CONNECTION_NORMAL; - zend_activate(TSRMLS_C); + zend_activate(); zend_set_timeout(EG(timeout_seconds), 1); - zend_activate_modules(TSRMLS_C); + zend_activate_modules(); PG(modules_activated)=1; } zend_catch { retval = FAILURE; @@ -1600,7 +1544,7 @@ static int php_start_sapi(TSRMLS_D) /* {{{ php_request_startup */ #ifndef APACHE_HOOKS -int php_request_startup(TSRMLS_D) +int php_request_startup(void) { int retval = SUCCESS; @@ -1620,7 +1564,7 @@ int php_request_startup(TSRMLS_D) PG(in_error_log) = 0; PG(during_request_startup) = 1; - php_output_activate(TSRMLS_C); + php_output_activate(); /* initialize global variables */ PG(modules_activated) = 0; @@ -1628,11 +1572,11 @@ int php_request_startup(TSRMLS_D) PG(connection_status) = PHP_CONNECTION_NORMAL; PG(in_user_include) = 0; - zend_activate(TSRMLS_C); - sapi_activate(TSRMLS_C); + zend_activate(); + sapi_activate(); #ifdef ZEND_SIGNALS - zend_signal_activate(TSRMLS_C); + zend_signal_activate(); #endif if (PG(max_input_time) == -1) { @@ -1651,23 +1595,22 @@ int php_request_startup(TSRMLS_D) } if (PG(output_handler) && PG(output_handler)[0]) { - zval *oh; + zval oh; - MAKE_STD_ZVAL(oh); - ZVAL_STRING(oh, PG(output_handler), 1); - php_output_start_user(oh, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC); + ZVAL_STRING(&oh, PG(output_handler)); + php_output_start_user(&oh, 0, PHP_OUTPUT_HANDLER_STDFLAGS); zval_ptr_dtor(&oh); } else if (PG(output_buffering)) { - php_output_start_user(NULL, PG(output_buffering) > 1 ? PG(output_buffering) : 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC); + php_output_start_user(NULL, PG(output_buffering) > 1 ? PG(output_buffering) : 0, PHP_OUTPUT_HANDLER_STDFLAGS); } else if (PG(implicit_flush)) { - php_output_set_implicit_flush(1 TSRMLS_CC); + php_output_set_implicit_flush(1); } /* We turn this off in php_execute_script() */ /* PG(during_request_startup) = 0; */ - php_hash_environment(TSRMLS_C); - zend_activate_modules(TSRMLS_C); + php_hash_environment(); + zend_activate_modules(); PG(modules_activated)=1; } zend_catch { retval = FAILURE; @@ -1678,7 +1621,7 @@ int php_request_startup(TSRMLS_D) return retval; } # else -int php_request_startup(TSRMLS_D) +int php_request_startup(void) { int retval = SUCCESS; @@ -1690,9 +1633,9 @@ int php_request_startup(TSRMLS_D) return FAILURE; } - php_output_activate(TSRMLS_C); - sapi_activate(TSRMLS_C); - php_hash_environment(TSRMLS_C); + php_output_activate(); + sapi_activate(); + php_hash_environment(); zend_try { PG(during_request_startup) = 1; @@ -1710,7 +1653,7 @@ int php_request_startup(TSRMLS_D) /* {{{ php_request_startup_for_hook */ -int php_request_startup_for_hook(TSRMLS_D) +int php_request_startup_for_hook(void) { int retval = SUCCESS; @@ -1718,13 +1661,13 @@ int php_request_startup_for_hook(TSRMLS_D) signal(SIGCHLD, sigchld_handler); #endif - if (php_start_sapi(TSRMLS_C) == FAILURE) { + if (php_start_sapi() == FAILURE) { return FAILURE; } - php_output_activate(TSRMLS_C); - sapi_activate_headers_only(TSRMLS_C); - php_hash_environment(TSRMLS_C); + php_output_activate(); + sapi_activate_headers_only(); + php_hash_environment(); return retval; } @@ -1734,12 +1677,11 @@ int php_request_startup_for_hook(TSRMLS_D) */ void php_request_shutdown_for_exec(void *dummy) { - TSRMLS_FETCH(); /* used to close fd's in the 3..255 range here, but it's problematic */ - shutdown_memory_manager(1, 1 TSRMLS_CC); - zend_interned_strings_restore(TSRMLS_C); + shutdown_memory_manager(1, 1); + zend_interned_strings_restore(); } /* }}} */ @@ -1747,50 +1689,47 @@ void php_request_shutdown_for_exec(void *dummy) */ void php_request_shutdown_for_hook(void *dummy) { - TSRMLS_FETCH(); if (PG(modules_activated)) zend_try { - php_call_shutdown_functions(TSRMLS_C); + php_call_shutdown_functions(); } zend_end_try(); if (PG(modules_activated)) { - zend_deactivate_modules(TSRMLS_C); - php_free_shutdown_functions(TSRMLS_C); + zend_deactivate_modules(); + php_free_shutdown_functions(); } zend_try { - zend_unset_timeout(TSRMLS_C); + zend_unset_timeout(); } zend_end_try(); zend_try { int i; for (i = 0; i < NUM_TRACK_VARS; i++) { - if (PG(http_globals)[i]) { - zval_ptr_dtor(&PG(http_globals)[i]); - } + zval_ptr_dtor(&PG(http_globals)[i]); } } zend_end_try(); - zend_deactivate(TSRMLS_C); + zend_deactivate(); zend_try { - sapi_deactivate(TSRMLS_C); + sapi_deactivate(); } zend_end_try(); zend_try { - php_shutdown_stream_hashes(TSRMLS_C); + php_shutdown_stream_hashes(); } zend_end_try(); zend_try { - shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); + shutdown_memory_manager(CG(unclean_shutdown), 0); } zend_end_try(); - zend_interned_strings_restore(TSRMLS_C); + zend_interned_strings_restore(); #ifdef ZEND_SIGNALS zend_try { - zend_signal_deactivate(TSRMLS_C); + zend_signal_deactivate(); } zend_end_try(); #endif } @@ -1802,26 +1741,24 @@ void php_request_shutdown_for_hook(void *dummy) void php_request_shutdown(void *dummy) { zend_bool report_memleaks; - TSRMLS_FETCH(); report_memleaks = PG(report_memleaks); - /* EG(opline_ptr) points into nirvana and therefore cannot be safely accessed + /* EG(current_execute_data) points into nirvana and therefore cannot be safely accessed * inside zend_executor callback functions. */ - EG(opline_ptr) = NULL; - EG(active_op_array) = NULL; + EG(current_execute_data) = NULL; - php_deactivate_ticks(TSRMLS_C); + php_deactivate_ticks(); /* 1. Call all possible shutdown functions registered with register_shutdown_function() */ if (PG(modules_activated)) zend_try { - php_call_shutdown_functions(TSRMLS_C); + php_call_shutdown_functions(); } zend_end_try(); /* 2. Call all possible __destruct() functions */ zend_try { - zend_call_destructors(TSRMLS_C); + zend_call_destructors(); } zend_end_try(); /* 3. Flush all output buffers */ @@ -1829,32 +1766,32 @@ void php_request_shutdown(void *dummy) zend_bool send_buffer = SG(request_info).headers_only ? 0 : 1; if (CG(unclean_shutdown) && PG(last_error_type) == E_ERROR && - (size_t)PG(memory_limit) < zend_memory_usage(1 TSRMLS_CC) + (size_t)PG(memory_limit) < zend_memory_usage(1) ) { send_buffer = 0; } if (!send_buffer) { - php_output_discard_all(TSRMLS_C); + php_output_discard_all(); } else { - php_output_end_all(TSRMLS_C); + php_output_end_all(); } } zend_end_try(); /* 4. Reset max_execution_time (no longer executing php code after response sent) */ zend_try { - zend_unset_timeout(TSRMLS_C); + zend_unset_timeout(); } zend_end_try(); /* 5. Call all extensions RSHUTDOWN functions */ if (PG(modules_activated)) { - zend_deactivate_modules(TSRMLS_C); - php_free_shutdown_functions(TSRMLS_C); + zend_deactivate_modules(); + php_free_shutdown_functions(); } /* 6. Shutdown output layer (send the set HTTP headers, cleanup output handlers, etc.) */ zend_try { - php_output_deactivate(TSRMLS_C); + php_output_deactivate(); } zend_end_try(); /* 7. Destroy super-globals */ @@ -1862,53 +1799,43 @@ void php_request_shutdown(void *dummy) int i; for (i=0; i<NUM_TRACK_VARS; i++) { - if (PG(http_globals)[i]) { - zval_ptr_dtor(&PG(http_globals)[i]); - } + zval_ptr_dtor(&PG(http_globals)[i]); } } zend_end_try(); - /* 7.5 free last error information and temp dir */ - if (PG(last_error_message)) { - free(PG(last_error_message)); - PG(last_error_message) = NULL; - } - if (PG(last_error_file)) { - free(PG(last_error_file)); - PG(last_error_file) = NULL; - } - php_shutdown_temporary_directory(); + /* 8. free request-bound globals */ + php_free_request_globals(); - /* 7. Shutdown scanner/executor/compiler and restore ini entries */ - zend_deactivate(TSRMLS_C); + /* 9. Shutdown scanner/executor/compiler and restore ini entries */ + zend_deactivate(); - /* 8. Call all extensions post-RSHUTDOWN functions */ + /* 10. Call all extensions post-RSHUTDOWN functions */ zend_try { - zend_post_deactivate_modules(TSRMLS_C); + zend_post_deactivate_modules(); } zend_end_try(); - /* 9. SAPI related shutdown (free stuff) */ + /* 11. SAPI related shutdown (free stuff) */ zend_try { - sapi_deactivate(TSRMLS_C); + sapi_deactivate(); } zend_end_try(); - /* 9.5 free virtual CWD memory */ - virtual_cwd_deactivate(TSRMLS_C); + /* 12. free virtual CWD memory */ + virtual_cwd_deactivate(); - /* 10. Destroy stream hashes */ + /* 13. Destroy stream hashes */ zend_try { - php_shutdown_stream_hashes(TSRMLS_C); + php_shutdown_stream_hashes(); } zend_end_try(); - /* 11. Free Willy (here be crashes) */ + /* 14. Free Willy (here be crashes) */ + zend_interned_strings_restore(); zend_try { - shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0 TSRMLS_CC); + shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0); } zend_end_try(); - zend_interned_strings_restore(TSRMLS_C); - /* 12. Reset max_execution_time */ + /* 15. Reset max_execution_time */ zend_try { - zend_unset_timeout(TSRMLS_C); + zend_unset_timeout(); } zend_end_try(); #ifdef PHP_WIN32 @@ -1926,7 +1853,7 @@ void php_request_shutdown(void *dummy) /* {{{ php_com_initialize */ -PHPAPI void php_com_initialize(TSRMLS_D) +PHPAPI void php_com_initialize(void) { #ifdef PHP_WIN32 if (!PG(com_initialized)) { @@ -1940,28 +1867,25 @@ PHPAPI void php_com_initialize(TSRMLS_D) /* {{{ php_output_wrapper */ -static int php_output_wrapper(const char *str, uint str_length) +static size_t php_output_wrapper(const char *str, size_t str_length) { - TSRMLS_FETCH(); - return php_output_write(str, str_length TSRMLS_CC); + return php_output_write(str, str_length); } /* }}} */ #ifdef ZTS /* {{{ core_globals_ctor */ -static void core_globals_ctor(php_core_globals *core_globals TSRMLS_DC) +static void core_globals_ctor(php_core_globals *core_globals) { memset(core_globals, 0, sizeof(*core_globals)); - - php_startup_ticks(TSRMLS_C); } /* }}} */ #endif /* {{{ core_globals_dtor */ -static void core_globals_dtor(php_core_globals *core_globals TSRMLS_DC) +static void core_globals_dtor(php_core_globals *core_globals) { if (core_globals->last_error_message) { free(core_globals->last_error_message); @@ -1979,7 +1903,7 @@ static void core_globals_dtor(php_core_globals *core_globals TSRMLS_DC) free(core_globals->php_binary); } - php_shutdown_ticks(TSRMLS_C); + php_shutdown_ticks(); } /* }}} */ @@ -1993,13 +1917,13 @@ PHP_MINFO_FUNCTION(php_core) { /* {{{ */ /* {{{ php_register_extensions */ -int php_register_extensions(zend_module_entry **ptr, int count TSRMLS_DC) +int php_register_extensions(zend_module_entry **ptr, int count) { zend_module_entry **end = ptr + count; while (ptr < end) { if (*ptr) { - if (zend_register_internal_module(*ptr TSRMLS_CC)==NULL) { + if (zend_register_internal_module(*ptr)==NULL) { return FAILURE; } } @@ -2015,10 +1939,10 @@ int php_register_extensions(zend_module_entry **ptr, int count TSRMLS_DC) * * See algo: https://bugs.php.net/bug.php?id=63159 */ -static int php_register_extensions_bc(zend_module_entry *ptr, int count TSRMLS_DC) +static int php_register_extensions_bc(zend_module_entry *ptr, int count) { while (count--) { - if (zend_register_internal_module(ptr++ TSRMLS_CC) == NULL) { + if (zend_register_internal_module(ptr++) == NULL) { return FAILURE; } } @@ -2026,7 +1950,7 @@ static int php_register_extensions_bc(zend_module_entry *ptr, int count TSRMLS_D } /* }}} */ -#if defined(PHP_WIN32) && _MSC_VER >= 1400 +#ifdef PHP_WIN32 static _invalid_parameter_handler old_invalid_parameter_handler; void dummy_invalid_parameter_handler( @@ -2041,12 +1965,11 @@ void dummy_invalid_parameter_handler( int len; if (!called) { - TSRMLS_FETCH(); - if(PG(windows_show_crt_warning)) { + if(PG(windows_show_crt_warning)) { called = 1; if (function) { if (file) { - len = _snprintf(buf, sizeof(buf)-1, "Invalid parameter detected in CRT function '%ws' (%ws:%d)", function, file, line); + len = _snprintf(buf, sizeof(buf)-1, "Invalid parameter detected in CRT function '%ws' (%ws:%u)", function, file, line); } else { len = _snprintf(buf, sizeof(buf)-1, "Invalid parameter detected in CRT function '%ws'", function); } @@ -2069,11 +1992,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod int retval = SUCCESS, module_number=0; /* for REGISTER_INI_ENTRIES() */ char *php_os; zend_module_entry *module; -#ifdef ZTS - zend_executor_globals *executor_globals; - void ***tsrm_ls; - php_core_globals *core_globals; -#endif #if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) WORD wVersionRequested = MAKEWORD(2, 0); @@ -2081,7 +1999,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod #endif #ifdef PHP_WIN32 php_os = "WINNT"; -#if _MSC_VER >= 1400 + old_invalid_parameter_handler = _set_invalid_parameter_handler(dummy_invalid_parameter_handler); if (old_invalid_parameter_handler != NULL) { @@ -2090,13 +2008,12 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod /* Disable the message box for assertions.*/ _CrtSetReportMode(_CRT_ASSERT, 0); -#endif #else - php_os=PHP_OS; + php_os = PHP_OS; #endif #ifdef ZTS - tsrm_ls = ts_resource(0); + (void)ts_resource(0); #endif #ifdef PHP_WIN32 @@ -2105,8 +2022,8 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod module_shutdown = 0; module_startup = 1; - sapi_initialize_empty_request(TSRMLS_C); - sapi_activate(TSRMLS_C); + sapi_initialize_empty_request(); + sapi_activate(); if (module_initialized) { return SUCCESS; @@ -2116,6 +2033,17 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod php_output_startup(); +#ifdef ZTS + ts_allocate_id(&core_globals_id, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor); + php_startup_ticks(); +#ifdef PHP_WIN32 + ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor); +#endif +#else + php_startup_ticks(); +#endif + gc_globals_ctor(); + zuf.error_function = php_error_cb; zuf.printf_function = php_printf; zuf.write_function = php_output_wrapper; @@ -2128,53 +2056,10 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod zuf.on_timeout = php_on_timeout; zuf.stream_open_function = php_stream_open_for_zend; zuf.vspprintf_function = vspprintf; + zuf.vstrpprintf_function = vstrpprintf; zuf.getenv_function = sapi_getenv; zuf.resolve_path_function = php_resolve_path_for_zend; - zend_startup(&zuf, NULL TSRMLS_CC); - -#ifdef ZTS - executor_globals = ts_resource(executor_globals_id); - ts_allocate_id(&core_globals_id, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor); - core_globals = ts_resource(core_globals_id); -#ifdef PHP_WIN32 - ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor); -#endif -#else - php_startup_ticks(TSRMLS_C); -#endif - gc_globals_ctor(TSRMLS_C); - -#ifdef PHP_WIN32 - { - OSVERSIONINFOEX *osvi = &EG(windows_version_info); - - ZeroMemory(osvi, sizeof(OSVERSIONINFOEX)); - osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - if( !GetVersionEx((OSVERSIONINFO *) osvi)) { - php_printf("\nGetVersionEx unusable. %d\n", GetLastError()); - return FAILURE; - } - } -#endif - EG(bailout) = NULL; - EG(error_reporting) = E_ALL & ~E_NOTICE; - EG(active_symbol_table) = NULL; - PG(header_is_being_sent) = 0; - SG(request_info).headers_only = 0; - SG(request_info).argv0 = NULL; - SG(request_info).argc=0; - SG(request_info).argv=(char **)NULL; - PG(connection_status) = PHP_CONNECTION_NORMAL; - PG(during_request_startup) = 0; - PG(last_error_message) = NULL; - PG(last_error_file) = NULL; - PG(last_error_lineno) = 0; - EG(error_handling) = EH_NORMAL; - EG(exception_class) = NULL; - PG(disable_functions) = NULL; - PG(disable_classes) = NULL; - EG(exception) = NULL; - EG(objects_store).object_buckets = NULL; + zend_startup(&zuf, NULL); #if HAVE_SETLOCALE setlocale(LC_CTYPE, ""); @@ -2228,8 +2113,9 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS); REGISTER_MAIN_LONG_CONSTANT("PHP_MAXPATHLEN", MAXPATHLEN, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", LONG_MAX, CONST_PERSISTENT | CONST_CS); - REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", ZEND_LONG_MAX, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MIN", ZEND_LONG_MIN, CONST_PERSISTENT | CONST_CS); + REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", SIZEOF_ZEND_LONG, CONST_PERSISTENT | CONST_CS); #ifdef PHP_WIN32 REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_MAJOR", EG(windows_version_info).dwMajorVersion, CONST_PERSISTENT | CONST_CS); @@ -2245,20 +2131,20 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_WORKSTATION", VER_NT_WORKSTATION, CONST_PERSISTENT | CONST_CS); #endif - php_binary_init(TSRMLS_C); + php_binary_init(); if (PG(php_binary)) { REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", PG(php_binary), strlen(PG(php_binary)), CONST_PERSISTENT | CONST_CS); } else { REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", "", 0, CONST_PERSISTENT | CONST_CS); } - php_output_register_constants(TSRMLS_C); - php_rfc1867_register_constants(TSRMLS_C); + php_output_register_constants(); + php_rfc1867_register_constants(); /* this will read in php.ini, set up the configuration parameters, load zend extensions and register php function extensions to be loaded later */ - if (php_init_config(TSRMLS_C) == FAILURE) { + if (php_init_config() == FAILURE) { return FAILURE; } @@ -2266,7 +2152,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod REGISTER_INI_ENTRIES(); /* Register Zend ini entries */ - zend_register_standard_ini_entries(TSRMLS_C); + zend_register_standard_ini_entries(); /* Disable realpath cache if an open_basedir is set */ if (PG(open_basedir) && *PG(open_basedir)) { @@ -2276,70 +2162,62 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod /* initialize stream wrappers registry * (this uses configuration parameters from php.ini) */ - if (php_init_stream_wrappers(module_number TSRMLS_CC) == FAILURE) { + if (php_init_stream_wrappers(module_number) == FAILURE) { php_printf("PHP: Unable to initialize stream url wrappers.\n"); return FAILURE; } zuv.html_errors = 1; zuv.import_use_extension = ".php"; - php_startup_auto_globals(TSRMLS_C); + zuv.import_use_extension_length = (uint)strlen(zuv.import_use_extension); + php_startup_auto_globals(); zend_set_utility_values(&zuv); - php_startup_sapi_content_types(TSRMLS_C); + php_startup_sapi_content_types(); /* startup extensions statically compiled in */ - if (php_register_internal_extensions_func(TSRMLS_C) == FAILURE) { + if (php_register_internal_extensions_func() == FAILURE) { php_printf("Unable to start builtin modules\n"); return FAILURE; } /* start additional PHP extensions */ - php_register_extensions_bc(additional_modules, num_additional_modules TSRMLS_CC); + php_register_extensions_bc(additional_modules, num_additional_modules); /* load and startup extensions compiled as shared objects (aka DLLs) as requested by php.ini entries - theese are loaded after initialization of internal extensions + these are loaded after initialization of internal extensions as extensions *might* rely on things from ext/standard which is always an internal extension and to be initialized ahead of all other internals */ - php_ini_register_extensions(TSRMLS_C); - zend_startup_modules(TSRMLS_C); + php_ini_register_extensions(); + zend_startup_modules(); /* start Zend extensions */ zend_startup_extensions(); - zend_collect_module_handlers(TSRMLS_C); + zend_collect_module_handlers(); /* register additional functions */ if (sapi_module.additional_functions) { - if (zend_hash_find(&module_registry, "standard", sizeof("standard"), (void**)&module)==SUCCESS) { + if ((module = zend_hash_str_find_ptr(&module_registry, "standard", sizeof("standard")-1)) != NULL) { EG(current_module) = module; - zend_register_functions(NULL, sapi_module.additional_functions, NULL, MODULE_PERSISTENT TSRMLS_CC); + zend_register_functions(NULL, sapi_module.additional_functions, NULL, MODULE_PERSISTENT); EG(current_module) = NULL; } } /* disable certain classes and functions as requested by php.ini */ - php_disable_functions(TSRMLS_C); - php_disable_classes(TSRMLS_C); + php_disable_functions(); + php_disable_classes(); /* make core report what it should */ - if (zend_hash_find(&module_registry, "core", sizeof("core"), (void**)&module)==SUCCESS) { + if ((module = zend_hash_str_find_ptr(&module_registry, "core", sizeof("core")-1)) != NULL) { module->version = PHP_VERSION; module->info_func = PHP_MINFO(php_core); } - -#ifdef PHP_WIN32 - /* Disable incompatible functions for the running platform */ - if (php_win32_disable_functions(TSRMLS_C) == FAILURE) { - php_printf("Unable to disable unsupported functions\n"); - return FAILURE; - } -#endif - - zend_post_startup(TSRMLS_C); + zend_post_startup(); module_initialized = 1; @@ -2349,7 +2227,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod struct { const long error_level; const char *phrase; - const char *directives[16]; /* Remember to change this if the number of directives change */ + const char *directives[17]; /* Remember to change this if the number of directives change */ } directives[2] = { { E_DEPRECATED, @@ -2363,6 +2241,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod "Directive '%s' is no longer available in PHP", { "allow_call_time_pass_reference", + "asp_tags", "define_syslog_variables", "highlight.bg", "magic_quotes_gpc", @@ -2390,7 +2269,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod const char **p = directives[i].directives; while(*p) { - long value; + zend_long value; if (cfg_get_long((char*)*p, &value) == SUCCESS && value) { zend_error(directives[i].error_level, directives[i].phrase, *p); @@ -2404,12 +2283,12 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod } zend_end_try(); } - sapi_deactivate(TSRMLS_C); + sapi_deactivate(); module_startup = 0; - shutdown_memory_manager(1, 0 TSRMLS_CC); - zend_interned_strings_snapshot(TSRMLS_C); - virtual_cwd_activate(TSRMLS_C); + shutdown_memory_manager(1, 0); + zend_interned_strings_snapshot(); + virtual_cwd_activate(); /* we're done */ return retval; @@ -2425,15 +2304,14 @@ void php_module_shutdown_for_exec(void) */ int php_module_shutdown_wrapper(sapi_module_struct *sapi_globals) { - TSRMLS_FETCH(); - php_module_shutdown(TSRMLS_C); + php_module_shutdown(); return SUCCESS; } /* }}} */ /* {{{ php_module_shutdown */ -void php_module_shutdown(TSRMLS_D) +void php_module_shutdown(void) { int module_number=0; /* for UNREGISTER_INI_ENTRIES() */ @@ -2456,12 +2334,12 @@ void php_module_shutdown(TSRMLS_D) php_win32_free_rng_lock(); #endif - sapi_flush(TSRMLS_C); + sapi_flush(); - zend_shutdown(TSRMLS_C); + zend_shutdown(); /* Destroys filter & transport registries too */ - php_shutdown_stream_wrappers(module_number TSRMLS_CC); + php_shutdown_stream_wrappers(module_number); UNREGISTER_INI_ENTRIES(); @@ -2469,10 +2347,10 @@ void php_module_shutdown(TSRMLS_D) php_shutdown_config(); #ifndef ZTS - zend_ini_shutdown(TSRMLS_C); - shutdown_memory_manager(CG(unclean_shutdown), 1 TSRMLS_CC); + zend_ini_shutdown(); + shutdown_memory_manager(CG(unclean_shutdown), 1); #else - zend_ini_global_shutdown(TSRMLS_C); + zend_ini_global_shutdown(); #endif php_output_shutdown(); @@ -2480,13 +2358,13 @@ void php_module_shutdown(TSRMLS_D) module_initialized = 0; #ifndef ZTS - core_globals_dtor(&core_globals TSRMLS_CC); - gc_globals_dtor(TSRMLS_C); + core_globals_dtor(&core_globals); + gc_globals_dtor(); #else ts_free_id(core_globals_id); #endif -#if defined(PHP_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1400) +#ifdef PHP_WIN32 if (old_invalid_parameter_handler == NULL) { _set_invalid_parameter_handler(old_invalid_parameter_handler); } @@ -2496,11 +2374,11 @@ void php_module_shutdown(TSRMLS_D) /* {{{ php_execute_script */ -PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC) +PHPAPI int php_execute_script(zend_file_handle *primary_file) { zend_file_handle *prepend_file_p, *append_file_p; - zend_file_handle prepend_file = {0}, append_file = {0}; -#if HAVE_BROKEN_GETCWD + zend_file_handle prepend_file = {{0}, NULL, NULL, 0, 0}, append_file = {{0}, NULL, NULL, 0, 0}; +#if HAVE_BROKEN_GETCWD volatile int old_cwd_fd = -1; #else char *old_cwd; @@ -2520,7 +2398,7 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC) #ifdef PHP_WIN32 if(primary_file->filename) { - UpdateIniFromRegistry(primary_file->filename TSRMLS_CC); + UpdateIniFromRegistry((char*)primary_file->filename); } #endif @@ -2544,13 +2422,9 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC) primary_file->opened_path == NULL && primary_file->type != ZEND_HANDLE_FILENAME ) { - int realfile_len; - int dummy = 1; - - if (expand_filepath(primary_file->filename, realfile TSRMLS_CC)) { - realfile_len = strlen(realfile); - zend_hash_add(&EG(included_files), realfile, realfile_len+1, (void *)&dummy, sizeof(int), NULL); - primary_file->opened_path = estrndup(realfile, realfile_len); + if (expand_filepath(primary_file->filename, realfile)) { + primary_file->opened_path = zend_string_init(realfile, strlen(realfile), 0); + zend_hash_add_empty_element(&EG(included_files), primary_file->opened_path); } } @@ -2575,7 +2449,7 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC) } if (PG(max_input_time) != -1) { #ifdef PHP_WIN32 - zend_unset_timeout(TSRMLS_C); + zend_unset_timeout(); #endif zend_set_timeout(INI_INT("max_execution_time"), 0); } @@ -2589,15 +2463,21 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC) int orig_start_lineno = CG(start_lineno); CG(start_lineno) = 0; - if (zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, NULL, 1, prepend_file_p) == SUCCESS) { + if (zend_execute_scripts(ZEND_REQUIRE, NULL, 1, prepend_file_p) == SUCCESS) { CG(start_lineno) = orig_start_lineno; - retval = (zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, NULL, 2, primary_file, append_file_p) == SUCCESS); + retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 2, primary_file, append_file_p) == SUCCESS); } } else { - retval = (zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS); + retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS); } } zend_end_try(); + if (EG(exception)) { + zend_try { + zend_exception_error(EG(exception), E_ERROR); + } zend_end_try(); + } + #if HAVE_BROKEN_GETCWD if (old_cwd_fd != -1) { fchdir(old_cwd_fd); @@ -2615,7 +2495,7 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC) /* {{{ php_execute_simple_script */ -PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret TSRMLS_DC) +PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval *ret) { char *old_cwd; ALLOCA_FLAG(use_heap) @@ -2628,7 +2508,7 @@ PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret zend_try { #ifdef PHP_WIN32 if(primary_file->filename) { - UpdateIniFromRegistry(primary_file->filename TSRMLS_CC); + UpdateIniFromRegistry((char*)primary_file->filename); } #endif @@ -2638,7 +2518,7 @@ PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1)); VCWD_CHDIR_FILE(primary_file->filename); } - zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, ret, 1, primary_file); + zend_execute_scripts(ZEND_REQUIRE, ret, 1, primary_file); } zend_end_try(); if (old_cwd[0] != '\0') { @@ -2654,10 +2534,9 @@ PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret */ PHPAPI void php_handle_aborted_connection(void) { - TSRMLS_FETCH(); PG(connection_status) = PHP_CONNECTION_ABORTED; - php_output_set_status(PHP_OUTPUT_DISABLED TSRMLS_CC); + php_output_set_status(PHP_OUTPUT_DISABLED); if (!PG(ignore_user_abort)) { zend_bailout(); @@ -2667,25 +2546,24 @@ PHPAPI void php_handle_aborted_connection(void) /* {{{ php_handle_auth_data */ -PHPAPI int php_handle_auth_data(const char *auth TSRMLS_DC) +PHPAPI int php_handle_auth_data(const char *auth) { int ret = -1; if (auth && auth[0] != '\0' && strncmp(auth, "Basic ", 6) == 0) { char *pass; - char *user; + zend_string *user; - user = php_base64_decode(auth + 6, strlen(auth) - 6, NULL); + user = php_base64_decode((const unsigned char*)auth + 6, strlen(auth) - 6); if (user) { - pass = strchr(user, ':'); + pass = strchr(ZSTR_VAL(user), ':'); if (pass) { *pass++ = '\0'; - SG(request_info).auth_user = user; + SG(request_info).auth_user = estrndup(ZSTR_VAL(user), ZSTR_LEN(user)); SG(request_info).auth_password = estrdup(pass); ret = 0; - } else { - efree(user); } + zend_string_free(user); } } @@ -2710,36 +2588,29 @@ PHPAPI int php_handle_auth_data(const char *auth TSRMLS_DC) /* {{{ php_lint_script */ -PHPAPI int php_lint_script(zend_file_handle *file TSRMLS_DC) +PHPAPI int php_lint_script(zend_file_handle *file) { zend_op_array *op_array; int retval = FAILURE; zend_try { - op_array = zend_compile_file(file, ZEND_INCLUDE TSRMLS_CC); - zend_destroy_file_handle(file TSRMLS_CC); + op_array = zend_compile_file(file, ZEND_INCLUDE); + zend_destroy_file_handle(file); if (op_array) { - destroy_op_array(op_array TSRMLS_CC); + destroy_op_array(op_array); efree(op_array); retval = SUCCESS; } } zend_end_try(); + if (EG(exception)) { + zend_exception_error(EG(exception), E_ERROR); + } return retval; } /* }}} */ -#ifdef PHP_WIN32 -/* {{{ dummy_indent - just so that this symbol gets exported... */ -PHPAPI void dummy_indent(void) -{ - zend_indent(); -} -/* }}} */ -#endif - /* * Local variables: * tab-width: 4 diff --git a/main/mergesort.c b/main/mergesort.c index 4555e1bc8f..a482f5b0fe 100644 --- a/main/mergesort.c +++ b/main/mergesort.c @@ -66,8 +66,8 @@ static char sccsid[] = "@(#)merge.c 8.2 (Berkeley) 2/14/94"; #include <winsock2.h> /* Includes definition for u_char */ #endif -static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp)(const void *, const void * TSRMLS_DC) TSRMLS_DC); -static void insertionsort(u_char *a, size_t n, size_t size, int (*cmp)(const void *, const void * TSRMLS_DC) TSRMLS_DC); +static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp)(const void *, const void *)); +static void insertionsort(u_char *a, size_t n, size_t size, int (*cmp)(const void *, const void *)); #define ISIZE sizeof(int) #define PSIZE sizeof(u_char *) @@ -102,9 +102,9 @@ static void insertionsort(u_char *a, size_t n, size_t size, int (*cmp)(const voi /* {{{ php_mergesort * Arguments are as for qsort. */ -PHPAPI int php_mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void * TSRMLS_DC) TSRMLS_DC) +PHPAPI int php_mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *)) { - register unsigned int i; + register size_t i; register int sense; int big, iflag; register u_char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; @@ -130,7 +130,7 @@ PHPAPI int php_mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const return (-1); list1 = base; - setup(list1, list2, nmemb, size, cmp TSRMLS_CC); + setup(list1, list2, nmemb, size, cmp); last = list2 + nmemb * size; i = big = 0; while (*EVAL(list2) != last) { @@ -144,7 +144,7 @@ PHPAPI int php_mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const p2 = *EVAL(p2); l2 = list1 + (p2 - list2); while (f1 < l1 && f2 < l2) { - if ((*cmp)(f1, f2 TSRMLS_CC) <= 0) { + if ((*cmp)(f1, f2) <= 0) { q = f2; b = f1, t = l1; sense = -1; @@ -154,7 +154,7 @@ PHPAPI int php_mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const sense = 0; } if (!big) { /* here i = 0 */ - while ((b += size) < t && cmp(q, b TSRMLS_CC) >sense) + while ((b += size) < t && cmp(q, b) >sense) if (++i == 6) { big = 1; goto EXPONENTIAL; @@ -163,12 +163,12 @@ PHPAPI int php_mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const EXPONENTIAL: for (i = size; ; i <<= 1) if ((p = (b + i)) >= t) { if ((p = t - size) > b && - (*cmp)(q, p TSRMLS_CC) <= sense) + (*cmp)(q, p) <= sense) t = p; else b = p; break; - } else if ((*cmp)(q, p TSRMLS_CC) <= sense) { + } else if ((*cmp)(q, p) <= sense) { t = p; if (i == size) big = 0; @@ -177,7 +177,7 @@ EXPONENTIAL: for (i = size; ; i <<= 1) b = p; while (t > b+size) { i = (((t - b) / size) >> 1) * size; - if ((*cmp)(q, p = b + i TSRMLS_CC) <= sense) + if ((*cmp)(q, p = b + i) <= sense) t = p; else b = p; @@ -185,7 +185,7 @@ EXPONENTIAL: for (i = size; ; i <<= 1) goto COPY; FASTCASE: while (i > size) if ((*cmp)(q, - p = b + (i >>= 1) TSRMLS_CC) <= sense) + p = b + (i >>= 1)) <= sense) t = p; else b = p; @@ -262,14 +262,14 @@ COPY: b = t; * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL * is defined. Otherwise simple pairwise merging is used.) */ -static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp)(const void *, const void * TSRMLS_DC) TSRMLS_DC) +static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp)(const void *, const void *)) { - int i, length, size2, tmp, sense; - u_char *f1, *f2, *s, *l2, *last, *p2; + size_t i, length, size2, sense; + u_char *f1, *f2, *s, *l2, *last, *p2, tmp; size2 = size*2; if (n <= 5) { - insertionsort(list1, n, size, cmp TSRMLS_CC); + insertionsort(list1, n, size, cmp); *EVAL(list2) = (u_char*) list2 + n*size; return; } @@ -278,19 +278,19 @@ static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp * for simplicity. */ i = 4 + (n & 1); - insertionsort(list1 + (n - i) * size, i, size, cmp TSRMLS_CC); + insertionsort(list1 + (n - i) * size, i, size, cmp); last = list1 + size * (n - i); *EVAL(list2 + (last - list1)) = list2 + n * size; #ifdef NATURAL p2 = list2; f1 = list1; - sense = (cmp(f1, f1 + size TSRMLS_CC) > 0); + sense = (cmp(f1, f1 + size) > 0); for (; f1 < last; sense = !sense) { length = 2; /* Find pairs with same sense. */ for (f2 = f1 + size2; f2 < last; f2 += size2) { - if ((cmp(f2, f2+ size TSRMLS_CC) > 0) != sense) + if ((cmp(f2, f2+ size) > 0) != sense) break; length += 2; } @@ -303,7 +303,7 @@ static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp } else { /* Natural merge */ l2 = f2; for (f2 = f1 + size2; f2 < l2; f2 += size2) { - if ((cmp(f2-size, f2 TSRMLS_CC) > 0) != sense) { + if ((cmp(f2-size, f2) > 0) != sense) { p2 = *EVAL(p2) = f2 - list1 + list2; if (sense > 0) reverse(f1, f2-size); @@ -313,7 +313,7 @@ static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp if (sense > 0) reverse (f1, f2-size); f1 = f2; - if (f2 < last || cmp(f2 - size, f2 TSRMLS_CC) > 0) + if (f2 < last || cmp(f2 - size, f2) > 0) p2 = *EVAL(p2) = f2 - list1 + list2; else p2 = *EVAL(p2) = list2 + n*size; @@ -322,7 +322,7 @@ static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp #else /* pairwise merge only. */ for (f1 = list1, p2 = list2; f1 < last; f1 += size2) { p2 = *EVAL(p2) = p2 + size2; - if (cmp (f1, f1 + size TSRMLS_CC) > 0) + if (cmp (f1, f1 + size) > 0) swap(f1, f1 + size); } #endif /* NATURAL */ @@ -333,15 +333,15 @@ static void setup(u_char *list1, u_char *list2, size_t n, size_t size, int (*cmp * This is to avoid out-of-bounds addresses in sorting the * last 4 elements. */ -static void insertionsort(u_char *a, size_t n, size_t size, int (*cmp)(const void *, const void * TSRMLS_DC) TSRMLS_DC) +static void insertionsort(u_char *a, size_t n, size_t size, int (*cmp)(const void *, const void *)) { u_char *ai, *s, *t, *u, tmp; - int i; + size_t i; for (ai = a+size; --n >= 1; ai += size) for (t = ai; t > a; t -= size) { u = t - size; - if (cmp(u, t TSRMLS_CC) <= 0) + if (cmp(u, t) <= 0) break; swap(u, t); } diff --git a/main/network.c b/main/network.c index 636afc62b0..c08194bcd6 100644 --- a/main/network.c +++ b/main/network.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -166,7 +166,7 @@ PHPAPI void php_network_freeaddresses(struct sockaddr **sal) /* {{{ php_network_getaddresses * Returns number of addresses, 0 for none/error */ -PHPAPI int php_network_getaddresses(const char *host, int socktype, struct sockaddr ***sal, char **error_string TSRMLS_DC) +PHPAPI int php_network_getaddresses(const char *host, int socktype, struct sockaddr ***sal, zend_string **error_string) { struct sockaddr **sap; int n; @@ -212,18 +212,18 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka if ((n = getaddrinfo(host, NULL, &hints, &res))) { if (error_string) { - spprintf(error_string, 0, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n)); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", *error_string); + *error_string = strpprintf(0, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n)); + php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string)); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n)); + php_error_docref(NULL, E_WARNING, "php_network_getaddresses: getaddrinfo failed: %s", PHP_GAI_STRERROR(n)); } return 0; } else if (res == NULL) { if (error_string) { - spprintf(error_string, 0, "php_network_getaddresses: getaddrinfo failed (null result pointer) errno=%d", errno); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", *error_string); + *error_string = strpprintf(0, "php_network_getaddresses: getaddrinfo failed (null result pointer) errno=%d", errno); + php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string)); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_network_getaddresses: getaddrinfo failed (null result pointer)"); + php_error_docref(NULL, E_WARNING, "php_network_getaddresses: getaddrinfo failed (null result pointer)"); } return 0; } @@ -254,10 +254,10 @@ PHPAPI int php_network_getaddresses(const char *host, int socktype, struct socka } if (host_info == NULL) { if (error_string) { - spprintf(error_string, 0, "php_network_getaddresses: gethostbyname failed. errno=%d", errno); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", *error_string); + error_string = strpprintf(0, "php_network_getaddresses: gethostbyname failed. errno=%d", errno); + php_error_docref(NULL, E_WARNING, "%s", ZSTR_VAL(*error_string)); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "php_network_getaddresses: gethostbyname failed"); + php_error_docref(NULL, E_WARNING, "php_network_getaddresses: gethostbyname failed"); } return 0; } @@ -310,7 +310,7 @@ PHPAPI int php_network_connect_socket(php_socket_t sockfd, socklen_t addrlen, int asynchronous, struct timeval *timeout, - char **error_string, + zend_string **error_string, int *error_code) { #if HAVE_NON_BLOCKING_CONNECT @@ -331,7 +331,7 @@ PHPAPI int php_network_connect_socket(php_socket_t sockfd, if (error != EINPROGRESS) { if (error_string) { - *error_string = php_socket_strerror(error, NULL, 0); + *error_string = php_socket_error_str(error); } return -1; @@ -387,13 +387,13 @@ ok: if (error) { ret = -1; if (error_string) { - *error_string = php_socket_strerror(error, NULL, 0); + *error_string = php_socket_error_str(error); } } return ret; #else if (asynchronous) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Asynchronous connect() not supported on this platform"); + php_error_docref(NULL, E_WARNING, "Asynchronous connect() not supported on this platform"); } return (connect(sockfd, addr, addrlen) == 0) ? 0 : -1; #endif @@ -421,15 +421,16 @@ static inline void sub_times(struct timeval a, struct timeval b, struct timeval * */ /* {{{ php_network_bind_socket_to_local_addr */ php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned port, - int socktype, char **error_string, int *error_code - TSRMLS_DC) + int socktype, long sockopts, zend_string **error_string, int *error_code + ) { int num_addrs, n, err = 0; php_socket_t sock; struct sockaddr **sal, **psal, *sa; socklen_t socklen; + int sockoptval = 1; - num_addrs = php_network_getaddresses(host, socktype, &psal, error_string TSRMLS_CC); + num_addrs = php_network_getaddresses(host, socktype, &psal, error_string); if (num_addrs == 0) { /* could not resolve address(es) */ @@ -469,9 +470,16 @@ php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned po /* attempt to bind */ #ifdef SO_REUSEADDR - { - int val = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&val, sizeof(val)); + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&sockoptval, sizeof(sockoptval)); +#endif +#ifdef SO_REUSEPORT + if (sockopts & STREAM_SOCKOP_SO_REUSEPORT) { + setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char*)&sockoptval, sizeof(sockoptval)); + } +#endif +#ifdef SO_BROADCAST + if (sockopts & STREAM_SOCKOP_SO_BROADCAST) { + setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&sockoptval, sizeof(sockoptval)); } #endif @@ -492,7 +500,7 @@ php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned po *error_code = err; } if (error_string) { - *error_string = php_socket_strerror(err, NULL, 0); + *error_string = php_socket_error_str(err); } bound: @@ -504,7 +512,7 @@ bound: } /* }}} */ -PHPAPI int php_network_parse_network_address_with_port(const char *addr, long addrlen, struct sockaddr *sa, socklen_t *sl TSRMLS_DC) +PHPAPI int php_network_parse_network_address_with_port(const char *addr, zend_long addrlen, struct sockaddr *sa, socklen_t *sl) { char *colon; char *tmp; @@ -513,7 +521,7 @@ PHPAPI int php_network_parse_network_address_with_port(const char *addr, long ad struct sockaddr_in *in4 = (struct sockaddr_in*)sa; struct sockaddr **psal; int n; - char *errstr = NULL; + zend_string *errstr = NULL; #if HAVE_IPV6 struct sockaddr_in6 *in6 = (struct sockaddr_in6*)sa; #endif @@ -555,12 +563,12 @@ PHPAPI int php_network_parse_network_address_with_port(const char *addr, long ad } /* looks like we'll need to resolve it */ - n = php_network_getaddresses(tmp, SOCK_DGRAM, &psal, &errstr TSRMLS_CC); + n = php_network_getaddresses(tmp, SOCK_DGRAM, &psal, &errstr); if (n == 0) { if (errstr) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to resolve `%s': %s", tmp, errstr); - STR_FREE(errstr); + php_error_docref(NULL, E_WARNING, "Failed to resolve `%s': %s", tmp, ZSTR_VAL(errstr)); + zend_string_release(errstr); } goto out; } @@ -586,7 +594,7 @@ PHPAPI int php_network_parse_network_address_with_port(const char *addr, long ad php_network_freeaddresses(psal); out: - STR_FREE(tmp); + efree(tmp); return ret; } @@ -595,11 +603,11 @@ PHPAPI void php_network_populate_name_from_sockaddr( /* input address */ struct sockaddr *sa, socklen_t sl, /* output readable address */ - char **textaddr, long *textaddrlen, + zend_string **textaddr, /* output address */ struct sockaddr **addr, socklen_t *addrlen - TSRMLS_DC) + ) { if (addr) { *addr = emalloc(sl); @@ -618,7 +626,7 @@ PHPAPI void php_network_populate_name_from_sockaddr( /* generally not thread safe, but it *is* thread safe under win32 */ buf = inet_ntoa(((struct sockaddr_in*)sa)->sin_addr); if (buf) { - *textaddrlen = spprintf(textaddr, 0, "%s:%d", + *textaddr = strpprintf(0, "%s:%d", buf, ntohs(((struct sockaddr_in*)sa)->sin_port)); } @@ -628,7 +636,7 @@ PHPAPI void php_network_populate_name_from_sockaddr( case AF_INET6: buf = (char*)inet_ntop(sa->sa_family, &((struct sockaddr_in6*)sa)->sin6_addr, (char *)&abuf, sizeof(abuf)); if (buf) { - *textaddrlen = spprintf(textaddr, 0, "%s:%d", + *textaddr = strpprintf(0, "%s:%d", buf, ntohs(((struct sockaddr_in6*)sa)->sin6_port)); } @@ -642,13 +650,10 @@ PHPAPI void php_network_populate_name_from_sockaddr( if (ua->sun_path[0] == '\0') { /* abstract name */ int len = strlen(ua->sun_path + 1) + 1; - *textaddrlen = len; - *textaddr = emalloc(len + 1); - memcpy(*textaddr, ua->sun_path, len); - (*textaddr)[len] = '\0'; + *textaddr = zend_string_init((char*)ua->sun_path, len, 0); } else { - *textaddrlen = strlen(ua->sun_path); - *textaddr = estrndup(ua->sun_path, *textaddrlen); + int len = strlen(ua->sun_path); + *textaddr = zend_string_init((char*)ua->sun_path, len, 0); } } break; @@ -660,10 +665,10 @@ PHPAPI void php_network_populate_name_from_sockaddr( } PHPAPI int php_network_get_peer_name(php_socket_t sock, - char **textaddr, long *textaddrlen, + zend_string **textaddr, struct sockaddr **addr, socklen_t *addrlen - TSRMLS_DC) + ) { php_sockaddr_storage sa; socklen_t sl = sizeof(sa); @@ -671,19 +676,19 @@ PHPAPI int php_network_get_peer_name(php_socket_t sock, if (getpeername(sock, (struct sockaddr*)&sa, &sl) == 0) { php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl, - textaddr, textaddrlen, + textaddr, addr, addrlen - TSRMLS_CC); + ); return 0; } return -1; } PHPAPI int php_network_get_sock_name(php_socket_t sock, - char **textaddr, long *textaddrlen, + zend_string **textaddr, struct sockaddr **addr, socklen_t *addrlen - TSRMLS_DC) + ) { php_sockaddr_storage sa; socklen_t sl = sizeof(sa); @@ -691,9 +696,9 @@ PHPAPI int php_network_get_sock_name(php_socket_t sock, if (getsockname(sock, (struct sockaddr*)&sa, &sl) == 0) { php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl, - textaddr, textaddrlen, + textaddr, addr, addrlen - TSRMLS_CC); + ); return 0; } return -1; @@ -705,19 +710,19 @@ PHPAPI int php_network_get_sock_name(php_socket_t sock, * using an optional timeout. * Returns the peer address in addr/addrlen (it will emalloc * these, so be sure to efree the result). - * If you specify textaddr/textaddrlen, a text-printable + * If you specify textaddr, a text-printable * version of the address will be emalloc'd and returned. * */ /* {{{ php_network_accept_incoming */ PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock, - char **textaddr, long *textaddrlen, + zend_string **textaddr, struct sockaddr **addr, socklen_t *addrlen, struct timeval *timeout, - char **error_string, + zend_string **error_string, int *error_code - TSRMLS_DC) + ) { php_socket_t clisock = -1; int error = 0, n; @@ -737,9 +742,9 @@ PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock, if (clisock != SOCK_ERR) { php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl, - textaddr, textaddrlen, + textaddr, addr, addrlen - TSRMLS_CC); + ); } else { error = php_socket_errno(); } @@ -749,7 +754,7 @@ PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock, *error_code = error; } if (error_string) { - *error_string = php_socket_strerror(error, NULL, 0); + *error_string = php_socket_error_str(error); } return clisock; @@ -766,9 +771,9 @@ PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock, /* {{{ php_network_connect_socket_to_host */ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short port, - int socktype, int asynchronous, struct timeval *timeout, char **error_string, - int *error_code, char *bindto, unsigned short bindport - TSRMLS_DC) + int socktype, int asynchronous, struct timeval *timeout, zend_string **error_string, + int *error_code, char *bindto, unsigned short bindport, long sockopts + ) { int num_addrs, n, fatal = 0; php_socket_t sock; @@ -779,7 +784,7 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short struct timeval limit_time, time_now; #endif - num_addrs = php_network_getaddresses(host, socktype, &psal, error_string TSRMLS_CC); + num_addrs = php_network_getaddresses(host, socktype, &psal, error_string); if (num_addrs == 0) { /* could not resolve address(es) */ @@ -849,7 +854,7 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short in4->sin_family = sa->sa_family; in4->sin_port = htons(bindport); if (!inet_aton(bindto, &in4->sin_addr)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid IP Address: %s", bindto); + php_error_docref(NULL, E_WARNING, "Invalid IP Address: %s", bindto); goto skip_bind; } memset(&(in4->sin_zero), 0, sizeof(in4->sin_zero)); @@ -864,13 +869,14 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short in6->sin6_family = sa->sa_family; in6->sin6_port = htons(bindport); if (inet_pton(AF_INET6, bindto, &in6->sin6_addr) < 1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid IP Address: %s", bindto); + php_error_docref(NULL, E_WARNING, "Invalid IP Address: %s", bindto); goto skip_bind; } } #endif + if (!local_address || bind(sock, local_address, local_address_len)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to bind to '%s:%d', system said: %s", bindto, bindport, strerror(errno)); + php_error_docref(NULL, E_WARNING, "failed to bind to '%s:%d', system said: %s", bindto, bindport, strerror(errno)); } skip_bind: if (local_address) { @@ -879,10 +885,18 @@ skip_bind: } /* free error string received during previous iteration (if any) */ if (error_string && *error_string) { - efree(*error_string); + zend_string_release(*error_string); *error_string = NULL; } +#ifdef SO_BROADCAST + { + int val = 1; + if (sockopts & STREAM_SOCKOP_SO_BROADCAST) { + setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&val, sizeof(val)); + } + } +#endif n = php_network_connect_socket(sock, sa, socklen, asynchronous, timeout ? &working_timeout : NULL, error_string, error_code); @@ -1034,8 +1048,46 @@ PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize) } /* }}} */ +/* {{{ php_socket_error_str */ +PHPAPI zend_string *php_socket_error_str(long err) +{ +#ifndef PHP_WIN32 + char *errstr; + + errstr = strerror(err); + return zend_string_init(errstr, strlen(errstr), 0); +#else + zend_string *ret; + char *sysbuf; + int free_it = 1; + + if (!FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&sysbuf, + 0, + NULL)) { + free_it = 0; + sysbuf = "Unknown Error"; + } + + ret = zend_string_init(sysbuf, strlen(sysbuf), 0); + + if (free_it) { + LocalFree(sysbuf); + } + + return ret; +#endif +} +/* }}} */ + /* deprecated */ -PHPAPI php_stream *_php_stream_sock_open_from_socket(php_socket_t socket, const char *persistent_id STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_sock_open_from_socket(php_socket_t socket, const char *persistent_id STREAMS_DC) { php_stream *stream; php_netstream_data_t *sock; @@ -1060,10 +1112,10 @@ PHPAPI php_stream *_php_stream_sock_open_from_socket(php_socket_t socket, const } PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port, - int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC TSRMLS_DC) + int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC) { char *res; - long reslen; + zend_long reslen; php_stream *stream; reslen = spprintf(&res, 0, "tcp://%s:%d", host, port); @@ -1076,20 +1128,22 @@ PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short p return stream; } -PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC) +PHPAPI int php_set_sock_blocking(php_socket_t socketd, int block) { int ret = SUCCESS; - int flags; - int myflag = 0; #ifdef PHP_WIN32 + u_long flags; + /* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */ flags = !block; if (ioctlsocket(socketd, FIONBIO, &flags) == SOCKET_ERROR) { ret = FAILURE; } #else - flags = fcntl(socketd, F_GETFL); + int myflag = 0; + int flags = fcntl(socketd, F_GETFL); + #ifdef O_NONBLOCK myflag = O_NONBLOCK; /* POSIX version */ #elif defined(O_NDELAY) @@ -1109,10 +1163,9 @@ PHPAPI int php_set_sock_blocking(int socketd, int block TSRMLS_DC) PHPAPI void _php_emit_fd_setsize_warning(int max_fd) { - TSRMLS_FETCH(); #ifdef PHP_WIN32 - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "PHP needs to be recompiled with a larger value of FD_SETSIZE.\n" "If this binary is from an official www.php.net package, file a bug report\n" "at http://bugs.php.net, including the following information:\n" @@ -1122,7 +1175,7 @@ PHPAPI void _php_emit_fd_setsize_warning(int max_fd) "one time, in order to avoid seeing this error again at a later date.", FD_SETSIZE, max_fd, (max_fd + 128) & ~127); #else - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "You MUST recompile PHP with a larger value of FD_SETSIZE.\n" "It is set to %d, but you have descriptors numbered at least as high as %d.\n" " --enable-fd-setsize=%d is recommended, but you may want to set it\n" diff --git a/main/output.c b/main/output.c index 456241f4e9..831c11f14a 100644 --- a/main/output.c +++ b/main/output.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -52,20 +52,20 @@ static HashTable php_output_handler_reverse_conflicts; /* }}} */ /* {{{ forward declarations */ -static inline int php_output_lock_error(int op TSRMLS_DC); -static inline void php_output_op(int op, const char *str, size_t len TSRMLS_DC); +static inline int php_output_lock_error(int op); +static inline void php_output_op(int op, const char *str, size_t len); -static inline php_output_handler *php_output_handler_init(const char *name, size_t name_len, size_t chunk_size, int flags TSRMLS_DC); +static inline php_output_handler *php_output_handler_init(zend_string *name, size_t chunk_size, int flags); static inline php_output_handler_status_t php_output_handler_op(php_output_handler *handler, php_output_context *context); -static inline int php_output_handler_append(php_output_handler *handler, const php_output_buffer *buf TSRMLS_DC); +static inline int php_output_handler_append(php_output_handler *handler, const php_output_buffer *buf); static inline zval *php_output_handler_status(php_output_handler *handler, zval *entry); -static inline php_output_context *php_output_context_init(php_output_context *context, int op TSRMLS_DC); +static inline php_output_context *php_output_context_init(php_output_context *context, int op); static inline void php_output_context_reset(php_output_context *context); static inline void php_output_context_swap(php_output_context *context); static inline void php_output_context_dtor(php_output_context *context); -static inline int php_output_stack_pop(int flags TSRMLS_DC); +static inline int php_output_stack_pop(int flags); static int php_output_stack_apply_op(void *h, void *c); static int php_output_stack_apply_clean(void *h, void *c); @@ -81,17 +81,18 @@ static int php_output_handler_devnull_func(void **handler_context, php_output_co * Initialize the module globals on MINIT */ static inline void php_output_init_globals(zend_output_globals *G) { + ZEND_TSRMLS_CACHE_UPDATE(); memset(G, 0, sizeof(*G)); } /* }}} */ /* {{{ stderr/stdout writer if not PHP_OUTPUT_ACTIVATED */ -static int php_output_stdout(const char *str, size_t str_len) +static size_t php_output_stdout(const char *str, size_t str_len) { fwrite(str, 1, str_len, stdout); return str_len; } -static int php_output_stderr(const char *str, size_t str_len) +static size_t php_output_stderr(const char *str, size_t str_len) { fwrite(str, 1, str_len, stderr); /* See http://support.microsoft.com/kb/190351 */ @@ -100,40 +101,46 @@ static int php_output_stderr(const char *str, size_t str_len) #endif return str_len; } -static int (*php_output_direct)(const char *str, size_t str_len) = php_output_stderr; +static size_t (*php_output_direct)(const char *str, size_t str_len) = php_output_stderr; /* }}} */ -/* {{{ void php_output_header(TSRMLS_D) */ -static void php_output_header(TSRMLS_D) +/* {{{ void php_output_header(void) */ +static void php_output_header(void) { if (!SG(headers_sent)) { if (!OG(output_start_filename)) { - if (zend_is_compiling(TSRMLS_C)) { - OG(output_start_filename) = zend_get_compiled_filename(TSRMLS_C); - OG(output_start_lineno) = zend_get_compiled_lineno(TSRMLS_C); - } else if (zend_is_executing(TSRMLS_C)) { - OG(output_start_filename) = zend_get_executed_filename(TSRMLS_C); - OG(output_start_lineno) = zend_get_executed_lineno(TSRMLS_C); + if (zend_is_compiling()) { + OG(output_start_filename) = ZSTR_VAL(zend_get_compiled_filename()); + OG(output_start_lineno) = zend_get_compiled_lineno(); + } else if (zend_is_executing()) { + OG(output_start_filename) = zend_get_executed_filename(); + OG(output_start_lineno) = zend_get_executed_lineno(); } #if PHP_OUTPUT_DEBUG fprintf(stderr, "!!! output started at: %s (%d)\n", OG(output_start_filename), OG(output_start_lineno)); #endif } - if (!php_header(TSRMLS_C)) { + if (!php_header()) { OG(flags) |= PHP_OUTPUT_DISABLED; } } } /* }}} */ +static void reverse_conflict_dtor(zval *zv) +{ + HashTable *ht = Z_PTR_P(zv); + zend_hash_destroy(ht); +} + /* {{{ void php_output_startup(void) * Set up module globals and initalize the conflict and reverse conflict hash tables */ PHPAPI void php_output_startup(void) { ZEND_INIT_MODULE_GLOBALS(output, php_output_init_globals, NULL); - zend_hash_init(&php_output_handler_aliases, 0, NULL, NULL, 1); - zend_hash_init(&php_output_handler_conflicts, 0, NULL, NULL, 1); - zend_hash_init(&php_output_handler_reverse_conflicts, 0, NULL, (void (*)(void *)) zend_hash_destroy, 1); + zend_hash_init(&php_output_handler_aliases, 8, NULL, NULL, 1); + zend_hash_init(&php_output_handler_conflicts, 8, NULL, NULL, 1); + zend_hash_init(&php_output_handler_reverse_conflicts, 8, NULL, reverse_conflict_dtor, 1); php_output_direct = php_output_stdout; } /* }}} */ @@ -149,31 +156,31 @@ PHPAPI void php_output_shutdown(void) } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_activate(TSRMLS_D) +/* {{{ SUCCESS|FAILURE php_output_activate(void) * Reset output globals and setup the output handler stack */ -PHPAPI int php_output_activate(TSRMLS_D) +PHPAPI int php_output_activate(void) { #ifdef ZTS - memset((*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(output_globals_id)], 0, sizeof(zend_output_globals)); + memset((*((void ***) ZEND_TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(output_globals_id)], 0, sizeof(zend_output_globals)); #else memset(&output_globals, 0, sizeof(zend_output_globals)); #endif - zend_stack_init(&OG(handlers)); + zend_stack_init(&OG(handlers), sizeof(php_output_handler *)); OG(flags) |= PHP_OUTPUT_ACTIVATED; return SUCCESS; } /* }}} */ -/* {{{ void php_output_deactivate(TSRMLS_D) +/* {{{ void php_output_deactivate(void) * Destroy the output handler stack */ -PHPAPI void php_output_deactivate(TSRMLS_D) +PHPAPI void php_output_deactivate(void) { php_output_handler **handler = NULL; if ((OG(flags) & PHP_OUTPUT_ACTIVATED)) { - php_output_header(TSRMLS_C); + php_output_header(); OG(flags) ^= PHP_OUTPUT_ACTIVATED; OG(active) = NULL; @@ -181,18 +188,18 @@ PHPAPI void php_output_deactivate(TSRMLS_D) /* release all output handlers */ if (OG(handlers).elements) { - while (SUCCESS == zend_stack_top(&OG(handlers), (void *) &handler)) { - php_output_handler_free(handler TSRMLS_CC); + while ((handler = zend_stack_top(&OG(handlers)))) { + php_output_handler_free(handler); zend_stack_del_top(&OG(handlers)); } - zend_stack_destroy(&OG(handlers)); } + zend_stack_destroy(&OG(handlers)); } } /* }}} */ /* {{{ void php_output_register_constants() */ -PHPAPI void php_output_register_constants(TSRMLS_D) +PHPAPI void php_output_register_constants(void) { REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_START", PHP_OUTPUT_HANDLER_START, CONST_CS | CONST_PERSISTENT); REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_WRITE", PHP_OUTPUT_HANDLER_WRITE, CONST_CS | CONST_PERSISTENT); @@ -211,17 +218,17 @@ PHPAPI void php_output_register_constants(TSRMLS_D) } /* }}} */ -/* {{{ void php_output_set_status(int status TSRMLS_DC) +/* {{{ void php_output_set_status(int status) * Used by SAPIs to disable output */ -PHPAPI void php_output_set_status(int status TSRMLS_DC) +PHPAPI void php_output_set_status(int status) { OG(flags) = (OG(flags) & ~0xf) | (status & 0xf); } /* }}} */ -/* {{{ int php_output_get_status(TSRMLS_C) +/* {{{ int php_output_get_status() * Get output control status */ -PHPAPI int php_output_get_status(TSRMLS_D) +PHPAPI int php_output_get_status(void) { return ( OG(flags) @@ -231,62 +238,45 @@ PHPAPI int php_output_get_status(TSRMLS_D) } /* }}} */ -/* {{{ int php_output_write_unbuffered(const char *str, size_t len TSRMLS_DC) +/* {{{ int php_output_write_unbuffered(const char *str, size_t len) * Unbuffered write */ -PHPAPI int php_output_write_unbuffered(const char *str, size_t len TSRMLS_DC) +PHPAPI size_t php_output_write_unbuffered(const char *str, size_t len) { -#if PHP_DEBUG - if (len > UINT_MAX) { - php_error(E_WARNING, "Attempt to output more than UINT_MAX bytes at once; " - "output will be truncated %lu => %lu", - (unsigned long) len, (unsigned long) (len % UINT_MAX)); - } -#endif - if (OG(flags) & PHP_OUTPUT_DISABLED) { - return 0; - } if (OG(flags) & PHP_OUTPUT_ACTIVATED) { - return sapi_module.ub_write(str, len TSRMLS_CC); + return sapi_module.ub_write(str, len); } return php_output_direct(str, len); } /* }}} */ -/* {{{ int php_output_write(const char *str, size_t len TSRMLS_DC) +/* {{{ int php_output_write(const char *str, size_t len) * Buffered write */ -PHPAPI int php_output_write(const char *str, size_t len TSRMLS_DC) +PHPAPI size_t php_output_write(const char *str, size_t len) { -#if PHP_DEBUG - if (len > UINT_MAX) { - php_error(E_WARNING, "Attempt to output more than UINT_MAX bytes at once; " - "output will be truncated %lu => %lu", - (unsigned long) len, (unsigned long) (len % UINT_MAX)); + if (OG(flags) & PHP_OUTPUT_ACTIVATED) { + php_output_op(PHP_OUTPUT_HANDLER_WRITE, str, len); + return len; } -#endif if (OG(flags) & PHP_OUTPUT_DISABLED) { return 0; } - if (OG(flags) & PHP_OUTPUT_ACTIVATED) { - php_output_op(PHP_OUTPUT_HANDLER_WRITE, str, len TSRMLS_CC); - return (int) len; - } return php_output_direct(str, len); } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_flush(TSRMLS_D) +/* {{{ SUCCESS|FAILURE php_output_flush(void) * Flush the most recent output handlers buffer */ -PHPAPI int php_output_flush(TSRMLS_D) +PHPAPI int php_output_flush(void) { php_output_context context; if (OG(active) && (OG(active)->flags & PHP_OUTPUT_HANDLER_FLUSHABLE)) { - php_output_context_init(&context, PHP_OUTPUT_HANDLER_FLUSH TSRMLS_CC); + php_output_context_init(&context, PHP_OUTPUT_HANDLER_FLUSH); php_output_handler_op(OG(active), &context); if (context.out.data && context.out.used) { zend_stack_del_top(&OG(handlers)); - php_output_write(context.out.data, context.out.used TSRMLS_CC); - zend_stack_push(&OG(handlers), &OG(active), sizeof(php_output_handler *)); + php_output_write(context.out.data, context.out.used); + zend_stack_push(&OG(handlers), &OG(active)); } php_output_context_dtor(&context); return SUCCESS; @@ -295,24 +285,24 @@ PHPAPI int php_output_flush(TSRMLS_D) } /* }}} */ -/* {{{ void php_output_flush_all(TSRMLS_C) +/* {{{ void php_output_flush_all() * Flush all output buffers subsequently */ -PHPAPI void php_output_flush_all(TSRMLS_D) +PHPAPI void php_output_flush_all(void) { if (OG(active)) { - php_output_op(PHP_OUTPUT_HANDLER_FLUSH, NULL, 0 TSRMLS_CC); + php_output_op(PHP_OUTPUT_HANDLER_FLUSH, NULL, 0); } } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_clean(TSRMLS_D) +/* {{{ SUCCESS|FAILURE php_output_clean(void) * Cleans the most recent output handlers buffer if the handler is cleanable */ -PHPAPI int php_output_clean(TSRMLS_D) +PHPAPI int php_output_clean(void) { php_output_context context; if (OG(active) && (OG(active)->flags & PHP_OUTPUT_HANDLER_CLEANABLE)) { - php_output_context_init(&context, PHP_OUTPUT_HANDLER_CLEAN TSRMLS_CC); + php_output_context_init(&context, PHP_OUTPUT_HANDLER_CLEAN); php_output_handler_op(OG(active), &context); php_output_context_dtor(&context); return SUCCESS; @@ -321,72 +311,72 @@ PHPAPI int php_output_clean(TSRMLS_D) } /* }}} */ -/* {{{ void php_output_clean_all(TSRMLS_D) +/* {{{ void php_output_clean_all(void) * Cleans all output handler buffers, without regard whether the handler is cleanable */ -PHPAPI void php_output_clean_all(TSRMLS_D) +PHPAPI void php_output_clean_all(void) { php_output_context context; if (OG(active)) { - php_output_context_init(&context, PHP_OUTPUT_HANDLER_CLEAN TSRMLS_CC); + php_output_context_init(&context, PHP_OUTPUT_HANDLER_CLEAN); zend_stack_apply_with_argument(&OG(handlers), ZEND_STACK_APPLY_TOPDOWN, php_output_stack_apply_clean, &context); } } -/* {{{ SUCCESS|FAILURE php_output_end(TSRMLS_D) +/* {{{ SUCCESS|FAILURE php_output_end(void) * Finalizes the most recent output handler at pops it off the stack if the handler is removable */ -PHPAPI int php_output_end(TSRMLS_D) +PHPAPI int php_output_end(void) { - if (php_output_stack_pop(PHP_OUTPUT_POP_TRY TSRMLS_CC)) { + if (php_output_stack_pop(PHP_OUTPUT_POP_TRY)) { return SUCCESS; } return FAILURE; } /* }}} */ -/* {{{ void php_output_end_all(TSRMLS_D) +/* {{{ void php_output_end_all(void) * Finalizes all output handlers and ends output buffering without regard whether a handler is removable */ -PHPAPI void php_output_end_all(TSRMLS_D) +PHPAPI void php_output_end_all(void) { - while (OG(active) && php_output_stack_pop(PHP_OUTPUT_POP_FORCE TSRMLS_CC)); + while (OG(active) && php_output_stack_pop(PHP_OUTPUT_POP_FORCE)); } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_discard(TSRMLS_D) +/* {{{ SUCCESS|FAILURE php_output_discard(void) * Discards the most recent output handlers buffer and pops it off the stack if the handler is removable */ -PHPAPI int php_output_discard(TSRMLS_D) +PHPAPI int php_output_discard(void) { - if (php_output_stack_pop(PHP_OUTPUT_POP_DISCARD|PHP_OUTPUT_POP_TRY TSRMLS_CC)) { + if (php_output_stack_pop(PHP_OUTPUT_POP_DISCARD|PHP_OUTPUT_POP_TRY)) { return SUCCESS; } return FAILURE; } /* }}} */ -/* {{{ void php_output_discard_all(TSRMLS_D) +/* {{{ void php_output_discard_all(void) * Discard all output handlers and buffers without regard whether a handler is removable */ -PHPAPI void php_output_discard_all(TSRMLS_D) +PHPAPI void php_output_discard_all(void) { while (OG(active)) { - php_output_stack_pop(PHP_OUTPUT_POP_DISCARD|PHP_OUTPUT_POP_FORCE TSRMLS_CC); + php_output_stack_pop(PHP_OUTPUT_POP_DISCARD|PHP_OUTPUT_POP_FORCE); } } /* }}} */ -/* {{{ int php_output_get_level(TSRMLS_D) +/* {{{ int php_output_get_level(void) * Get output buffering level, ie. how many output handlers the stack contains */ -PHPAPI int php_output_get_level(TSRMLS_D) +PHPAPI int php_output_get_level(void) { return OG(active) ? zend_stack_count(&OG(handlers)) : 0; } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_get_contents(zval *z TSRMLS_DC) +/* {{{ SUCCESS|FAILURE php_output_get_contents(zval *z) * Get the contents of the active output handlers buffer */ -PHPAPI int php_output_get_contents(zval *p TSRMLS_DC) +PHPAPI int php_output_get_contents(zval *p) { if (OG(active)) { - ZVAL_STRINGL(p, OG(active)->buffer.data, OG(active)->buffer.used, 1); + ZVAL_STRINGL(p, OG(active)->buffer.data, OG(active)->buffer.used); return SUCCESS; } else { ZVAL_NULL(p); @@ -394,9 +384,9 @@ PHPAPI int php_output_get_contents(zval *p TSRMLS_DC) } } -/* {{{ SUCCESS|FAILURE php_output_get_length(zval *z TSRMLS_DC) +/* {{{ SUCCESS|FAILURE php_output_get_length(zval *z) * Get the length of the active output handlers buffer */ -PHPAPI int php_output_get_length(zval *p TSRMLS_DC) +PHPAPI int php_output_get_length(zval *p) { if (OG(active)) { ZVAL_LONG(p, OG(active)->buffer.used); @@ -408,113 +398,113 @@ PHPAPI int php_output_get_length(zval *p TSRMLS_DC) } /* }}} */ -/* {{{ php_output_handler* php_output_get_active_handler(TSRMLS_D) +/* {{{ php_output_handler* php_output_get_active_handler(void) * Get active output handler */ -PHPAPI php_output_handler* php_output_get_active_handler(TSRMLS_D) +PHPAPI php_output_handler* php_output_get_active_handler(void) { return OG(active); } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_handler_start_default(TSRMLS_D) +/* {{{ SUCCESS|FAILURE php_output_handler_start_default(void) * Start a "default output handler" */ -PHPAPI int php_output_start_default(TSRMLS_D) +PHPAPI int php_output_start_default(void) { php_output_handler *handler; - handler = php_output_handler_create_internal(ZEND_STRL(php_output_default_handler_name), php_output_handler_default_func, 0, PHP_OUTPUT_HANDLER_STDFLAGS TSRMLS_CC); - if (SUCCESS == php_output_handler_start(handler TSRMLS_CC)) { + handler = php_output_handler_create_internal(ZEND_STRL(php_output_default_handler_name), php_output_handler_default_func, 0, PHP_OUTPUT_HANDLER_STDFLAGS); + if (SUCCESS == php_output_handler_start(handler)) { return SUCCESS; } - php_output_handler_free(&handler TSRMLS_CC); + php_output_handler_free(&handler); return FAILURE; } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_handler_start_devnull(TSRMLS_D) +/* {{{ SUCCESS|FAILURE php_output_handler_start_devnull(void) * Start a "null output handler" */ -PHPAPI int php_output_start_devnull(TSRMLS_D) +PHPAPI int php_output_start_devnull(void) { php_output_handler *handler; - handler = php_output_handler_create_internal(ZEND_STRL(php_output_devnull_handler_name), php_output_handler_devnull_func, PHP_OUTPUT_HANDLER_DEFAULT_SIZE, 0 TSRMLS_CC); - if (SUCCESS == php_output_handler_start(handler TSRMLS_CC)) { + handler = php_output_handler_create_internal(ZEND_STRL(php_output_devnull_handler_name), php_output_handler_devnull_func, PHP_OUTPUT_HANDLER_DEFAULT_SIZE, 0); + if (SUCCESS == php_output_handler_start(handler)) { return SUCCESS; } - php_output_handler_free(&handler TSRMLS_CC); + php_output_handler_free(&handler); return FAILURE; } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_start_user(zval *handler, size_t chunk_size, int flags TSRMLS_DC) +/* {{{ SUCCESS|FAILURE php_output_start_user(zval *handler, size_t chunk_size, int flags) * Start a user level output handler */ -PHPAPI int php_output_start_user(zval *output_handler, size_t chunk_size, int flags TSRMLS_DC) +PHPAPI int php_output_start_user(zval *output_handler, size_t chunk_size, int flags) { php_output_handler *handler; if (output_handler) { - handler = php_output_handler_create_user(output_handler, chunk_size, flags TSRMLS_CC); + handler = php_output_handler_create_user(output_handler, chunk_size, flags); } else { - handler = php_output_handler_create_internal(ZEND_STRL(php_output_default_handler_name), php_output_handler_default_func, chunk_size, flags TSRMLS_CC); + handler = php_output_handler_create_internal(ZEND_STRL(php_output_default_handler_name), php_output_handler_default_func, chunk_size, flags); } - if (SUCCESS == php_output_handler_start(handler TSRMLS_CC)) { + if (SUCCESS == php_output_handler_start(handler)) { return SUCCESS; } - php_output_handler_free(&handler TSRMLS_CC); + php_output_handler_free(&handler); return FAILURE; } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_start_internal(zval *name, php_output_handler_func_t handler, size_t chunk_size, int flags TSRMLS_DC) +/* {{{ SUCCESS|FAILURE php_output_start_internal(zval *name, php_output_handler_func_t handler, size_t chunk_size, int flags) * Start an internal output handler that does not have to maintain a non-global state */ -PHPAPI int php_output_start_internal(const char *name, size_t name_len, php_output_handler_func_t output_handler, size_t chunk_size, int flags TSRMLS_DC) +PHPAPI int php_output_start_internal(const char *name, size_t name_len, php_output_handler_func_t output_handler, size_t chunk_size, int flags) { php_output_handler *handler; - handler = php_output_handler_create_internal(name, name_len, php_output_handler_compat_func, chunk_size, flags TSRMLS_CC); - php_output_handler_set_context(handler, output_handler, NULL TSRMLS_CC); - if (SUCCESS == php_output_handler_start(handler TSRMLS_CC)) { + handler = php_output_handler_create_internal(name, name_len, php_output_handler_compat_func, chunk_size, flags); + php_output_handler_set_context(handler, output_handler, NULL); + if (SUCCESS == php_output_handler_start(handler)) { return SUCCESS; } - php_output_handler_free(&handler TSRMLS_CC); + php_output_handler_free(&handler); return FAILURE; } /* }}} */ -/* {{{ php_output_handler *php_output_handler_create_user(zval *handler, size_t chunk_size, int flags TSRMLS_DC) +/* {{{ php_output_handler *php_output_handler_create_user(zval *handler, size_t chunk_size, int flags) * Create a user level output handler */ -PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler, size_t chunk_size, int flags TSRMLS_DC) +PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler, size_t chunk_size, int flags) { - char *handler_name = NULL, *error = NULL; + zend_string *handler_name = NULL; + char *error = NULL; php_output_handler *handler = NULL; - php_output_handler_alias_ctor_t *alias = NULL; + php_output_handler_alias_ctor_t alias = NULL; php_output_handler_user_func_t *user = NULL; switch (Z_TYPE_P(output_handler)) { case IS_NULL: - handler = php_output_handler_create_internal(ZEND_STRL(php_output_default_handler_name), php_output_handler_default_func, chunk_size, flags TSRMLS_CC); + handler = php_output_handler_create_internal(ZEND_STRL(php_output_default_handler_name), php_output_handler_default_func, chunk_size, flags); break; case IS_STRING: - if (Z_STRLEN_P(output_handler) && (alias = php_output_handler_alias(Z_STRVAL_P(output_handler), Z_STRLEN_P(output_handler) TSRMLS_CC))) { - handler = (*alias)(Z_STRVAL_P(output_handler), Z_STRLEN_P(output_handler), chunk_size, flags TSRMLS_CC); + if (Z_STRLEN_P(output_handler) && (alias = php_output_handler_alias(Z_STRVAL_P(output_handler), Z_STRLEN_P(output_handler)))) { + handler = alias(Z_STRVAL_P(output_handler), Z_STRLEN_P(output_handler), chunk_size, flags); break; } default: user = ecalloc(1, sizeof(php_output_handler_user_func_t)); - if (SUCCESS == zend_fcall_info_init(output_handler, 0, &user->fci, &user->fcc, &handler_name, &error TSRMLS_CC)) { - handler = php_output_handler_init(handler_name, strlen(handler_name), chunk_size, (flags & ~0xf) | PHP_OUTPUT_HANDLER_USER TSRMLS_CC); - Z_ADDREF_P(output_handler); - user->zoh = output_handler; + if (SUCCESS == zend_fcall_info_init(output_handler, 0, &user->fci, &user->fcc, &handler_name, &error)) { + handler = php_output_handler_init(handler_name, chunk_size, (flags & ~0xf) | PHP_OUTPUT_HANDLER_USER); + ZVAL_COPY(&user->zoh, output_handler); handler->func.user = user; } else { efree(user); } if (error) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "%s", error); + php_error_docref("ref.outcontrol", E_WARNING, "%s", error); efree(error); } if (handler_name) { - efree(handler_name); + zend_string_release(handler_name); } } @@ -522,78 +512,74 @@ PHPAPI php_output_handler *php_output_handler_create_user(zval *output_handler, } /* }}} */ -/* {{{ php_output_handler *php_output_handler_create_internal(zval *name, php_output_handler_context_func_t handler, size_t chunk_size, int flags TSRMLS_DC) +/* {{{ php_output_handler *php_output_handler_create_internal(zval *name, php_output_handler_context_func_t handler, size_t chunk_size, int flags) * Create an internal output handler that can maintain a non-global state */ -PHPAPI php_output_handler *php_output_handler_create_internal(const char *name, size_t name_len, php_output_handler_context_func_t output_handler, size_t chunk_size, int flags TSRMLS_DC) +PHPAPI php_output_handler *php_output_handler_create_internal(const char *name, size_t name_len, php_output_handler_context_func_t output_handler, size_t chunk_size, int flags) { php_output_handler *handler; + zend_string *str = zend_string_init(name, name_len, 1); - handler = php_output_handler_init(name, name_len, chunk_size, (flags & ~0xf) | PHP_OUTPUT_HANDLER_INTERNAL TSRMLS_CC); + handler = php_output_handler_init(str, chunk_size, (flags & ~0xf) | PHP_OUTPUT_HANDLER_INTERNAL); handler->func.internal = output_handler; + zend_string_release(str); return handler; } /* }}} */ -/* {{{ void php_output_handler_set_context(php_output_handler *handler, void *opaq, void (*dtor)(void* TSRMLS_DC) TSRMLS_DC) +/* {{{ void php_output_handler_set_context(php_output_handler *handler, void *opaq, void (*dtor)(void*)) * Set the context/state of an output handler. Calls the dtor of the previous context if there is one */ -PHPAPI void php_output_handler_set_context(php_output_handler *handler, void *opaq, void (*dtor)(void* TSRMLS_DC) TSRMLS_DC) +PHPAPI void php_output_handler_set_context(php_output_handler *handler, void *opaq, void (*dtor)(void*)) { if (handler->dtor && handler->opaq) { - handler->dtor(handler->opaq TSRMLS_CC); + handler->dtor(handler->opaq); } handler->dtor = dtor; handler->opaq = opaq; } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_handler_start(php_output_handler *handler TSRMLS_DC) +/* {{{ SUCCESS|FAILURE php_output_handler_start(php_output_handler *handler) * Starts the set up output handler and pushes it on top of the stack. Checks for any conflicts regarding the output handler to start */ -PHPAPI int php_output_handler_start(php_output_handler *handler TSRMLS_DC) +PHPAPI int php_output_handler_start(php_output_handler *handler) { - HashPosition pos; HashTable *rconflicts; - php_output_handler_conflict_check_t *conflict; + php_output_handler_conflict_check_t conflict; - if (php_output_lock_error(PHP_OUTPUT_HANDLER_START TSRMLS_CC) || !handler) { + if (php_output_lock_error(PHP_OUTPUT_HANDLER_START) || !handler) { return FAILURE; } - if (SUCCESS == zend_hash_find(&php_output_handler_conflicts, handler->name, handler->name_len+1, (void *) &conflict)) { - if (SUCCESS != (*conflict)(handler->name, handler->name_len TSRMLS_CC)) { + if (NULL != (conflict = zend_hash_find_ptr(&php_output_handler_conflicts, handler->name))) { + if (SUCCESS != conflict(ZSTR_VAL(handler->name), ZSTR_LEN(handler->name))) { return FAILURE; } } - if (SUCCESS == zend_hash_find(&php_output_handler_reverse_conflicts, handler->name, handler->name_len+1, (void *) &rconflicts)) { - for (zend_hash_internal_pointer_reset_ex(rconflicts, &pos); - zend_hash_get_current_data_ex(rconflicts, (void *) &conflict, &pos) == SUCCESS; - zend_hash_move_forward_ex(rconflicts, &pos) - ) { - if (SUCCESS != (*conflict)(handler->name, handler->name_len TSRMLS_CC)) { + if (NULL != (rconflicts = zend_hash_find_ptr(&php_output_handler_reverse_conflicts, handler->name))) { + ZEND_HASH_FOREACH_PTR(rconflicts, conflict) { + if (SUCCESS != conflict(ZSTR_VAL(handler->name), ZSTR_LEN(handler->name))) { return FAILURE; } - } - } - /* zend_stack_push never returns SUCCESS but FAILURE or stack level */ - if (FAILURE == (handler->level = zend_stack_push(&OG(handlers), &handler, sizeof(php_output_handler *)))) { - return FAILURE; + } ZEND_HASH_FOREACH_END(); } + /* zend_stack_push returns stack level */ + handler->level = zend_stack_push(&OG(handlers), &handler); OG(active) = handler; return SUCCESS; } /* }}} */ -/* {{{ int php_output_handler_started(zval *name TSRMLS_DC) +/* {{{ int php_output_handler_started(zval *name) * Check whether a certain output handler is in use */ -PHPAPI int php_output_handler_started(const char *name, size_t name_len TSRMLS_DC) +PHPAPI int php_output_handler_started(const char *name, size_t name_len) { - php_output_handler ***handlers; - int i, count = php_output_get_level(TSRMLS_C); + php_output_handler **handlers; + int i, count = php_output_get_level(); if (count) { - handlers = (php_output_handler ***) zend_stack_base(&OG(handlers)); + handlers = (php_output_handler **) zend_stack_base(&OG(handlers)); for (i = 0; i < count; ++i) { - if (name_len == (*(handlers[i]))->name_len && !memcmp((*(handlers[i]))->name, name, name_len)) { + if (name_len == ZSTR_LEN(handlers[i]->name) && !memcmp(ZSTR_VAL(handlers[i]->name), name, name_len)) { return 1; } } @@ -603,15 +589,15 @@ PHPAPI int php_output_handler_started(const char *name, size_t name_len TSRMLS_D } /* }}} */ -/* {{{ int php_output_handler_conflict(zval *handler_new, zval *handler_old TSRMLS_DC) +/* {{{ int php_output_handler_conflict(zval *handler_new, zval *handler_old) * Check whether a certain handler is in use and issue a warning that the new handler would conflict with the already used one */ -PHPAPI int php_output_handler_conflict(const char *handler_new, size_t handler_new_len, const char *handler_set, size_t handler_set_len TSRMLS_DC) +PHPAPI int php_output_handler_conflict(const char *handler_new, size_t handler_new_len, const char *handler_set, size_t handler_set_len) { - if (php_output_handler_started(handler_set, handler_set_len TSRMLS_CC)) { + if (php_output_handler_started(handler_set, handler_set_len)) { if (handler_new_len != handler_set_len || memcmp(handler_new, handler_set, handler_set_len)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler '%s' conflicts with '%s'", handler_new, handler_set); + php_error_docref("ref.outcontrol", E_WARNING, "output handler '%s' conflicts with '%s'", handler_new, handler_set); } else { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler '%s' cannot be used twice", handler_new); + php_error_docref("ref.outcontrol", E_WARNING, "output handler '%s' cannot be used twice", handler_new); } return 1; } @@ -619,21 +605,21 @@ PHPAPI int php_output_handler_conflict(const char *handler_new, size_t handler_n } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_handler_conflict_register(zval *name, php_output_handler_conflict_check_t check_func TSRMLS_DC) +/* {{{ SUCCESS|FAILURE php_output_handler_conflict_register(zval *name, php_output_handler_conflict_check_t check_func) * Register a conflict checking function on MINIT */ -PHPAPI int php_output_handler_conflict_register(const char *name, size_t name_len, php_output_handler_conflict_check_t check_func TSRMLS_DC) +PHPAPI int php_output_handler_conflict_register(const char *name, size_t name_len, php_output_handler_conflict_check_t check_func) { if (!EG(current_module)) { zend_error(E_ERROR, "Cannot register an output handler conflict outside of MINIT"); return FAILURE; } - return zend_hash_update(&php_output_handler_conflicts, name, name_len+1, &check_func, sizeof(php_output_handler_conflict_check_t *), NULL); + return zend_hash_str_update_ptr(&php_output_handler_conflicts, name, name_len, check_func) ? SUCCESS : FAILURE; } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_handler_reverse_conflict_register(zval *name, php_output_handler_conflict_check_t check_func TSRMLS_DC) +/* {{{ SUCCESS|FAILURE php_output_handler_reverse_conflict_register(zval *name, php_output_handler_conflict_check_t check_func) * Register a reverse conflict checking function on MINIT */ -PHPAPI int php_output_handler_reverse_conflict_register(const char *name, size_t name_len, php_output_handler_conflict_check_t check_func TSRMLS_DC) +PHPAPI int php_output_handler_reverse_conflict_register(const char *name, size_t name_len, php_output_handler_conflict_check_t check_func) { HashTable rev, *rev_ptr = NULL; @@ -642,15 +628,15 @@ PHPAPI int php_output_handler_reverse_conflict_register(const char *name, size_t return FAILURE; } - if (SUCCESS == zend_hash_find(&php_output_handler_reverse_conflicts, name, name_len+1, (void *) &rev_ptr)) { - return zend_hash_next_index_insert(rev_ptr, &check_func, sizeof(php_output_handler_conflict_check_t *), NULL); + if (NULL != (rev_ptr = zend_hash_str_find_ptr(&php_output_handler_reverse_conflicts, name, name_len))) { + return zend_hash_next_index_insert_ptr(rev_ptr, check_func) ? SUCCESS : FAILURE; } else { - zend_hash_init(&rev, 1, NULL, NULL, 1); - if (SUCCESS != zend_hash_next_index_insert(&rev, &check_func, sizeof(php_output_handler_conflict_check_t *), NULL)) { + zend_hash_init(&rev, 8, NULL, NULL, 1); + if (NULL == zend_hash_next_index_insert_ptr(&rev, check_func)) { zend_hash_destroy(&rev); return FAILURE; } - if (SUCCESS != zend_hash_update(&php_output_handler_reverse_conflicts, name, name_len+1, &rev, sizeof(HashTable), NULL)) { + if (NULL == zend_hash_str_update_mem(&php_output_handler_reverse_conflicts, name, name_len+1, &rev, sizeof(HashTable))) { zend_hash_destroy(&rev); return FAILURE; } @@ -659,32 +645,29 @@ PHPAPI int php_output_handler_reverse_conflict_register(const char *name, size_t } /* }}} */ -/* {{{ php_output_handler_alias_ctor_t php_output_handler_alias(zval *name TSRMLS_DC) +/* {{{ php_output_handler_alias_ctor_t php_output_handler_alias(zval *name) * Get an internal output handler for a user handler if it exists */ -PHPAPI php_output_handler_alias_ctor_t *php_output_handler_alias(const char *name, size_t name_len TSRMLS_DC) +PHPAPI php_output_handler_alias_ctor_t php_output_handler_alias(const char *name, size_t name_len) { - php_output_handler_alias_ctor_t *func = NULL; - - zend_hash_find(&php_output_handler_aliases, name, name_len+1, (void *) &func); - return func; + return zend_hash_str_find_ptr(&php_output_handler_aliases, name, name_len); } /* }}} */ -/* {{{ SUCCESS|FAILURE php_output_handler_alias_register(zval *name, php_output_handler_alias_ctor_t func TSRMLS_DC) +/* {{{ SUCCESS|FAILURE php_output_handler_alias_register(zval *name, php_output_handler_alias_ctor_t func) * Registers an internal output handler as alias for a user handler */ -PHPAPI int php_output_handler_alias_register(const char *name, size_t name_len, php_output_handler_alias_ctor_t func TSRMLS_DC) +PHPAPI int php_output_handler_alias_register(const char *name, size_t name_len, php_output_handler_alias_ctor_t func) { if (!EG(current_module)) { zend_error(E_ERROR, "Cannot register an output handler alias outside of MINIT"); return FAILURE; } - return zend_hash_update(&php_output_handler_aliases, name, name_len+1, &func, sizeof(php_output_handler_alias_ctor_t *), NULL); + return zend_hash_str_update_ptr(&php_output_handler_aliases, name, name_len, func) ? SUCCESS : FAILURE; } /* }}} */ /* {{{ SUCCESS|FAILURE php_output_handler_hook(php_output_handler_hook_t type, void *arg TSMRLS_DC) * Output handler hook for output handler functions to check/modify the current handlers abilities */ -PHPAPI int php_output_handler_hook(php_output_handler_hook_t type, void *arg TSRMLS_DC) +PHPAPI int php_output_handler_hook(php_output_handler_hook_t type, void *arg) { if (OG(running)) { switch (type) { @@ -711,18 +694,22 @@ PHPAPI int php_output_handler_hook(php_output_handler_hook_t type, void *arg TSR } /* }}} */ -/* {{{ void php_output_handler_dtor(php_output_handler *handler TSRMLS_DC) +/* {{{ void php_output_handler_dtor(php_output_handler *handler) * Destroy an output handler */ -PHPAPI void php_output_handler_dtor(php_output_handler *handler TSRMLS_DC) +PHPAPI void php_output_handler_dtor(php_output_handler *handler) { - STR_FREE(handler->name); - STR_FREE(handler->buffer.data); + if (handler->name) { + zend_string_release(handler->name); + } + if (handler->buffer.data) { + efree(handler->buffer.data); + } if (handler->flags & PHP_OUTPUT_HANDLER_USER) { zval_ptr_dtor(&handler->func.user->zoh); efree(handler->func.user); } if (handler->dtor && handler->opaq) { - handler->dtor(handler->opaq TSRMLS_CC); + handler->dtor(handler->opaq); } memset(handler, 0, sizeof(*handler)); } @@ -730,19 +717,19 @@ PHPAPI void php_output_handler_dtor(php_output_handler *handler TSRMLS_DC) /* {{{ void php_output_handler_free(php_output_handler **handler TSMRLS_DC) * Destroy and free an output handler */ -PHPAPI void php_output_handler_free(php_output_handler **h TSRMLS_DC) +PHPAPI void php_output_handler_free(php_output_handler **h) { if (*h) { - php_output_handler_dtor(*h TSRMLS_CC); + php_output_handler_dtor(*h); efree(*h); *h = NULL; } } /* }}} */ -/* void php_output_set_implicit_flush(int enabled TSRMLS_DC) +/* void php_output_set_implicit_flush(int enabled) * Enable or disable implicit flush */ -PHPAPI void php_output_set_implicit_flush(int flush TSRMLS_DC) +PHPAPI void php_output_set_implicit_flush(int flush) { if (flush) { OG(flags) |= PHP_OUTPUT_IMPLICITFLUSH; @@ -752,47 +739,46 @@ PHPAPI void php_output_set_implicit_flush(int flush TSRMLS_DC) } /* }}} */ -/* {{{ char *php_output_get_start_filename(TSRMLS_D) +/* {{{ char *php_output_get_start_filename(void) * Get the file name where output has started */ -PHPAPI const char *php_output_get_start_filename(TSRMLS_D) +PHPAPI const char *php_output_get_start_filename(void) { return OG(output_start_filename); } /* }}} */ -/* {{{ int php_output_get_start_lineno(TSRMLS_D) +/* {{{ int php_output_get_start_lineno(void) * Get the line number where output has started */ -PHPAPI int php_output_get_start_lineno(TSRMLS_D) +PHPAPI int php_output_get_start_lineno(void) { return OG(output_start_lineno); } /* }}} */ -/* {{{ static int php_output_lock_error(int op TSRMLS_DC) +/* {{{ static int php_output_lock_error(int op) * Checks whether an unallowed operation is attempted from within the output handler and issues a fatal error */ -static inline int php_output_lock_error(int op TSRMLS_DC) +static inline int php_output_lock_error(int op) { /* if there's no ob active, ob has been stopped */ if (op && OG(active) && OG(running)) { /* fatal error */ - php_output_deactivate(TSRMLS_C); - php_error_docref("ref.outcontrol" TSRMLS_CC, E_ERROR, "Cannot use output buffering in output buffering display handlers"); + php_output_deactivate(); + php_error_docref("ref.outcontrol", E_RECOVERABLE_ERROR, "Cannot use output buffering in output buffering display handlers"); return 1; } return 0; } /* }}} */ -/* {{{ static php_output_context *php_output_context_init(php_output_context *context, int op TSRMLS_DC) +/* {{{ static php_output_context *php_output_context_init(php_output_context *context, int op) * Initialize a new output context */ -static inline php_output_context *php_output_context_init(php_output_context *context, int op TSRMLS_DC) +static inline php_output_context *php_output_context_init(php_output_context *context, int op) { if (!context) { context = emalloc(sizeof(php_output_context)); } memset(context, 0, sizeof(php_output_context)); - TSRMLS_SET_CTX(context->tsrm_ls); context->op = op; return context; @@ -872,15 +858,14 @@ static inline void php_output_context_dtor(php_output_context *context) } /* }}} */ -/* {{{ static php_output_handler *php_output_handler_init(zval *name, size_t chunk_size, int flags TSRMLS_DC) +/* {{{ static php_output_handler *php_output_handler_init(zval *name, size_t chunk_size, int flags) * Allocates and initializes a php_output_handler structure */ -static inline php_output_handler *php_output_handler_init(const char *name, size_t name_len, size_t chunk_size, int flags TSRMLS_DC) +static inline php_output_handler *php_output_handler_init(zend_string *name, size_t chunk_size, int flags) { php_output_handler *handler; handler = ecalloc(1, sizeof(php_output_handler)); - handler->name = estrndup(name, name_len); - handler->name_len = name_len; + handler->name = zend_string_copy(name); handler->size = chunk_size; handler->flags = flags; handler->buffer.size = PHP_OUTPUT_HANDLER_INITBUF_SIZE(chunk_size); @@ -890,9 +875,9 @@ static inline php_output_handler *php_output_handler_init(const char *name, size } /* }}} */ -/* {{{ static int php_output_handler_appen(php_output_handler *handler, const php_output_buffer *buf TSRMLS_DC) +/* {{{ static int php_output_handler_appen(php_output_handler *handler, const php_output_buffer *buf) * Appends input to the output handlers buffer and indicates whether the buffer does not have to be processed by the output handler */ -static inline int php_output_handler_append(php_output_handler *handler, const php_output_buffer *buf TSRMLS_DC) +static inline int php_output_handler_append(php_output_handler *handler, const php_output_buffer *buf) { if (buf->used) { OG(flags) |= PHP_OUTPUT_WRITTEN; @@ -924,7 +909,6 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl { php_output_handler_status_t status; int original_op = context->op; - PHP_OUTPUT_TSRMLS(context); #if PHP_OUTPUT_DEBUG fprintf(stderr, ">>> op(%d, " @@ -948,13 +932,13 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl ); #endif - if (php_output_lock_error(context->op TSRMLS_CC)) { + if (php_output_lock_error(context->op)) { /* fatal error */ return PHP_OUTPUT_HANDLER_FAILURE; } /* storable? */ - if (php_output_handler_append(handler, &context->in TSRMLS_CC) && !context->op) { + if (php_output_handler_append(handler, &context->in) && !context->op) { context->op = original_op; return PHP_OUTPUT_HANDLER_NO_DATA; } else { @@ -965,23 +949,22 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl OG(running) = handler; if (handler->flags & PHP_OUTPUT_HANDLER_USER) { - zval *retval = NULL, *ob_data, *ob_mode; + zval retval, ob_data, ob_mode; - MAKE_STD_ZVAL(ob_data); - ZVAL_STRINGL(ob_data, handler->buffer.data, handler->buffer.used, 1); - MAKE_STD_ZVAL(ob_mode); - ZVAL_LONG(ob_mode, (long) context->op); - zend_fcall_info_argn(&handler->func.user->fci TSRMLS_CC, 2, &ob_data, &ob_mode); + ZVAL_STRINGL(&ob_data, handler->buffer.data, handler->buffer.used); + ZVAL_LONG(&ob_mode, (zend_long) context->op); + zend_fcall_info_argn(&handler->func.user->fci, 2, &ob_data, &ob_mode); + zval_ptr_dtor(&ob_data); -#define PHP_OUTPUT_USER_SUCCESS(retval) (retval && !(Z_TYPE_P(retval) == IS_BOOL && Z_BVAL_P(retval)==0)) - if (SUCCESS == zend_fcall_info_call(&handler->func.user->fci, &handler->func.user->fcc, &retval, NULL TSRMLS_CC) && PHP_OUTPUT_USER_SUCCESS(retval)) { +#define PHP_OUTPUT_USER_SUCCESS(retval) ((Z_TYPE(retval) != IS_UNDEF) && !(Z_TYPE(retval) == IS_FALSE)) + if (SUCCESS == zend_fcall_info_call(&handler->func.user->fci, &handler->func.user->fcc, &retval, NULL) && PHP_OUTPUT_USER_SUCCESS(retval)) { /* user handler may have returned TRUE */ status = PHP_OUTPUT_HANDLER_NO_DATA; - if (Z_TYPE_P(retval) != IS_BOOL) { + if (Z_TYPE(retval) != IS_FALSE && Z_TYPE(retval) != IS_TRUE) { convert_to_string_ex(&retval); - if (Z_STRLEN_P(retval)) { - context->out.data = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); - context->out.used = Z_STRLEN_P(retval); + if (Z_STRLEN(retval)) { + context->out.data = estrndup(Z_STRVAL(retval), Z_STRLEN(retval)); + context->out.used = Z_STRLEN(retval); context->out.free = 1; status = PHP_OUTPUT_HANDLER_SUCCESS; } @@ -991,12 +974,8 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl status = PHP_OUTPUT_HANDLER_FAILURE; } - zend_fcall_info_argn(&handler->func.user->fci TSRMLS_CC, 0); - zval_ptr_dtor(&ob_data); - zval_ptr_dtor(&ob_mode); - if (retval) { - zval_ptr_dtor(&retval); - } + zend_fcall_info_argn(&handler->func.user->fci, 0); + zval_ptr_dtor(&retval); } else { @@ -1049,19 +1028,19 @@ static inline php_output_handler_status_t php_output_handler_op(php_output_handl /* }}} */ -/* {{{ static void php_output_op(int op, const char *str, size_t len TSRMLS_DC) +/* {{{ static void php_output_op(int op, const char *str, size_t len) * Output op dispatcher, passes input and output handlers output through the output handler stack until it gets written to the SAPI */ -static inline void php_output_op(int op, const char *str, size_t len TSRMLS_DC) +static inline void php_output_op(int op, const char *str, size_t len) { php_output_context context; php_output_handler **active; int obh_cnt; - if (php_output_lock_error(op TSRMLS_CC)) { + if (php_output_lock_error(op)) { return; } - php_output_context_init(&context, op TSRMLS_CC); + php_output_context_init(&context, op); /* * broken up for better performance: @@ -1074,7 +1053,7 @@ static inline void php_output_op(int op, const char *str, size_t len TSRMLS_DC) if (obh_cnt > 1) { zend_stack_apply_with_argument(&OG(handlers), ZEND_STACK_APPLY_TOPDOWN, php_output_stack_apply_op, &context); - } else if ((SUCCESS == zend_stack_top(&OG(handlers), (void *) &active)) && (!((*active)->flags & PHP_OUTPUT_HANDLER_DISABLED))) { + } else if ((active = zend_stack_top(&OG(handlers))) && (!((*active)->flags & PHP_OUTPUT_HANDLER_DISABLED))) { php_output_handler_op(*active, &context); } else { php_output_context_pass(&context); @@ -1085,16 +1064,16 @@ static inline void php_output_op(int op, const char *str, size_t len TSRMLS_DC) } if (context.out.data && context.out.used) { - php_output_header(TSRMLS_C); + php_output_header(); if (!(OG(flags) & PHP_OUTPUT_DISABLED)) { #if PHP_OUTPUT_DEBUG fprintf(stderr, "::: sapi_write('%s', %zu)\n", context.out.data, context.out.used); #endif - sapi_module.ub_write(context.out.data, context.out.used TSRMLS_CC); + sapi_module.ub_write(context.out.data, context.out.used); if (OG(flags) & PHP_OUTPUT_IMPLICITFLUSH) { - sapi_flush(TSRMLS_C); + sapi_flush(); } OG(flags) |= PHP_OUTPUT_SENT; @@ -1173,7 +1152,7 @@ static int php_output_stack_apply_list(void *h, void *z) php_output_handler *handler = *(php_output_handler **) h; zval *array = (zval *) z; - add_next_index_stringl(array, handler->name, handler->name_len, 1); + add_next_index_str(array, zend_string_copy(handler->name)); return 0; } /* }}} */ @@ -1183,9 +1162,9 @@ static int php_output_stack_apply_list(void *h, void *z) static int php_output_stack_apply_status(void *h, void *z) { php_output_handler *handler = *(php_output_handler **) h; - zval *array = (zval *) z; + zval arr, *array = (zval *) z; - add_next_index_zval(array, php_output_handler_status(handler, NULL)); + add_next_index_zval(array, php_output_handler_status(handler, &arr)); return 0; } @@ -1194,42 +1173,40 @@ static int php_output_stack_apply_status(void *h, void *z) * Returns an array with the status of the output handler */ static inline zval *php_output_handler_status(php_output_handler *handler, zval *entry) { - if (!entry) { - MAKE_STD_ZVAL(entry); - array_init(entry); - } + ZEND_ASSERT(entry != NULL); - add_assoc_stringl(entry, "name", handler->name, handler->name_len, 1); - add_assoc_long(entry, "type", (long) (handler->flags & 0xf)); - add_assoc_long(entry, "flags", (long) handler->flags); - add_assoc_long(entry, "level", (long) handler->level); - add_assoc_long(entry, "chunk_size", (long) handler->size); - add_assoc_long(entry, "buffer_size", (long) handler->buffer.size); - add_assoc_long(entry, "buffer_used", (long) handler->buffer.used); + array_init(entry); + add_assoc_str(entry, "name", zend_string_copy(handler->name)); + add_assoc_long(entry, "type", (zend_long) (handler->flags & 0xf)); + add_assoc_long(entry, "flags", (zend_long) handler->flags); + add_assoc_long(entry, "level", (zend_long) handler->level); + add_assoc_long(entry, "chunk_size", (zend_long) handler->size); + add_assoc_long(entry, "buffer_size", (zend_long) handler->buffer.size); + add_assoc_long(entry, "buffer_used", (zend_long) handler->buffer.used); return entry; } /* }}} */ -/* {{{ static int php_output_stack_pop(int flags TSRMLS_DC) +/* {{{ static int php_output_stack_pop(int flags) * Pops an output handler off the stack */ -static inline int php_output_stack_pop(int flags TSRMLS_DC) +static inline int php_output_stack_pop(int flags) { php_output_context context; php_output_handler **current, *orphan = OG(active); if (!orphan) { if (!(flags & PHP_OUTPUT_POP_SILENT)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to %s buffer. No buffer to %s", (flags&PHP_OUTPUT_POP_DISCARD)?"discard":"send", (flags&PHP_OUTPUT_POP_DISCARD)?"discard":"send"); + php_error_docref("ref.outcontrol", E_NOTICE, "failed to %s buffer. No buffer to %s", (flags&PHP_OUTPUT_POP_DISCARD)?"discard":"send", (flags&PHP_OUTPUT_POP_DISCARD)?"discard":"send"); } return 0; } else if (!(flags & PHP_OUTPUT_POP_FORCE) && !(orphan->flags & PHP_OUTPUT_HANDLER_REMOVABLE)) { if (!(flags & PHP_OUTPUT_POP_SILENT)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to %s buffer of %s (%d)", (flags&PHP_OUTPUT_POP_DISCARD)?"discard":"send", orphan->name, orphan->level); + php_error_docref("ref.outcontrol", E_NOTICE, "failed to %s buffer of %s (%d)", (flags&PHP_OUTPUT_POP_DISCARD)?"discard":"send", ZSTR_VAL(orphan->name), orphan->level); } return 0; } else { - php_output_context_init(&context, PHP_OUTPUT_HANDLER_FINAL TSRMLS_CC); + php_output_context_init(&context, PHP_OUTPUT_HANDLER_FINAL); /* don't run the output handler if it's disabled */ if (!(orphan->flags & PHP_OUTPUT_HANDLER_DISABLED)) { @@ -1246,7 +1223,7 @@ static inline int php_output_stack_pop(int flags TSRMLS_DC) /* pop it off the stack */ zend_stack_del_top(&OG(handlers)); - if (SUCCESS == zend_stack_top(&OG(handlers), (void *) ¤t)) { + if ((current = zend_stack_top(&OG(handlers)))) { OG(active) = *current; } else { OG(active) = NULL; @@ -1254,11 +1231,11 @@ static inline int php_output_stack_pop(int flags TSRMLS_DC) /* pass output along */ if (context.out.data && context.out.used && !(flags & PHP_OUTPUT_POP_DISCARD)) { - php_output_write(context.out.data, context.out.used TSRMLS_CC); + php_output_write(context.out.data, context.out.used); } /* destroy the handler (after write!) */ - php_output_handler_free(&orphan TSRMLS_CC); + php_output_handler_free(&orphan); php_output_context_dtor(&context); return 1; @@ -1271,13 +1248,12 @@ static inline int php_output_stack_pop(int flags TSRMLS_DC) static int php_output_handler_compat_func(void **handler_context, php_output_context *output_context) { php_output_handler_func_t func = *(php_output_handler_func_t *) handler_context; - PHP_OUTPUT_TSRMLS(output_context); if (func) { char *out_str = NULL; - uint out_len = 0; + size_t out_len = 0; - func(output_context->in.data, output_context->in.used, &out_str, &out_len, output_context->op TSRMLS_CC); + func(output_context->in.data, output_context->in.used, &out_str, &out_len, output_context->op); if (out_str) { output_context->out.data = out_str; @@ -1319,10 +1295,10 @@ static int php_output_handler_devnull_func(void **handler_context, php_output_co PHP_FUNCTION(ob_start) { zval *output_handler = NULL; - long chunk_size = 0; - long flags = PHP_OUTPUT_HANDLER_STDFLAGS; + zend_long chunk_size = 0; + zend_long flags = PHP_OUTPUT_HANDLER_STDFLAGS; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/ll", &output_handler, &chunk_size, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|z/ll", &output_handler, &chunk_size, &flags) == FAILURE) { return; } @@ -1330,8 +1306,8 @@ PHP_FUNCTION(ob_start) chunk_size = 0; } - if (php_output_start_user(output_handler, chunk_size, flags TSRMLS_CC) == FAILURE) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to create buffer"); + if (php_output_start_user(output_handler, chunk_size, flags) == FAILURE) { + php_error_docref("ref.outcontrol", E_NOTICE, "failed to create buffer"); RETURN_FALSE; } RETURN_TRUE; @@ -1347,12 +1323,12 @@ PHP_FUNCTION(ob_flush) } if (!OG(active)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to flush buffer. No buffer to flush"); + php_error_docref("ref.outcontrol", E_NOTICE, "failed to flush buffer. No buffer to flush"); RETURN_FALSE; } - if (SUCCESS != php_output_flush(TSRMLS_C)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to flush buffer of %s (%d)", OG(active)->name, OG(active)->level); + if (SUCCESS != php_output_flush()) { + php_error_docref("ref.outcontrol", E_NOTICE, "failed to flush buffer of %s (%d)", ZSTR_VAL(OG(active)->name), OG(active)->level); RETURN_FALSE; } RETURN_TRUE; @@ -1368,12 +1344,12 @@ PHP_FUNCTION(ob_clean) } if (!OG(active)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete"); + php_error_docref("ref.outcontrol", E_NOTICE, "failed to delete buffer. No buffer to delete"); RETURN_FALSE; } - if (SUCCESS != php_output_clean(TSRMLS_C)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer of %s (%d)", OG(active)->name, OG(active)->level); + if (SUCCESS != php_output_clean()) { + php_error_docref("ref.outcontrol", E_NOTICE, "failed to delete buffer of %s (%d)", ZSTR_VAL(OG(active)->name), OG(active)->level); RETURN_FALSE; } RETURN_TRUE; @@ -1389,11 +1365,11 @@ PHP_FUNCTION(ob_end_flush) } if (!OG(active)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush"); + php_error_docref("ref.outcontrol", E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush"); RETURN_FALSE; } - RETURN_BOOL(SUCCESS == php_output_end(TSRMLS_C)); + RETURN_BOOL(SUCCESS == php_output_end()); } /* }}} */ @@ -1406,11 +1382,11 @@ PHP_FUNCTION(ob_end_clean) } if (!OG(active)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete"); + php_error_docref("ref.outcontrol", E_NOTICE, "failed to delete buffer. No buffer to delete"); RETURN_FALSE; } - RETURN_BOOL(SUCCESS == php_output_discard(TSRMLS_C)); + RETURN_BOOL(SUCCESS == php_output_discard()); } /* }}} */ @@ -1422,13 +1398,13 @@ PHP_FUNCTION(ob_get_flush) return; } - if (php_output_get_contents(return_value TSRMLS_CC) == FAILURE) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush"); + if (php_output_get_contents(return_value) == FAILURE) { + php_error_docref("ref.outcontrol", E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush"); RETURN_FALSE; } - if (SUCCESS != php_output_end(TSRMLS_C)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer of %s (%d)", OG(active)->name, OG(active)->level); + if (SUCCESS != php_output_end()) { + php_error_docref("ref.outcontrol", E_NOTICE, "failed to delete buffer of %s (%d)", ZSTR_VAL(OG(active)->name), OG(active)->level); } } /* }}} */ @@ -1445,13 +1421,13 @@ PHP_FUNCTION(ob_get_clean) RETURN_FALSE; } - if (php_output_get_contents(return_value TSRMLS_CC) == FAILURE) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete"); + if (php_output_get_contents(return_value) == FAILURE) { + php_error_docref("ref.outcontrol", E_NOTICE, "failed to delete buffer. No buffer to delete"); RETURN_FALSE; } - if (SUCCESS != php_output_discard(TSRMLS_C)) { - php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer of %s (%d)", OG(active)->name, OG(active)->level); + if (SUCCESS != php_output_discard()) { + php_error_docref("ref.outcontrol", E_NOTICE, "failed to delete buffer of %s (%d)", ZSTR_VAL(OG(active)->name), OG(active)->level); } } /* }}} */ @@ -1464,7 +1440,7 @@ PHP_FUNCTION(ob_get_contents) return; } - if (php_output_get_contents(return_value TSRMLS_CC) == FAILURE) { + if (php_output_get_contents(return_value) == FAILURE) { RETURN_FALSE; } } @@ -1478,7 +1454,7 @@ PHP_FUNCTION(ob_get_level) return; } - RETURN_LONG(php_output_get_level(TSRMLS_C)); + RETURN_LONG(php_output_get_level()); } /* }}} */ @@ -1490,7 +1466,7 @@ PHP_FUNCTION(ob_get_length) return; } - if (php_output_get_length(return_value TSRMLS_CC) == FAILURE) { + if (php_output_get_length(return_value) == FAILURE) { RETURN_FALSE; } } @@ -1520,17 +1496,17 @@ PHP_FUNCTION(ob_get_status) { zend_bool full_status = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &full_status) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &full_status) == FAILURE) { return; } - - array_init(return_value); if (!OG(active)) { + array_init(return_value); return; } if (full_status) { + array_init(return_value); zend_stack_apply_with_argument(&OG(handlers), ZEND_STACK_APPLY_BOTTOMUP, php_output_stack_apply_status, return_value); } else { php_output_handler_status(OG(active), return_value); @@ -1542,13 +1518,13 @@ PHP_FUNCTION(ob_get_status) Turn implicit flush on/off and is equivalent to calling flush() after every output call */ PHP_FUNCTION(ob_implicit_flush) { - long flag = 1; + zend_long flag = 1; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flag) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &flag) == FAILURE) { return; } - php_output_set_implicit_flush(flag TSRMLS_CC); + php_output_set_implicit_flush(flag); } /* }}} */ @@ -1556,7 +1532,7 @@ PHP_FUNCTION(ob_implicit_flush) Reset(clear) URL rewriter values */ PHP_FUNCTION(output_reset_rewrite_vars) { - if (php_url_scanner_reset_vars(TSRMLS_C) == SUCCESS) { + if (php_url_scanner_reset_vars() == SUCCESS) { RETURN_TRUE; } else { RETURN_FALSE; @@ -1569,13 +1545,13 @@ PHP_FUNCTION(output_reset_rewrite_vars) PHP_FUNCTION(output_add_rewrite_var) { char *name, *value; - int name_len, value_len; + size_t name_len, value_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &value, &value_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &name, &name_len, &value, &value_len) == FAILURE) { return; } - if (php_url_scanner_add_var(name, name_len, value, value_len, 1 TSRMLS_CC) == SUCCESS) { + if (php_url_scanner_add_var(name, name_len, value, value_len, 1) == SUCCESS) { RETURN_TRUE; } else { RETURN_FALSE; diff --git a/main/php.h b/main/php.h index 243012ccc6..2a461377f4 100644 --- a/main/php.h +++ b/main/php.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -26,14 +26,14 @@ #include <dmalloc.h> #endif -#define PHP_API_VERSION 20131106 +#define PHP_API_VERSION 20131218 #define PHP_HAVE_STREAMS #define YYDEBUG 0 #define PHP_DEFAULT_CHARSET "UTF-8" #include "php_version.h" #include "zend.h" -#include "zend_qsort.h" +#include "zend_sort.h" #include "php_compat.h" #include "zend_API.h" @@ -257,11 +257,7 @@ END_EXTERN_C() # endif #endif -#if defined(__GNUC__) && __GNUC__ >= 4 -# define php_ignore_value(x) (({ __typeof__ (x) __x = (x); (void) __x; })) -#else -# define php_ignore_value(x) ((void) (x)) -#endif +#define php_ignore_value(x) ZEND_IGNORE_VALUE(x) /* global variables */ #if !defined(PHP_WIN32) @@ -280,11 +276,11 @@ ssize_t pread(int, void *, size_t, off64_t); BEGIN_EXTERN_C() void phperror(char *error); -PHPAPI int php_write(void *buf, uint size TSRMLS_DC); -PHPAPI int php_printf(const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 1, +PHPAPI size_t php_write(void *buf, size_t size); +PHPAPI size_t php_printf(const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 1, 2); PHPAPI int php_get_module_initialized(void); -PHPAPI void php_log_err(char *log_message TSRMLS_DC); +PHPAPI ZEND_COLD void php_log_err(char *log_message); int Debug(char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 1, 2); int cfgparse(void); END_EXTERN_C() @@ -293,13 +289,13 @@ END_EXTERN_C() #define error_handling_t zend_error_handling_t BEGIN_EXTERN_C() -static inline ZEND_ATTRIBUTE_DEPRECATED void php_set_error_handling(error_handling_t error_handling, zend_class_entry *exception_class TSRMLS_DC) +static inline ZEND_ATTRIBUTE_DEPRECATED void php_set_error_handling(error_handling_t error_handling, zend_class_entry *exception_class) { - zend_replace_error_handling(error_handling, exception_class, NULL TSRMLS_CC); + zend_replace_error_handling(error_handling, exception_class, NULL); } static inline ZEND_ATTRIBUTE_DEPRECATED void php_std_error_handling() {} -PHPAPI void php_verror(const char *docref, const char *params, int type, const char *format, va_list args TSRMLS_DC) PHP_ATTRIBUTE_FORMAT(printf, 4, 0); +PHPAPI ZEND_COLD void php_verror(const char *docref, const char *params, int type, const char *format, va_list args) PHP_ATTRIBUTE_FORMAT(printf, 4, 0); #ifdef ZTS #define PHP_ATTR_FMT_OFFSET 1 @@ -308,14 +304,14 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c #endif /* PHPAPI void php_error(int type, const char *format, ...); */ -PHPAPI void php_error_docref0(const char *docref TSRMLS_DC, int type, const char *format, ...) +PHPAPI ZEND_COLD void php_error_docref0(const char *docref, int type, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, PHP_ATTR_FMT_OFFSET + 3, PHP_ATTR_FMT_OFFSET + 4); -PHPAPI void php_error_docref1(const char *docref TSRMLS_DC, const char *param1, int type, const char *format, ...) +PHPAPI ZEND_COLD void php_error_docref1(const char *docref, const char *param1, int type, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, PHP_ATTR_FMT_OFFSET + 4, PHP_ATTR_FMT_OFFSET + 5); -PHPAPI void php_error_docref2(const char *docref TSRMLS_DC, const char *param1, const char *param2, int type, const char *format, ...) +PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, PHP_ATTR_FMT_OFFSET + 5, PHP_ATTR_FMT_OFFSET + 6); #ifdef PHP_WIN32 -PHPAPI void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2 TSRMLS_DC); +PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2); #endif END_EXTERN_C() @@ -332,12 +328,12 @@ END_EXTERN_C() /* functions */ BEGIN_EXTERN_C() -PHPAPI extern int (*php_register_internal_extensions_func)(TSRMLS_D); -PHPAPI int php_register_internal_extensions(TSRMLS_D); -PHPAPI int php_mergesort(void *base, size_t nmemb, register size_t size, int (*cmp)(const void *, const void * TSRMLS_DC) TSRMLS_DC); +PHPAPI extern int (*php_register_internal_extensions_func)(void); +PHPAPI int php_register_internal_extensions(void); +PHPAPI int php_mergesort(void *base, size_t nmemb, register size_t size, int (*cmp)(const void *, const void *)); PHPAPI void php_register_pre_request_shutdown(void (*func)(void *), void *userdata); -PHPAPI void php_com_initialize(TSRMLS_D); -PHPAPI char *php_get_current_user(TSRMLS_D); +PHPAPI void php_com_initialize(void); +PHPAPI char *php_get_current_user(void); END_EXTERN_C() /* PHP-named Zend macro wrappers */ @@ -387,7 +383,7 @@ END_EXTERN_C() #define PHP_MINFO_FUNCTION ZEND_MODULE_INFO_D #define PHP_GINIT_FUNCTION ZEND_GINIT_FUNCTION #define PHP_GSHUTDOWN_FUNCTION ZEND_GSHUTDOWN_FUNCTION - + #define PHP_MODULE_GLOBALS ZEND_MODULE_GLOBALS @@ -434,7 +430,7 @@ END_EXTERN_C() #else /* ! (CRAY || __arm) */ #define XtOffset(p_type, field) \ - ((long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL))) + ((zend_long) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL))) #endif /* !CRAY */ #endif /* ! XtOffset */ diff --git a/main/php_compat.h b/main/php_compat.h index 3c826f513d..d4a9efc114 100644 --- a/main/php_compat.h +++ b/main/php_compat.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ diff --git a/main/php_content_types.c b/main/php_content_types.c index 2ec848255d..7b80813040 100644 --- a/main/php_content_types.c +++ b/main/php_content_types.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -33,19 +33,6 @@ static sapi_post_entry php_post_entries[] = { }; /* }}} */ -static zend_bool populate_raw_post_data(TSRMLS_D) -{ - if (!SG(request_info).request_body) { - return (zend_bool) 0; - } - - if (!PG(always_populate_raw_post_data)) { - return (zend_bool) !SG(request_info).post_entry; - } - - return (zend_bool) (PG(always_populate_raw_post_data) > 0); -} - /* {{{ SAPI_POST_READER_FUNC */ SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader) @@ -53,30 +40,7 @@ SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader) if (!strcmp(SG(request_info).request_method, "POST")) { if (NULL == SG(request_info).post_entry) { /* no post handler registered, so we just swallow the data */ - sapi_read_standard_form_data(TSRMLS_C); - } - - if (populate_raw_post_data(TSRMLS_C)) { - size_t length; - char *data = NULL; - - php_stream_rewind(SG(request_info).request_body); - length = php_stream_copy_to_mem(SG(request_info).request_body, &data, PHP_STREAM_COPY_ALL, 0); - php_stream_rewind(SG(request_info).request_body); - - if (length > INT_MAX) { - sapi_module.sapi_error(E_WARNING, - "HTTP_RAW_POST_DATA truncated from %lu to %d bytes", - (unsigned long) length, INT_MAX); - length = INT_MAX; - } - SET_VAR_STRINGL("HTTP_RAW_POST_DATA", data, length); - - sapi_module.sapi_error(E_DEPRECATED, - "Automatically populating $HTTP_RAW_POST_DATA is deprecated and " - "will be removed in a future version. To avoid this warning set " - "'always_populate_raw_post_data' to '-1' in php.ini and use the " - "php://input stream instead."); + sapi_read_standard_form_data(); } } } @@ -84,20 +48,20 @@ SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader) /* {{{ php_startup_sapi_content_types */ -int php_startup_sapi_content_types(TSRMLS_D) +int php_startup_sapi_content_types(void) { - sapi_register_default_post_reader(php_default_post_reader TSRMLS_CC); - sapi_register_treat_data(php_default_treat_data TSRMLS_CC); - sapi_register_input_filter(php_default_input_filter, NULL TSRMLS_CC); + sapi_register_default_post_reader(php_default_post_reader); + sapi_register_treat_data(php_default_treat_data); + sapi_register_input_filter(php_default_input_filter, NULL); return SUCCESS; } /* }}} */ /* {{{ php_setup_sapi_content_types */ -int php_setup_sapi_content_types(TSRMLS_D) +int php_setup_sapi_content_types(void) { - sapi_register_post_entries(php_post_entries TSRMLS_CC); + sapi_register_post_entries(php_post_entries); return SUCCESS; } diff --git a/main/php_content_types.h b/main/php_content_types.h index d8b04b525f..eeca8da39a 100644 --- a/main/php_content_types.h +++ b/main/php_content_types.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -25,7 +25,7 @@ SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader); SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler); -int php_startup_sapi_content_types(TSRMLS_D); -int php_setup_sapi_content_types(TSRMLS_D); +int php_startup_sapi_content_types(void); +int php_setup_sapi_content_types(void); #endif /* PHP_CONTENT_TYPES_H */ diff --git a/main/php_getopt.h b/main/php_getopt.h index 06b61feed2..9437c51d07 100644 --- a/main/php_getopt.h +++ b/main/php_getopt.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ diff --git a/main/php_globals.h b/main/php_globals.h index 5896fcd25c..315e3b7830 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -26,7 +26,7 @@ typedef struct _php_core_globals php_core_globals; #ifdef ZTS -# define PG(v) TSRMG(core_globals_id, php_core_globals *, v) +# define PG(v) ZEND_TSRMG(core_globals_id, php_core_globals *, v) extern PHPAPI int core_globals_id; #else # define PG(v) (core_globals.v) @@ -56,7 +56,7 @@ typedef struct _arg_separators { struct _php_core_globals { zend_bool implicit_flush; - long output_buffering; + zend_long output_buffering; zend_bool sql_safe_mode; zend_bool enable_dl; @@ -64,16 +64,16 @@ struct _php_core_globals { char *output_handler; char *unserialize_callback_func; - long serialize_precision; + zend_long serialize_precision; - long memory_limit; - long max_input_time; + zend_long memory_limit; + zend_long max_input_time; zend_bool track_errors; zend_bool display_errors; zend_bool display_startup_errors; zend_bool log_errors; - long log_errors_max_len; + zend_long log_errors_max_len; zend_bool ignore_repeated_errors; zend_bool ignore_repeated_source; zend_bool report_memleaks; @@ -88,8 +88,8 @@ struct _php_core_globals { char *sys_temp_dir; char *upload_tmp_dir; - long upload_max_filesize; - + zend_long upload_max_filesize; + char *error_append_string; char *error_prepend_string; @@ -113,7 +113,7 @@ struct _php_core_globals { zend_llist tick_functions; - zval *http_globals[6]; + zval http_globals[6]; zend_bool expose_php; @@ -126,7 +126,7 @@ struct _php_core_globals { zend_bool html_errors; zend_bool xmlrpc_errors; - long xmlrpc_error_number; + zend_long xmlrpc_error_number; zend_bool activated_auto_globals[8]; @@ -135,7 +135,6 @@ struct _php_core_globals { zend_bool during_request_startup; zend_bool allow_url_fopen; zend_bool enable_post_data_reading; - signed char always_populate_raw_post_data; zend_bool report_zend_debug; int last_error_type; @@ -143,6 +142,8 @@ struct _php_core_globals { char *last_error_file; int last_error_lineno; + char *php_sys_temp_dir; + char *disable_functions; char *disable_classes; zend_bool allow_url_include; @@ -150,12 +151,12 @@ struct _php_core_globals { #ifdef PHP_WIN32 zend_bool com_initialized; #endif - long max_input_nesting_level; - long max_input_vars; + zend_long max_input_nesting_level; + zend_long max_input_vars; zend_bool in_user_include; char *user_ini_filename; - long user_ini_cache_ttl; + zend_long user_ini_cache_ttl; char *request_order; diff --git a/main/php_ini.c b/main/php_ini.c index 4d7720e66e..17d4e31aeb 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -37,10 +37,6 @@ #include <dirent.h> #endif -#ifndef S_ISREG -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif - #ifdef PHP_WIN32 #define TRANSLATE_SLASHES_LOWER(path) \ { \ @@ -74,18 +70,19 @@ PHPAPI char *php_ini_scanned_files=NULL; /* {{{ php_ini_displayer_cb */ -static void php_ini_displayer_cb(zend_ini_entry *ini_entry, int type TSRMLS_DC) +static void php_ini_displayer_cb(zend_ini_entry *ini_entry, int type) { if (ini_entry->displayer) { ini_entry->displayer(ini_entry, type); } else { char *display_string; - uint display_string_length, esc_html=0; + size_t display_string_length; + int esc_html=0; if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) { - if (ini_entry->orig_value && ini_entry->orig_value[0]) { - display_string = ini_entry->orig_value; - display_string_length = ini_entry->orig_value_length; + if (ini_entry->orig_value && ZSTR_VAL(ini_entry->orig_value)[0]) { + display_string = ZSTR_VAL(ini_entry->orig_value); + display_string_length = ZSTR_LEN(ini_entry->orig_value); esc_html = !sapi_module.phpinfo_as_text; } else { if (!sapi_module.phpinfo_as_text) { @@ -96,9 +93,9 @@ static void php_ini_displayer_cb(zend_ini_entry *ini_entry, int type TSRMLS_DC) display_string_length = sizeof("no value") - 1; } } - } else if (ini_entry->value && ini_entry->value[0]) { - display_string = ini_entry->value; - display_string_length = ini_entry->value_length; + } else if (ini_entry->value && ZSTR_VAL(ini_entry->value)[0]) { + display_string = ZSTR_VAL(ini_entry->value); + display_string_length = ZSTR_LEN(ini_entry->value); esc_html = !sapi_module.phpinfo_as_text; } else { if (!sapi_module.phpinfo_as_text) { @@ -111,7 +108,7 @@ static void php_ini_displayer_cb(zend_ini_entry *ini_entry, int type TSRMLS_DC) } if (esc_html) { - php_html_puts(display_string, display_string_length TSRMLS_CC); + php_html_puts(display_string, display_string_length); } else { PHPWRITE(display_string, display_string_length); } @@ -121,26 +118,29 @@ static void php_ini_displayer_cb(zend_ini_entry *ini_entry, int type TSRMLS_DC) /* {{{ php_ini_displayer */ -static int php_ini_displayer(zend_ini_entry *ini_entry, int module_number TSRMLS_DC) +static int php_ini_displayer(zval *el, void *arg) { + zend_ini_entry *ini_entry = (zend_ini_entry*)Z_PTR_P(el); + int module_number = *(int *)arg; + if (ini_entry->module_number != module_number) { return 0; } if (!sapi_module.phpinfo_as_text) { PUTS("<tr>"); PUTS("<td class=\"e\">"); - PHPWRITE(ini_entry->name, ini_entry->name_length - 1); + PHPWRITE(ZSTR_VAL(ini_entry->name), ZSTR_LEN(ini_entry->name)); PUTS("</td><td class=\"v\">"); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE TSRMLS_CC); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE); PUTS("</td><td class=\"v\">"); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG TSRMLS_CC); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG); PUTS("</td></tr>\n"); } else { - PHPWRITE(ini_entry->name, ini_entry->name_length - 1); + PHPWRITE(ZSTR_VAL(ini_entry->name), ZSTR_LEN(ini_entry->name)); PUTS(" => "); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE TSRMLS_CC); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE); PUTS(" => "); - php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG TSRMLS_CC); + php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG); PUTS("\n"); } return 0; @@ -149,10 +149,12 @@ static int php_ini_displayer(zend_ini_entry *ini_entry, int module_number TSRMLS /* {{{ php_ini_available */ -static int php_ini_available(zend_ini_entry *ini_entry, int *module_number_available TSRMLS_DC) +static int php_ini_available(zval *el, void *arg) { - if (ini_entry->module_number == *module_number_available) { - *module_number_available = -1; + zend_ini_entry *ini_entry = (zend_ini_entry *)Z_PTR_P(el); + int *module_number_available = (int *)arg; + if (ini_entry->module_number == *(int *)module_number_available) { + *(int *)module_number_available = -1; return ZEND_HASH_APPLY_STOP; } else { return ZEND_HASH_APPLY_KEEP; @@ -165,7 +167,6 @@ static int php_ini_available(zend_ini_entry *ini_entry, int *module_number_avail PHPAPI void display_ini_entries(zend_module_entry *module) { int module_number, module_number_available; - TSRMLS_FETCH(); if (module) { module_number = module->module_number; @@ -173,11 +174,11 @@ PHPAPI void display_ini_entries(zend_module_entry *module) module_number = 0; } module_number_available = module_number; - zend_hash_apply_with_argument(EG(ini_directives), (apply_func_arg_t) php_ini_available, &module_number_available TSRMLS_CC); + zend_hash_apply_with_argument(EG(ini_directives), php_ini_available, &module_number_available); if (module_number_available == -1) { php_info_print_table_start(); php_info_print_table_header(3, "Directive", "Local Value", "Master Value"); - zend_hash_apply_with_argument(EG(ini_directives), (apply_func_arg_t) php_ini_displayer, (void *) (zend_intptr_t) module_number TSRMLS_CC); + zend_hash_apply_with_argument(EG(ini_directives), php_ini_displayer, (void *)&module_number); php_info_print_table_end(); } } @@ -193,9 +194,9 @@ PHPAPI void config_zval_dtor(zval *zvalue) { if (Z_TYPE_P(zvalue) == IS_ARRAY) { zend_hash_destroy(Z_ARRVAL_P(zvalue)); - free(Z_ARRVAL_P(zvalue)); + free(Z_ARR_P(zvalue)); } else if (Z_TYPE_P(zvalue) == IS_STRING) { - free(Z_STRVAL_P(zvalue)); + zend_string_release(Z_STR_P(zvalue)); } } /* Reset / free active_ini_sectin global */ @@ -237,14 +238,14 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t /* All other entries are added into either configuration_hash or active ini section array */ } else { /* Store in active hash */ - zend_hash_update(active_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, arg2, sizeof(zval), (void **) &entry); - Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry)); + entry = zend_hash_update(active_hash, Z_STR_P(arg1), arg2); + Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), 1); } } break; case ZEND_INI_PARSER_POP_ENTRY: { - zval *option_arr; + zval option_arr; zval *find_arr; if (!arg2) { @@ -255,23 +256,19 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t /* fprintf(stdout, "ZEND_INI_PARSER_POP_ENTRY: %s[%s] = %s\n",Z_STRVAL_P(arg1), Z_STRVAL_P(arg3), Z_STRVAL_P(arg2)); */ /* If option not found in hash or is not an array -> create array, otherwise add to existing array */ - if (zend_hash_find(active_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, (void **) &find_arr) == FAILURE || Z_TYPE_P(find_arr) != IS_ARRAY) { - option_arr = (zval *) pemalloc(sizeof(zval), 1); - INIT_PZVAL(option_arr); - Z_TYPE_P(option_arr) = IS_ARRAY; - Z_ARRVAL_P(option_arr) = (HashTable *) pemalloc(sizeof(HashTable), 1); - zend_hash_init(Z_ARRVAL_P(option_arr), 0, NULL, (dtor_func_t) config_zval_dtor, 1); - zend_hash_update(active_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1) + 1, option_arr, sizeof(zval), (void **) &find_arr); - free(option_arr); + if ((find_arr = zend_hash_find(active_hash, Z_STR_P(arg1))) == NULL || Z_TYPE_P(find_arr) != IS_ARRAY) { + ZVAL_NEW_PERSISTENT_ARR(&option_arr); + zend_hash_init(Z_ARRVAL(option_arr), 8, NULL, config_zval_dtor, 1); + find_arr = zend_hash_update(active_hash, Z_STR_P(arg1), &option_arr); } /* arg3 is possible option offset name */ if (arg3 && Z_STRLEN_P(arg3) > 0) { - zend_symtable_update(Z_ARRVAL_P(find_arr), Z_STRVAL_P(arg3), Z_STRLEN_P(arg3) + 1, arg2, sizeof(zval), (void **) &entry); + entry = zend_symtable_update(Z_ARRVAL_P(find_arr), Z_STR_P(arg3), arg2); } else { - zend_hash_next_index_insert(Z_ARRVAL_P(find_arr), arg2, sizeof(zval), (void **) &entry); + entry = zend_hash_next_index_insert(Z_ARRVAL_P(find_arr), arg2); } - Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry)); + Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), 1); } break; @@ -280,7 +277,7 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t /* fprintf(stdout, "ZEND_INI_PARSER_SECTION: %s\n",Z_STRVAL_P(arg1)); */ char *key = NULL; - uint key_len; + size_t key_len; /* PATH sections */ if (!strncasecmp(Z_STRVAL_P(arg1), "PATH", sizeof("PATH") - 1)) { @@ -324,16 +321,12 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t } /* Search for existing entry and if it does not exist create one */ - if (zend_hash_find(target_hash, key, key_len + 1, (void **) &entry) == FAILURE) { - zval *section_arr; - - section_arr = (zval *) pemalloc(sizeof(zval), 1); - INIT_PZVAL(section_arr); - Z_TYPE_P(section_arr) = IS_ARRAY; - Z_ARRVAL_P(section_arr) = (HashTable *) pemalloc(sizeof(HashTable), 1); - zend_hash_init(Z_ARRVAL_P(section_arr), 0, NULL, (dtor_func_t) config_zval_dtor, 1); - zend_hash_update(target_hash, key, key_len + 1, section_arr, sizeof(zval), (void **) &entry); - free(section_arr); + if ((entry = zend_hash_str_find(target_hash, key, key_len)) == NULL) { + zval section_arr; + + ZVAL_NEW_PERSISTENT_ARR(§ion_arr); + zend_hash_init(Z_ARRVAL(section_arr), 8, NULL, (dtor_func_t) config_zval_dtor, 1); + entry = zend_hash_str_update(target_hash, key, key_len, §ion_arr); } active_ini_hash = Z_ARRVAL_P(entry); } @@ -345,27 +338,31 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t /* {{{ php_load_php_extension_cb */ -static void php_load_php_extension_cb(void *arg TSRMLS_DC) +static void php_load_php_extension_cb(void *arg) { #ifdef HAVE_LIBDL - php_load_extension(*((char **) arg), MODULE_PERSISTENT, 0 TSRMLS_CC); + php_load_extension(*((char **) arg), MODULE_PERSISTENT, 0); #endif } /* }}} */ /* {{{ php_load_zend_extension_cb */ -static void php_load_zend_extension_cb(void *arg TSRMLS_DC) +static void php_load_zend_extension_cb(void *arg) { char *filename = *((char **) arg); - int length = strlen(filename); + const int length = (int)strlen(filename); + +#ifndef PHP_WIN32 + (void) length; +#endif if (IS_ABSOLUTE_PATH(filename, length)) { zend_load_extension(filename); } else { char *libpath; char *extension_dir = INI_STR("extension_dir"); - int extension_dir_len = strlen(extension_dir); + int extension_dir_len = (int)strlen(extension_dir); if (IS_SLASH(extension_dir[extension_dir_len-1])) { spprintf(&libpath, 0, "%s%s", extension_dir, filename); @@ -380,7 +377,7 @@ static void php_load_zend_extension_cb(void *arg TSRMLS_DC) /* {{{ php_init_config */ -int php_init_config(TSRMLS_D) +int php_init_config(void) { char *php_ini_file_name = NULL; char *php_ini_search_path = NULL; @@ -388,10 +385,9 @@ int php_init_config(TSRMLS_D) char *open_basedir; int free_ini_search_path = 0; zend_file_handle fh; + zend_string *opened_path = NULL; - if (zend_hash_init(&configuration_hash, 0, NULL, (dtor_func_t) config_zval_dtor, 1) == FAILURE) { - return FAILURE; - } + zend_hash_init(&configuration_hash, 8, NULL, config_zval_dtor, 1); if (sapi_module.ini_defaults) { sapi_module.ini_defaults(&configuration_hash); @@ -425,8 +421,8 @@ int php_init_config(TSRMLS_D) SetLastError(0); - /*If the given bugger is not large enough to hold the data, the return value is - the buffer size, in characters, required to hold the string and its terminating + /*If the given buffer is not large enough to hold the data, the return value is + the buffer size, in characters, required to hold the string and its terminating null character. We use this return value to alloc the final buffer. */ size = GetEnvironmentVariableA("PHPRC", &dummybuf, 0); if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) { @@ -454,7 +450,7 @@ int php_init_config(TSRMLS_D) * Prepare search path */ - search_path_size = MAXPATHLEN * 4 + strlen(env_location) + 3 + 1; + search_path_size = MAXPATHLEN * 4 + (int)strlen(env_location) + 3 + 1; php_ini_search_path = (char *) emalloc(search_path_size); free_ini_search_path = 1; php_ini_search_path[0] = 0; @@ -550,13 +546,13 @@ int php_init_config(TSRMLS_D) /* Check if php_ini_file_name is a file and can be opened */ if (php_ini_file_name && php_ini_file_name[0]) { - struct stat statbuf; + zend_stat_t statbuf; if (!VCWD_STAT(php_ini_file_name, &statbuf)) { if (!((statbuf.st_mode & S_IFMT) == S_IFDIR)) { fh.handle.fp = VCWD_FOPEN(php_ini_file_name, "r"); if (fh.handle.fp) { - fh.filename = php_ini_opened_path = expand_filepath(php_ini_file_name, NULL TSRMLS_CC); + fh.filename = expand_filepath(php_ini_file_name, NULL); } } } @@ -567,18 +563,18 @@ int php_init_config(TSRMLS_D) const char *fmt = "php-%s.ini"; char *ini_fname; spprintf(&ini_fname, 0, fmt, sapi_module.name); - fh.handle.fp = php_fopen_with_path(ini_fname, "r", php_ini_search_path, &php_ini_opened_path TSRMLS_CC); + fh.handle.fp = php_fopen_with_path(ini_fname, "r", php_ini_search_path, &opened_path); efree(ini_fname); if (fh.handle.fp) { - fh.filename = php_ini_opened_path; + fh.filename = ZSTR_VAL(opened_path); } } /* If still no ini file found, search for php.ini file in search path */ if (!fh.handle.fp) { - fh.handle.fp = php_fopen_with_path("php.ini", "r", php_ini_search_path, &php_ini_opened_path TSRMLS_CC); + fh.handle.fp = php_fopen_with_path("php.ini", "r", php_ini_search_path, &opened_path); if (fh.handle.fp) { - fh.filename = php_ini_opened_path; + fh.filename = ZSTR_VAL(opened_path); } } } @@ -593,19 +589,17 @@ int php_init_config(TSRMLS_D) fh.type = ZEND_HANDLE_FP; RESET_ACTIVE_INI_HASH(); - zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash TSRMLS_CC); + zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash); { zval tmp; - Z_STRLEN(tmp) = strlen(fh.filename); - Z_STRVAL(tmp) = zend_strndup(fh.filename, Z_STRLEN(tmp)); - Z_TYPE(tmp) = IS_STRING; - Z_SET_REFCOUNT(tmp, 0); - - zend_hash_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path"), (void *) &tmp, sizeof(zval), NULL); - if (php_ini_opened_path) { - efree(php_ini_opened_path); + ZVAL_NEW_STR(&tmp, zend_string_init(fh.filename, strlen(fh.filename), 1)); + zend_hash_str_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path")-1, &tmp); + if (opened_path) { + zend_string_release(opened_path); + } else { + efree((char *)fh.filename); } php_ini_opened_path = zend_strndup(Z_STRVAL(tmp), Z_STRLEN(tmp)); } @@ -617,13 +611,13 @@ int php_init_config(TSRMLS_D) /* Or fall back using possible --with-config-file-scan-dir setting (defaults to empty string!) */ php_ini_scanned_path = PHP_CONFIG_FILE_SCAN_DIR; } - php_ini_scanned_path_len = strlen(php_ini_scanned_path); + php_ini_scanned_path_len = (int)strlen(php_ini_scanned_path); /* Scan and parse any .ini files found in scan path if path not empty. */ if (!sapi_module.php_ini_ignore && php_ini_scanned_path_len) { struct dirent **namelist; int ndir, i; - struct stat sb; + zend_stat_t sb; char ini_file[MAXPATHLEN]; char *p; zend_file_handle fh2; @@ -647,7 +641,7 @@ int php_init_config(TSRMLS_D) to allow "/foo/phd.d:" or ":/foo/php.d" */ debpath = PHP_CONFIG_FILE_SCAN_DIR; } - lenpath = strlen(debpath); + lenpath = (int)strlen(debpath); if (lenpath > 0 && (ndir = php_scandir(debpath, &namelist, 0, php_alphasort)) > 0) { @@ -672,9 +666,9 @@ int php_init_config(TSRMLS_D) fh2.filename = ini_file; fh2.type = ZEND_HANDLE_FP; - if (zend_parse_ini_file(&fh2, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash TSRMLS_CC) == SUCCESS) { + if (zend_parse_ini_file(&fh2, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash) == SUCCESS) { /* Here, add it to the list of ini files read */ - l = strlen(ini_file); + l = (int)strlen(ini_file); total_l += l + 2; p = estrndup(ini_file, l); zend_llist_add_element(&scanned_ini_list, &p); @@ -690,7 +684,7 @@ int php_init_config(TSRMLS_D) efree(bufpath); if (total_l) { - int php_ini_scanned_files_len = (php_ini_scanned_files) ? strlen(php_ini_scanned_files) + 1 : 0; + int php_ini_scanned_files_len = (php_ini_scanned_files) ? (int)strlen(php_ini_scanned_files) + 1 : 0; php_ini_scanned_files = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1); if (!php_ini_scanned_files_len) { *php_ini_scanned_files = '\0'; @@ -713,7 +707,7 @@ int php_init_config(TSRMLS_D) if (sapi_module.ini_entries) { /* Reset active ini section */ RESET_ACTIVE_INI_HASH(); - zend_parse_ini_string(sapi_module.ini_entries, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash TSRMLS_CC); + zend_parse_ini_string(sapi_module.ini_entries, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash); } return SUCCESS; @@ -739,10 +733,10 @@ int php_shutdown_config(void) /* {{{ php_ini_register_extensions */ -void php_ini_register_extensions(TSRMLS_D) +void php_ini_register_extensions(void) { - zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb TSRMLS_CC); - zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb TSRMLS_CC); + zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb); + zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb); zend_llist_destroy(&extension_lists.engine); zend_llist_destroy(&extension_lists.functions); @@ -751,9 +745,9 @@ void php_ini_register_extensions(TSRMLS_D) /* {{{ php_parse_user_ini_file */ -PHPAPI int php_parse_user_ini_file(const char *dirname, char *ini_filename, HashTable *target_hash TSRMLS_DC) +PHPAPI int php_parse_user_ini_file(const char *dirname, char *ini_filename, HashTable *target_hash) { - struct stat sb; + zend_stat_t sb; char ini_file[MAXPATHLEN]; zend_file_handle fh; @@ -769,7 +763,7 @@ PHPAPI int php_parse_user_ini_file(const char *dirname, char *ini_filename, Hash /* Reset active ini section */ RESET_ACTIVE_INI_HASH(); - if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash TSRMLS_CC) == SUCCESS) { + if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash) == SUCCESS) { /* FIXME: Add parsed file to the list of user files read? */ return SUCCESS; } @@ -783,21 +777,15 @@ PHPAPI int php_parse_user_ini_file(const char *dirname, char *ini_filename, Hash /* {{{ php_ini_activate_config */ -PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage TSRMLS_DC) +PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage) { - char *str; + zend_string *str; zval *data; - uint str_len; - ulong num_index; /* Walk through config hash and alter matching ini entries using the values found in the hash */ - for (zend_hash_internal_pointer_reset(source_hash); - zend_hash_get_current_key_ex(source_hash, &str, &str_len, &num_index, 0, NULL) == HASH_KEY_IS_STRING; - zend_hash_move_forward(source_hash) - ) { - zend_hash_get_current_data(source_hash, (void **) &data); - zend_alter_ini_entry_ex(str, str_len, Z_STRVAL_P(data), Z_STRLEN_P(data), modify_type, stage, 0 TSRMLS_CC); - } + ZEND_HASH_FOREACH_STR_KEY_VAL(source_hash, str, data) { + zend_alter_ini_entry_ex(str, Z_STR_P(data), modify_type, stage, 0); + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -811,7 +799,7 @@ PHPAPI int php_ini_has_per_dir_config(void) /* {{{ php_ini_activate_per_dir_config */ -PHPAPI void php_ini_activate_per_dir_config(char *path, uint path_len TSRMLS_DC) +PHPAPI void php_ini_activate_per_dir_config(char *path, size_t path_len) { zval *tmp2; char *ptr; @@ -842,8 +830,8 @@ PHPAPI void php_ini_activate_per_dir_config(char *path, uint path_len TSRMLS_DC) while ((ptr = strchr(ptr, '/')) != NULL) { *ptr = 0; /* Search for source array matching the path from configuration_hash */ - if (zend_hash_find(&configuration_hash, path, strlen(path) + 1, (void **) &tmp2) == SUCCESS) { - php_ini_activate_config(Z_ARRVAL_P(tmp2), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE TSRMLS_CC); + if ((tmp2 = zend_hash_str_find(&configuration_hash, path, strlen(path))) != NULL) { + php_ini_activate_config(Z_ARRVAL_P(tmp2), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); } *ptr = '/'; ptr++; @@ -862,14 +850,14 @@ PHPAPI int php_ini_has_per_host_config(void) /* {{{ php_ini_activate_per_host_config */ -PHPAPI void php_ini_activate_per_host_config(const char *host, uint host_len TSRMLS_DC) +PHPAPI void php_ini_activate_per_host_config(const char *host, size_t host_len) { zval *tmp; if (has_per_host_config && host && host_len) { /* Search for source array matching the host from configuration_hash */ - if (zend_hash_find(&configuration_hash, host, host_len, (void **) &tmp) == SUCCESS) { - php_ini_activate_config(Z_ARRVAL_P(tmp), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE TSRMLS_CC); + if ((tmp = zend_hash_str_find(&configuration_hash, host, host_len)) != NULL) { + php_ini_activate_config(Z_ARRVAL_P(tmp), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); } } } @@ -877,32 +865,31 @@ PHPAPI void php_ini_activate_per_host_config(const char *host, uint host_len TSR /* {{{ cfg_get_entry */ -PHPAPI zval *cfg_get_entry(const char *name, uint name_length) +PHPAPI zval *cfg_get_entry_ex(zend_string *name) { - zval *tmp; + return zend_hash_find(&configuration_hash, name); +} +/* }}} */ - if (zend_hash_find(&configuration_hash, name, name_length, (void **) &tmp) == SUCCESS) { - return tmp; - } else { - return NULL; - } +/* {{{ cfg_get_entry + */ +PHPAPI zval *cfg_get_entry(const char *name, size_t name_length) +{ + return zend_hash_str_find(&configuration_hash, name, name_length); } /* }}} */ /* {{{ cfg_get_long */ -PHPAPI int cfg_get_long(const char *varname, long *result) +PHPAPI int cfg_get_long(const char *varname, zend_long *result) { - zval *tmp, var; + zval *tmp; - if (zend_hash_find(&configuration_hash, varname, strlen(varname) + 1, (void **) &tmp) == FAILURE) { + if ((tmp = zend_hash_str_find(&configuration_hash, varname, strlen(varname))) == NULL) { *result = 0; return FAILURE; } - var = *tmp; - zval_copy_ctor(&var); - convert_to_long(&var); - *result = Z_LVAL(var); + *result = zval_get_long(tmp); return SUCCESS; } /* }}} */ @@ -911,16 +898,13 @@ PHPAPI int cfg_get_long(const char *varname, long *result) */ PHPAPI int cfg_get_double(const char *varname, double *result) { - zval *tmp, var; + zval *tmp; - if (zend_hash_find(&configuration_hash, varname, strlen(varname) + 1, (void **) &tmp) == FAILURE) { + if ((tmp = zend_hash_str_find(&configuration_hash, varname, strlen(varname))) == NULL) { *result = (double) 0; return FAILURE; } - var = *tmp; - zval_copy_ctor(&var); - convert_to_double(&var); - *result = Z_DVAL(var); + *result = zval_get_double(tmp); return SUCCESS; } /* }}} */ @@ -931,7 +915,7 @@ PHPAPI int cfg_get_string(const char *varname, char **result) { zval *tmp; - if (zend_hash_find(&configuration_hash, varname, strlen(varname)+1, (void **) &tmp) == FAILURE) { + if ((tmp = zend_hash_str_find(&configuration_hash, varname, strlen(varname))) == NULL) { *result = NULL; return FAILURE; } diff --git a/main/php_ini.h b/main/php_ini.h index ad287fa2bb..f583208800 100644 --- a/main/php_ini.h +++ b/main/php_ini.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -25,19 +25,20 @@ BEGIN_EXTERN_C() PHPAPI void config_zval_dtor(zval *zvalue); -int php_init_config(TSRMLS_D); +int php_init_config(void); int php_shutdown_config(void); -void php_ini_register_extensions(TSRMLS_D); -PHPAPI zval *cfg_get_entry(const char *name, uint name_length); -PHPAPI int cfg_get_long(const char *varname, long *result); +void php_ini_register_extensions(void); +PHPAPI zval *cfg_get_entry_ex(zend_string *name); +PHPAPI zval *cfg_get_entry(const char *name, size_t name_length); +PHPAPI int cfg_get_long(const char *varname, zend_long *result); PHPAPI int cfg_get_double(const char *varname, double *result); PHPAPI int cfg_get_string(const char *varname, char **result); -PHPAPI int php_parse_user_ini_file(const char *dirname, char *ini_filename, HashTable *target_hash TSRMLS_DC); -PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage TSRMLS_DC); +PHPAPI int php_parse_user_ini_file(const char *dirname, char *ini_filename, HashTable *target_hash); +PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage); PHPAPI int php_ini_has_per_dir_config(void); PHPAPI int php_ini_has_per_host_config(void); -PHPAPI void php_ini_activate_per_dir_config(char *path, uint path_len TSRMLS_DC); -PHPAPI void php_ini_activate_per_host_config(const char *host, uint host_len TSRMLS_DC); +PHPAPI void php_ini_activate_per_dir_config(char *path, size_t path_len); +PHPAPI void php_ini_activate_per_host_config(const char *host, size_t host_len); PHPAPI HashTable* php_ini_get_configuration_hash(void); END_EXTERN_C() diff --git a/main/php_main.h b/main/php_main.h index 2afd23f340..7caaba6ea7 100644 --- a/main/php_main.h +++ b/main/php_main.h @@ -1,6 +1,6 @@ -/* +/* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -27,28 +27,28 @@ #include "SAPI.h" BEGIN_EXTERN_C() -PHPAPI int php_request_startup(TSRMLS_D); +PHPAPI int php_request_startup(void); PHPAPI void php_request_shutdown(void *dummy); PHPAPI void php_request_shutdown_for_exec(void *dummy); PHPAPI int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules); -PHPAPI void php_module_shutdown(TSRMLS_D); +PHPAPI void php_module_shutdown(void); PHPAPI void php_module_shutdown_for_exec(void); PHPAPI int php_module_shutdown_wrapper(sapi_module_struct *sapi_globals); -PHPAPI int php_request_startup_for_hook(TSRMLS_D); +PHPAPI int php_request_startup_for_hook(void); PHPAPI void php_request_shutdown_for_hook(void *dummy); -PHPAPI int php_register_extensions(zend_module_entry **ptr, int count TSRMLS_DC); +PHPAPI int php_register_extensions(zend_module_entry **ptr, int count); -PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC); -PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret TSRMLS_DC); -PHPAPI int php_handle_special_queries(TSRMLS_D); -PHPAPI int php_lint_script(zend_file_handle *file TSRMLS_DC); +PHPAPI int php_execute_script(zend_file_handle *primary_file); +PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval *ret); +PHPAPI int php_handle_special_queries(void); +PHPAPI int php_lint_script(zend_file_handle *file); PHPAPI void php_handle_aborted_connection(void); -PHPAPI int php_handle_auth_data(const char *auth TSRMLS_DC); +PHPAPI int php_handle_auth_data(const char *auth); -PHPAPI void php_html_puts(const char *str, uint siz TSRMLS_DC); -PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode TSRMLS_DC); +PHPAPI void php_html_puts(const char *str, size_t siz); +PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode); /* environment module */ extern int php_init_environ(void); diff --git a/main/php_memory_streams.h b/main/php_memory_streams.h index 9ee4eed417..8db6e5323b 100644 --- a/main/php_memory_streams.h +++ b/main/php_memory_streams.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -29,25 +29,25 @@ #define TEMP_STREAM_READONLY 1 #define TEMP_STREAM_TAKE_BUFFER 2 -#define php_stream_memory_create(mode) _php_stream_memory_create((mode) STREAMS_CC TSRMLS_CC) -#define php_stream_memory_create_rel(mode) _php_stream_memory_create((mode) STREAMS_REL_CC TSRMLS_CC) -#define php_stream_memory_open(mode, buf, length) _php_stream_memory_open((mode), (buf), (length) STREAMS_CC TSRMLS_CC) -#define php_stream_memory_get_buffer(stream, length) _php_stream_memory_get_buffer((stream), (length) STREAMS_CC TSRMLS_CC) +#define php_stream_memory_create(mode) _php_stream_memory_create((mode) STREAMS_CC) +#define php_stream_memory_create_rel(mode) _php_stream_memory_create((mode) STREAMS_REL_CC) +#define php_stream_memory_open(mode, buf, length) _php_stream_memory_open((mode), (buf), (length) STREAMS_CC) +#define php_stream_memory_get_buffer(stream, length) _php_stream_memory_get_buffer((stream), (length) STREAMS_CC) #define php_stream_temp_new() php_stream_temp_create(TEMP_STREAM_DEFAULT, PHP_STREAM_MAX_MEM) -#define php_stream_temp_create(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_CC TSRMLS_CC) -#define php_stream_temp_create_ex(mode, max_memory_usage, tmpdir) _php_stream_temp_create_ex((mode), (max_memory_usage), (tmpdir) STREAMS_CC TSRMLS_CC) -#define php_stream_temp_create_rel(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_REL_CC TSRMLS_CC) -#define php_stream_temp_open(mode, max_memory_usage, buf, length) _php_stream_temp_open((mode), (max_memory_usage), (buf), (length) STREAMS_CC TSRMLS_CC) +#define php_stream_temp_create(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_CC) +#define php_stream_temp_create_ex(mode, max_memory_usage, tmpdir) _php_stream_temp_create_ex((mode), (max_memory_usage), (tmpdir) STREAMS_CC) +#define php_stream_temp_create_rel(mode, max_memory_usage) _php_stream_temp_create((mode), (max_memory_usage) STREAMS_REL_CC) +#define php_stream_temp_open(mode, max_memory_usage, buf, length) _php_stream_temp_open((mode), (max_memory_usage), (buf), (length) STREAMS_CC) BEGIN_EXTERN_C() -PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC TSRMLS_DC); -PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length STREAMS_DC TSRMLS_DC); -PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length STREAMS_DC TSRMLS_DC); +PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC); +PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length STREAMS_DC); +PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length STREAMS_DC); -PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC); -PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC TSRMLS_DC); -PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC TSRMLS_DC); +PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC); +PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC); +PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC); END_EXTERN_C() extern PHPAPI php_stream_ops php_stream_memory_ops; diff --git a/main/php_network.h b/main/php_network.h index 8dc4e0aa60..d17530208a 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -63,6 +63,7 @@ * Also works sensibly for win32 */ BEGIN_EXTERN_C() PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize); +PHPAPI zend_string *php_socket_error_str(long err); END_EXTERN_C() #ifdef HAVE_NETINET_IN_H @@ -105,6 +106,11 @@ typedef int php_socket_t; # define SOCK_RECV_ERR -1 #endif +#define STREAM_SOCKOP_NONE 1 << 0 +#define STREAM_SOCKOP_SO_REUSEPORT 1 << 1 +#define STREAM_SOCKOP_SO_BROADCAST 1 << 2 + + /* uncomment this to debug poll(2) emulation on systems that have poll(2) */ /* #define PHP_USE_POLL_2_EMULATION 1 */ @@ -224,49 +230,49 @@ typedef struct { #endif BEGIN_EXTERN_C() -PHPAPI int php_network_getaddresses(const char *host, int socktype, struct sockaddr ***sal, char **error_string TSRMLS_DC); +PHPAPI int php_network_getaddresses(const char *host, int socktype, struct sockaddr ***sal, zend_string **error_string); PHPAPI void php_network_freeaddresses(struct sockaddr **sal); PHPAPI php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short port, - int socktype, int asynchronous, struct timeval *timeout, char **error_string, - int *error_code, char *bindto, unsigned short bindport - TSRMLS_DC); + int socktype, int asynchronous, struct timeval *timeout, zend_string **error_string, + int *error_code, char *bindto, unsigned short bindport, long sockopts + ); PHPAPI int php_network_connect_socket(php_socket_t sockfd, const struct sockaddr *addr, socklen_t addrlen, int asynchronous, struct timeval *timeout, - char **error_string, + zend_string **error_string, int *error_code); #define php_connect_nonb(sock, addr, addrlen, timeout) \ php_network_connect_socket((sock), (addr), (addrlen), 0, (timeout), NULL, NULL) PHPAPI php_socket_t php_network_bind_socket_to_local_addr(const char *host, unsigned port, - int socktype, char **error_string, int *error_code - TSRMLS_DC); + int socktype, long sockopts, zend_string **error_string, int *error_code + ); PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock, - char **textaddr, long *textaddrlen, + zend_string **textaddr, struct sockaddr **addr, socklen_t *addrlen, struct timeval *timeout, - char **error_string, + zend_string **error_string, int *error_code - TSRMLS_DC); + ); -PHPAPI int php_network_get_sock_name(php_socket_t sock, - char **textaddr, long *textaddrlen, +PHPAPI int php_network_get_sock_name(php_socket_t sock, + zend_string **textaddr, struct sockaddr **addr, socklen_t *addrlen - TSRMLS_DC); - -PHPAPI int php_network_get_peer_name(php_socket_t sock, - char **textaddr, long *textaddrlen, + ); + +PHPAPI int php_network_get_peer_name(php_socket_t sock, + zend_string **textaddr, struct sockaddr **addr, socklen_t *addrlen - TSRMLS_DC); + ); PHPAPI void php_any_addr(int family, php_sockaddr_storage *addr, unsigned short port); PHPAPI int php_sockaddr_size(php_sockaddr_storage *addr); @@ -285,31 +291,31 @@ extern php_stream_ops php_stream_generic_socket_ops; #define PHP_STREAM_IS_SOCKET (&php_stream_socket_ops) BEGIN_EXTERN_C() -PHPAPI php_stream *_php_stream_sock_open_from_socket(php_socket_t socket, const char *persistent_id STREAMS_DC TSRMLS_DC ); +PHPAPI php_stream *_php_stream_sock_open_from_socket(php_socket_t socket, const char *persistent_id STREAMS_DC ); /* open a connection to a host using php_hostconnect and return a stream */ PHPAPI php_stream *_php_stream_sock_open_host(const char *host, unsigned short port, - int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC TSRMLS_DC); + int socktype, struct timeval *timeout, const char *persistent_id STREAMS_DC); PHPAPI void php_network_populate_name_from_sockaddr( /* input address */ struct sockaddr *sa, socklen_t sl, /* output readable address */ - char **textaddr, long *textaddrlen, + zend_string **textaddr, /* output address */ struct sockaddr **addr, socklen_t *addrlen - TSRMLS_DC); + ); PHPAPI int php_network_parse_network_address_with_port(const char *addr, - long addrlen, struct sockaddr *sa, socklen_t *sl TSRMLS_DC); + zend_long addrlen, struct sockaddr *sa, socklen_t *sl); END_EXTERN_C() -#define php_stream_sock_open_from_socket(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_CC TSRMLS_CC) -#define php_stream_sock_open_host(host, port, socktype, timeout, persistent) _php_stream_sock_open_host((host), (port), (socktype), (timeout), (persistent) STREAMS_CC TSRMLS_CC) +#define php_stream_sock_open_from_socket(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_CC) +#define php_stream_sock_open_host(host, port, socktype, timeout, persistent) _php_stream_sock_open_host((host), (port), (socktype), (timeout), (persistent) STREAMS_CC) /* {{{ memory debug */ -#define php_stream_sock_open_from_socket_rel(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_REL_CC TSRMLS_CC) -#define php_stream_sock_open_host_rel(host, port, socktype, timeout, persistent) _php_stream_sock_open_host((host), (port), (socktype), (timeout), (persistent) STREAMS_REL_CC TSRMLS_CC) -#define php_stream_sock_open_unix_rel(path, pathlen, persistent, timeval) _php_stream_sock_open_unix((path), (pathlen), (persistent), (timeval) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_sock_open_from_socket_rel(socket, persistent) _php_stream_sock_open_from_socket((socket), (persistent) STREAMS_REL_CC) +#define php_stream_sock_open_host_rel(host, port, socktype, timeout, persistent) _php_stream_sock_open_host((host), (port), (socktype), (timeout), (persistent) STREAMS_REL_CC) +#define php_stream_sock_open_unix_rel(path, pathlen, persistent, timeval) _php_stream_sock_open_unix((path), (pathlen), (persistent), (timeval) STREAMS_REL_CC) /* }}} */ diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c index cbfecca0be..4b8a5636b9 100644 --- a/main/php_open_temporary_file.c +++ b/main/php_open_temporary_file.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -94,10 +94,10 @@ * SUCH DAMAGE. */ -static int php_do_open_temporary_file(const char *path, const char *pfx, char **opened_path_p TSRMLS_DC) +static int php_do_open_temporary_file(const char *path, const char *pfx, zend_string **opened_path_p) { char *trailing_slash; - char *opened_path; + char opened_path[MAXPATHLEN]; char cwd[MAXPATHLEN]; cwd_state new_state; int fd = -1; @@ -125,9 +125,9 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** } new_state.cwd = estrdup(cwd); - new_state.cwd_length = strlen(cwd); + new_state.cwd_length = (int)strlen(cwd); - if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH TSRMLS_CC)) { + if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) { efree(new_state.cwd); return -1; } @@ -138,8 +138,7 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** trailing_slash = "/"; } - if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) { - efree(opened_path); + if (snprintf(opened_path, MAXPATHLEN, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) { efree(new_state.cwd); return -1; } @@ -150,7 +149,6 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** /* Some versions of windows set the temp file to be read-only, * which means that opening it will fail... */ if (VCWD_CHMOD(opened_path, 0600)) { - efree(opened_path); efree(new_state.cwd); return -1; } @@ -165,56 +163,35 @@ static int php_do_open_temporary_file(const char *path, const char *pfx, char ** } #endif - if (fd == -1 || !opened_path_p) { - efree(opened_path); - } else { - *opened_path_p = opened_path; + if (fd != -1 && opened_path_p) { + *opened_path_p = zend_string_init(opened_path, strlen(opened_path), 0); } efree(new_state.cwd); return fd; } /* }}} */ -/* Cache the chosen temporary directory. */ -static -#ifdef ZTS -#ifdef PHP_WIN32 -__declspec(thread) -#elif defined(__GNUC__) -__thread -#endif -#endif -char* temporary_directory; - -PHPAPI void php_shutdown_temporary_directory(void) -{ - if (temporary_directory) { - efree(temporary_directory); - temporary_directory = NULL; - } -} - /* * Determine where to place temporary files. */ -PHPAPI const char* php_get_temporary_directory(TSRMLS_D) +PHPAPI const char* php_get_temporary_directory(void) { /* Did we determine the temporary directory already? */ - if (temporary_directory) { - return temporary_directory; + if (PG(php_sys_temp_dir)) { + return PG(php_sys_temp_dir); } /* Is there a temporary directory "sys_temp_dir" in .ini defined? */ { char *sys_temp_dir = PG(sys_temp_dir); if (sys_temp_dir) { - int len = strlen(sys_temp_dir); + int len = (int)strlen(sys_temp_dir); if (len >= 2 && sys_temp_dir[len - 1] == DEFAULT_SLASH) { - temporary_directory = estrndup(sys_temp_dir, len - 1); - return temporary_directory; + PG(php_sys_temp_dir) = estrndup(sys_temp_dir, len - 1); + return PG(php_sys_temp_dir); } else if (len >= 1 && sys_temp_dir[len - 1] != DEFAULT_SLASH) { - temporary_directory = estrndup(sys_temp_dir, len); - return temporary_directory; + PG(php_sys_temp_dir) = estrndup(sys_temp_dir, len); + return PG(php_sys_temp_dir); } } } @@ -230,11 +207,11 @@ PHPAPI const char* php_get_temporary_directory(TSRMLS_D) DWORD len = GetTempPath(sizeof(sTemp),sTemp); assert(0 < len); /* should *never* fail! */ if (sTemp[len - 1] == DEFAULT_SLASH) { - temporary_directory = estrndup(sTemp, len - 1); + PG(php_sys_temp_dir) = estrndup(sTemp, len - 1); } else { - temporary_directory = estrndup(sTemp, len); + PG(php_sys_temp_dir) = estrndup(sTemp, len); } - return temporary_directory; + return PG(php_sys_temp_dir); } #else /* On Unix use the (usual) TMPDIR environment variable. */ @@ -244,24 +221,24 @@ PHPAPI const char* php_get_temporary_directory(TSRMLS_D) int len = strlen(s); if (s[len - 1] == DEFAULT_SLASH) { - temporary_directory = estrndup(s, len - 1); + PG(php_sys_temp_dir) = estrndup(s, len - 1); } else { - temporary_directory = estrndup(s, len); + PG(php_sys_temp_dir) = estrndup(s, len); } - return temporary_directory; + return PG(php_sys_temp_dir); } } #ifdef P_tmpdir /* Use the standard default temporary directory. */ if (P_tmpdir) { - temporary_directory = estrdup(P_tmpdir); - return temporary_directory; + PG(php_sys_temp_dir) = estrdup(P_tmpdir); + return PG(php_sys_temp_dir); } #endif /* Shouldn't ever(!) end up here ... last ditch default. */ - temporary_directory = estrndup("/tmp", sizeof("/tmp")); - return temporary_directory; + PG(php_sys_temp_dir) = estrdup("/tmp"); + return PG(php_sys_temp_dir); #endif } @@ -272,7 +249,7 @@ PHPAPI const char* php_get_temporary_directory(TSRMLS_D) * This function should do its best to return a file pointer to a newly created * unique file, on every platform. */ -PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, zend_bool open_basedir_check TSRMLS_DC) +PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, zend_string **opened_path_p, zend_bool open_basedir_check) { int fd; const char *temp_dir; @@ -286,17 +263,17 @@ PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **ope if (!dir || *dir == '\0') { def_tmp: - temp_dir = php_get_temporary_directory(TSRMLS_C); + temp_dir = php_get_temporary_directory(); - if (temp_dir && *temp_dir != '\0' && (!open_basedir_check || !php_check_open_basedir(temp_dir TSRMLS_CC))) { - return php_do_open_temporary_file(temp_dir, pfx, opened_path_p TSRMLS_CC); + if (temp_dir && *temp_dir != '\0' && (!open_basedir_check || !php_check_open_basedir(temp_dir))) { + return php_do_open_temporary_file(temp_dir, pfx, opened_path_p); } else { return -1; } } /* Try the directory given as parameter. */ - fd = php_do_open_temporary_file(dir, pfx, opened_path_p TSRMLS_CC); + fd = php_do_open_temporary_file(dir, pfx, opened_path_p); if (fd == -1) { /* Use default temporary directory. */ goto def_tmp; @@ -304,15 +281,15 @@ def_tmp: return fd; } -PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC) +PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, zend_string **opened_path_p) { - return php_open_temporary_fd_ex(dir, pfx, opened_path_p, 0 TSRMLS_CC); + return php_open_temporary_fd_ex(dir, pfx, opened_path_p, 0); } -PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC) +PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, zend_string **opened_path_p) { FILE *fp; - int fd = php_open_temporary_fd(dir, pfx, opened_path_p TSRMLS_CC); + int fd = php_open_temporary_fd(dir, pfx, opened_path_p); if (fd == -1) { return NULL; diff --git a/main/php_open_temporary_file.h b/main/php_open_temporary_file.h index 6b822feb06..3d45fbe332 100644 --- a/main/php_open_temporary_file.h +++ b/main/php_open_temporary_file.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -22,11 +22,10 @@ #define PHP_OPEN_TEMPORARY_FILE_H BEGIN_EXTERN_C() -PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC); -PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, zend_bool open_basedir_check TSRMLS_DC); -PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC); -PHPAPI const char *php_get_temporary_directory(TSRMLS_D); -PHPAPI void php_shutdown_temporary_directory(void); +PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, zend_string **opened_path_p); +PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, zend_string **opened_path_p, zend_bool open_basedir_check); +PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, zend_string **opened_path_p); +PHPAPI const char *php_get_temporary_directory(void); END_EXTERN_C() #endif /* PHP_OPEN_TEMPORARY_FILE_H */ diff --git a/main/php_output.h b/main/php_output.h index 923385d04b..6bb89a7458 100644 --- a/main/php_output.h +++ b/main/php_output.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -95,48 +95,42 @@ typedef struct _php_output_buffer { size_t size; size_t used; uint free:1; - uint _res:31; + uint _reserved:31; } php_output_buffer; typedef struct _php_output_context { int op; php_output_buffer in; php_output_buffer out; -#ifdef ZTS - void ***tsrm_ls; -#endif } php_output_context; -#define PHP_OUTPUT_TSRMLS(ctx) TSRMLS_FETCH_FROM_CTX((ctx)->tsrm_ls) - /* old-style, stateless callback */ -typedef void (*php_output_handler_func_t)(char *output, uint output_len, char **handled_output, uint *handled_output_len, int mode TSRMLS_DC); +typedef void (*php_output_handler_func_t)(char *output, size_t output_len, char **handled_output, size_t *handled_output_len, int mode); /* new-style, opaque context callback */ typedef int (*php_output_handler_context_func_t)(void **handler_context, php_output_context *output_context); /* output handler context dtor */ -typedef void (*php_output_handler_context_dtor_t)(void *opaq TSRMLS_DC); +typedef void (*php_output_handler_context_dtor_t)(void *opaq); /* conflict check callback */ -typedef int (*php_output_handler_conflict_check_t)(const char *handler_name, size_t handler_name_len TSRMLS_DC); +typedef int (*php_output_handler_conflict_check_t)(const char *handler_name, size_t handler_name_len); /* ctor for aliases */ -typedef struct _php_output_handler *(*php_output_handler_alias_ctor_t)(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags TSRMLS_DC); +typedef struct _php_output_handler *(*php_output_handler_alias_ctor_t)(const char *handler_name, size_t handler_name_len, size_t chunk_size, int flags); typedef struct _php_output_handler_user_func_t { zend_fcall_info fci; zend_fcall_info_cache fcc; - zval *zoh; + zval zoh; } php_output_handler_user_func_t; typedef struct _php_output_handler { - char *name; - size_t name_len; + zend_string *name; int flags; int level; size_t size; php_output_buffer buffer; - + void *opaq; - void (*dtor)(void *opaq TSRMLS_DC); - + void (*dtor)(void *opaq); + union { php_output_handler_user_func_t *user; php_output_handler_context_func_t internal; @@ -144,37 +138,37 @@ typedef struct _php_output_handler { } php_output_handler; ZEND_BEGIN_MODULE_GLOBALS(output) - int flags; zend_stack handlers; php_output_handler *active; php_output_handler *running; const char *output_start_filename; int output_start_lineno; + int flags; ZEND_END_MODULE_GLOBALS(output) PHPAPI ZEND_EXTERN_MODULE_GLOBALS(output); /* there should not be a need to use OG() from outside of output.c */ #ifdef ZTS -# define OG(v) TSRMG(output_globals_id, zend_output_globals *, v) +# define OG(v) ZEND_TSRMG(output_globals_id, zend_output_globals *, v) #else # define OG(v) (output_globals.v) #endif /* convenience macros */ -#define PHPWRITE(str, str_len) php_output_write((str), (str_len) TSRMLS_CC) -#define PHPWRITE_H(str, str_len) php_output_write_unbuffered((str), (str_len) TSRMLS_CC) +#define PHPWRITE(str, str_len) php_output_write((str), (str_len)) +#define PHPWRITE_H(str, str_len) php_output_write_unbuffered((str), (str_len)) -#define PUTC(c) (php_output_write(&(c), 1 TSRMLS_CC), (c)) -#define PUTC_H(c) (php_output_write_unbuffered(&(c), 1 TSRMLS_CC), (c)) +#define PUTC(c) (php_output_write((const char *) &(c), 1), (c)) +#define PUTC_H(c) (php_output_write_unbuffered((const char *) &(c), 1), (c)) #define PUTS(str) do { \ const char *__str = (str); \ - php_output_write(__str, strlen(__str) TSRMLS_CC); \ + php_output_write(__str, strlen(__str)); \ } while (0) #define PUTS_H(str) do { \ const char *__str = (str); \ - php_output_write_unbuffered(__str, strlen(__str) TSRMLS_CC); \ + php_output_write_unbuffered(__str, strlen(__str)); \ } while (0) @@ -185,10 +179,10 @@ extern const char php_output_devnull_handler_name[sizeof("null output handler")] #define php_output_tearup() \ php_output_startup(); \ - php_output_activate(TSRMLS_C) + php_output_activate() #define php_output_teardown() \ - php_output_end_all(TSRMLS_C); \ - php_output_deactivate(TSRMLS_C); \ + php_output_end_all(); \ + php_output_deactivate(); \ php_output_shutdown() /* MINIT */ @@ -196,58 +190,58 @@ PHPAPI void php_output_startup(void); /* MSHUTDOWN */ PHPAPI void php_output_shutdown(void); -PHPAPI void php_output_register_constants(TSRMLS_D); +PHPAPI void php_output_register_constants(void); /* RINIT */ -PHPAPI int php_output_activate(TSRMLS_D); +PHPAPI int php_output_activate(void); /* RSHUTDOWN */ -PHPAPI void php_output_deactivate(TSRMLS_D); - -PHPAPI void php_output_set_status(int status TSRMLS_DC); -PHPAPI int php_output_get_status(TSRMLS_D); -PHPAPI void php_output_set_implicit_flush(int flush TSRMLS_DC); -PHPAPI const char *php_output_get_start_filename(TSRMLS_D); -PHPAPI int php_output_get_start_lineno(TSRMLS_D); - -PHPAPI int php_output_write_unbuffered(const char *str, size_t len TSRMLS_DC); -PHPAPI int php_output_write(const char *str, size_t len TSRMLS_DC); - -PHPAPI int php_output_flush(TSRMLS_D); -PHPAPI void php_output_flush_all(TSRMLS_D); -PHPAPI int php_output_clean(TSRMLS_D); -PHPAPI void php_output_clean_all(TSRMLS_D); -PHPAPI int php_output_end(TSRMLS_D); -PHPAPI void php_output_end_all(TSRMLS_D); -PHPAPI int php_output_discard(TSRMLS_D); -PHPAPI void php_output_discard_all(TSRMLS_D); - -PHPAPI int php_output_get_contents(zval *p TSRMLS_DC); -PHPAPI int php_output_get_length(zval *p TSRMLS_DC); -PHPAPI int php_output_get_level(TSRMLS_D); -PHPAPI php_output_handler* php_output_get_active_handler(TSRMLS_D); - -PHPAPI int php_output_start_default(TSRMLS_D); -PHPAPI int php_output_start_devnull(TSRMLS_D); - -PHPAPI int php_output_start_user(zval *output_handler, size_t chunk_size, int flags TSRMLS_DC); -PHPAPI int php_output_start_internal(const char *name, size_t name_len, php_output_handler_func_t output_handler, size_t chunk_size, int flags TSRMLS_DC); - -PHPAPI php_output_handler *php_output_handler_create_user(zval *handler, size_t chunk_size, int flags TSRMLS_DC); -PHPAPI php_output_handler *php_output_handler_create_internal(const char *name, size_t name_len, php_output_handler_context_func_t handler, size_t chunk_size, int flags TSRMLS_DC); - -PHPAPI void php_output_handler_set_context(php_output_handler *handler, void *opaq, void (*dtor)(void* TSRMLS_DC) TSRMLS_DC); -PHPAPI int php_output_handler_start(php_output_handler *handler TSRMLS_DC); -PHPAPI int php_output_handler_started(const char *name, size_t name_len TSRMLS_DC); -PHPAPI int php_output_handler_hook(php_output_handler_hook_t type, void *arg TSRMLS_DC); -PHPAPI void php_output_handler_dtor(php_output_handler *handler TSRMLS_DC); -PHPAPI void php_output_handler_free(php_output_handler **handler TSRMLS_DC); - -PHPAPI int php_output_handler_conflict(const char *handler_new, size_t handler_new_len, const char *handler_set, size_t handler_set_len TSRMLS_DC); -PHPAPI int php_output_handler_conflict_register(const char *handler_name, size_t handler_name_len, php_output_handler_conflict_check_t check_func TSRMLS_DC); -PHPAPI int php_output_handler_reverse_conflict_register(const char *handler_name, size_t handler_name_len, php_output_handler_conflict_check_t check_func TSRMLS_DC); - -PHPAPI php_output_handler_alias_ctor_t *php_output_handler_alias(const char *handler_name, size_t handler_name_len TSRMLS_DC); -PHPAPI int php_output_handler_alias_register(const char *handler_name, size_t handler_name_len, php_output_handler_alias_ctor_t func TSRMLS_DC); +PHPAPI void php_output_deactivate(void); + +PHPAPI void php_output_set_status(int status); +PHPAPI int php_output_get_status(void); +PHPAPI void php_output_set_implicit_flush(int flush); +PHPAPI const char *php_output_get_start_filename(void); +PHPAPI int php_output_get_start_lineno(void); + +PHPAPI size_t php_output_write_unbuffered(const char *str, size_t len); +PHPAPI size_t php_output_write(const char *str, size_t len); + +PHPAPI int php_output_flush(void); +PHPAPI void php_output_flush_all(void); +PHPAPI int php_output_clean(void); +PHPAPI void php_output_clean_all(void); +PHPAPI int php_output_end(void); +PHPAPI void php_output_end_all(void); +PHPAPI int php_output_discard(void); +PHPAPI void php_output_discard_all(void); + +PHPAPI int php_output_get_contents(zval *p); +PHPAPI int php_output_get_length(zval *p); +PHPAPI int php_output_get_level(void); +PHPAPI php_output_handler* php_output_get_active_handler(void); + +PHPAPI int php_output_start_default(void); +PHPAPI int php_output_start_devnull(void); + +PHPAPI int php_output_start_user(zval *output_handler, size_t chunk_size, int flags); +PHPAPI int php_output_start_internal(const char *name, size_t name_len, php_output_handler_func_t output_handler, size_t chunk_size, int flags); + +PHPAPI php_output_handler *php_output_handler_create_user(zval *handler, size_t chunk_size, int flags); +PHPAPI php_output_handler *php_output_handler_create_internal(const char *name, size_t name_len, php_output_handler_context_func_t handler, size_t chunk_size, int flags); + +PHPAPI void php_output_handler_set_context(php_output_handler *handler, void *opaq, void (*dtor)(void*)); +PHPAPI int php_output_handler_start(php_output_handler *handler); +PHPAPI int php_output_handler_started(const char *name, size_t name_len); +PHPAPI int php_output_handler_hook(php_output_handler_hook_t type, void *arg); +PHPAPI void php_output_handler_dtor(php_output_handler *handler); +PHPAPI void php_output_handler_free(php_output_handler **handler); + +PHPAPI int php_output_handler_conflict(const char *handler_new, size_t handler_new_len, const char *handler_set, size_t handler_set_len); +PHPAPI int php_output_handler_conflict_register(const char *handler_name, size_t handler_name_len, php_output_handler_conflict_check_t check_func); +PHPAPI int php_output_handler_reverse_conflict_register(const char *handler_name, size_t handler_name_len, php_output_handler_conflict_check_t check_func); + +PHPAPI php_output_handler_alias_ctor_t php_output_handler_alias(const char *handler_name, size_t handler_name_len); +PHPAPI int php_output_handler_alias_register(const char *handler_name, size_t handler_name_len, php_output_handler_alias_ctor_t func); END_EXTERN_C() diff --git a/main/php_reentrancy.h b/main/php_reentrancy.h index 80c2fe0c20..2240d634a1 100644 --- a/main/php_reentrancy.h +++ b/main/php_reentrancy.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -130,4 +130,4 @@ void reentrancy_shutdown(void); #define reentrancy_shutdown() #endif -#endif +#endif diff --git a/main/php_scandir.c b/main/php_scandir.c index bd87c64aca..67bb25696c 100644 --- a/main/php_scandir.c +++ b/main/php_scandir.c @@ -1,6 +1,6 @@ -/* +/* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -35,7 +35,7 @@ #ifdef PHP_WIN32 #include "win32/param.h" #include "win32/readdir.h" -#endif +#endif #include <stdlib.h> #ifndef NETWARE @@ -86,7 +86,7 @@ PHPAPI int php_scandir(const char *dirname, struct dirent **namelist[], int (*se struct dirent **newv; if (vector_size == 0) { vector_size = 10; - } else { + } else { vector_size *= 2; } @@ -97,7 +97,7 @@ PHPAPI int php_scandir(const char *dirname, struct dirent **namelist[], int (*se vector = newv; } - dsize = sizeof (struct dirent) + ((strlen(dp->d_name) + 1) * sizeof(char)); + dsize = sizeof (struct dirent) + (((int)strlen(dp->d_name) + 1) * sizeof(char)); newdp = (struct dirent *) malloc(dsize); if (newdp == NULL) { @@ -112,7 +112,7 @@ PHPAPI int php_scandir(const char *dirname, struct dirent **namelist[], int (*se *namelist = vector; if (compare) { - qsort (*namelist, nfiles, sizeof(struct dirent *), compare); + qsort (*namelist, nfiles, sizeof(struct dirent *), (int (*) (const void *, const void *)) compare); } return nfiles; @@ -122,7 +122,7 @@ fail: free(vector[nfiles]); } free(vector); - return -1; + return -1; } #endif diff --git a/main/php_scandir.h b/main/php_scandir.h index 9a087d3dc1..cd473a0262 100644 --- a/main/php_scandir.h +++ b/main/php_scandir.h @@ -1,6 +1,6 @@ -/* +/* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ diff --git a/main/php_sprintf.c b/main/php_sprintf.c index 0f133b01af..3eecffa770 100644 --- a/main/php_sprintf.c +++ b/main/php_sprintf.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ diff --git a/main/php_stdint.h b/main/php_stdint.h index 796dc4d4f4..71f7493a6a 100644 --- a/main/php_stdint.h +++ b/main/php_stdint.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -19,6 +19,25 @@ #ifndef PHP_STDINT_H #define PHP_STDINT_H +/* C99 requires these for C++ to get the definitions + * of INT64_MAX and other macros used by Zend/zend_long.h + * C11 drops this requirement, so these effectively + * just backport that piece of behavior. + * + * These defines are placed here instead of + * with the include below, because sys/types + * and inttypes may include stdint themselves. + * And these definitions MUST come first. + */ +#ifdef __cplusplus +# ifndef __STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS +# endif +# ifndef __STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS +# endif +#endif + #if defined(_MSC_VER) /* Make sure the regular stdint.h wasn't included already and prevent it to be included afterwards. Though if some other library needs some stuff from @@ -28,6 +47,7 @@ # if !defined(_STDINT) # define _STDINT # include "win32/php_stdint.h" +# include "win32/php_inttypes.h" # endif # define HAVE_INT8_T 1 # define HAVE_UINT8_T 1 diff --git a/main/php_streams.h b/main/php_streams.h index 4da2dce98e..255b065bd4 100644 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -26,6 +26,8 @@ #endif #include <sys/types.h> #include <sys/stat.h> +#include "zend.h" +#include "zend_stream.h" BEGIN_EXTERN_C() PHPAPI int php_file_le_stream(void); @@ -59,27 +61,27 @@ END_EXTERN_C() /* these functions relay the file/line number information. They are depth aware, so they will pass * the ultimate ancestor, which is useful, because there can be several layers of calls */ -#define php_stream_alloc_rel(ops, thisptr, persistent, mode) _php_stream_alloc((ops), (thisptr), (persistent), (mode) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_alloc_rel(ops, thisptr, persistent, mode) _php_stream_alloc((ops), (thisptr), (persistent), (mode) STREAMS_REL_CC) -#define php_stream_copy_to_mem_rel(src, buf, maxlen, persistent) _php_stream_copy_to_mem((src), (buf), (maxlen), (persistent) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_copy_to_mem_rel(src, maxlen, persistent) _php_stream_copy_to_mem((src), (buf), (maxlen), (persistent) STREAMS_REL_CC) -#define php_stream_fopen_rel(filename, mode, opened, options) _php_stream_fopen((filename), (mode), (opened), (options) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_fopen_rel(filename, mode, opened, options) _php_stream_fopen((filename), (mode), (opened), (options) STREAMS_REL_CC) -#define php_stream_fopen_with_path_rel(filename, mode, path, opened, options) _php_stream_fopen_with_path((filename), (mode), (path), (opened), (options) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_fopen_with_path_rel(filename, mode, path, opened, options) _php_stream_fopen_with_path((filename), (mode), (path), (opened), (options) STREAMS_REL_CC) -#define php_stream_fopen_from_fd_rel(fd, mode, persistent_id) _php_stream_fopen_from_fd((fd), (mode), (persistent_id) STREAMS_REL_CC TSRMLS_CC) -#define php_stream_fopen_from_file_rel(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_fopen_from_fd_rel(fd, mode, persistent_id) _php_stream_fopen_from_fd((fd), (mode), (persistent_id) STREAMS_REL_CC) +#define php_stream_fopen_from_file_rel(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_REL_CC) -#define php_stream_fopen_from_pipe_rel(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_fopen_from_pipe_rel(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_REL_CC) -#define php_stream_fopen_tmpfile_rel() _php_stream_fopen_tmpfile(0 STREAMS_REL_CC TSRMLS_CC) +#define php_stream_fopen_tmpfile_rel() _php_stream_fopen_tmpfile(0 STREAMS_REL_CC) -#define php_stream_fopen_temporary_file_rel(dir, pfx, opened_path) _php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_fopen_temporary_file_rel(dir, pfx, opened_path) _php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_REL_CC) -#define php_stream_open_wrapper_rel(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_REL_CC TSRMLS_CC) -#define php_stream_open_wrapper_ex_rel(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_open_wrapper_rel(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_REL_CC) +#define php_stream_open_wrapper_ex_rel(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_REL_CC) -#define php_stream_make_seekable_rel(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_make_seekable_rel(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_REL_CC) /* }}} */ @@ -104,7 +106,7 @@ typedef struct _php_stream_filter php_stream_filter; #include "streams/php_stream_filter_api.h" typedef struct _php_stream_statbuf { - struct stat sb; /* regular info */ + zend_stat_t sb; /* regular info */ /* extended info to go here some day: content-type etc. etc. */ } php_stream_statbuf; @@ -115,47 +117,47 @@ typedef struct _php_stream_dirent { /* operations on streams that are file-handles */ typedef struct _php_stream_ops { /* stdio like functions - these are mandatory! */ - size_t (*write)(php_stream *stream, const char *buf, size_t count TSRMLS_DC); - size_t (*read)(php_stream *stream, char *buf, size_t count TSRMLS_DC); - int (*close)(php_stream *stream, int close_handle TSRMLS_DC); - int (*flush)(php_stream *stream TSRMLS_DC); + size_t (*write)(php_stream *stream, const char *buf, size_t count); + size_t (*read)(php_stream *stream, char *buf, size_t count); + int (*close)(php_stream *stream, int close_handle); + int (*flush)(php_stream *stream); const char *label; /* label for this ops structure */ /* these are optional */ - int (*seek)(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC); - int (*cast)(php_stream *stream, int castas, void **ret TSRMLS_DC); - int (*stat)(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); - int (*set_option)(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); + int (*seek)(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset); + int (*cast)(php_stream *stream, int castas, void **ret); + int (*stat)(php_stream *stream, php_stream_statbuf *ssb); + int (*set_option)(php_stream *stream, int option, int value, void *ptrparam); } php_stream_ops; typedef struct _php_stream_wrapper_ops { /* open/create a wrapped stream */ php_stream *(*stream_opener)(php_stream_wrapper *wrapper, const char *filename, const char *mode, - int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); + int options, zend_string **opened_path, php_stream_context *context STREAMS_DC); /* close/destroy a wrapped stream */ - int (*stream_closer)(php_stream_wrapper *wrapper, php_stream *stream TSRMLS_DC); + int (*stream_closer)(php_stream_wrapper *wrapper, php_stream *stream); /* stat a wrapped stream */ - int (*stream_stat)(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); + int (*stream_stat)(php_stream_wrapper *wrapper, php_stream *stream, php_stream_statbuf *ssb); /* stat a URL */ - int (*url_stat)(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); + int (*url_stat)(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context); /* open a "directory" stream */ php_stream *(*dir_opener)(php_stream_wrapper *wrapper, const char *filename, const char *mode, - int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); + int options, zend_string **opened_path, php_stream_context *context STREAMS_DC); const char *label; /* delete a file */ - int (*unlink)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); + int (*unlink)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context); /* rename a file */ - int (*rename)(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC); + int (*rename)(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context); /* Create/Remove directory */ - int (*stream_mkdir)(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context TSRMLS_DC); - int (*stream_rmdir)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); + int (*stream_mkdir)(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context); + int (*stream_rmdir)(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context); /* Metadata handling */ - int (*stream_metadata)(php_stream_wrapper *wrapper, const char *url, int options, void *value, php_stream_context *context TSRMLS_DC); + int (*stream_metadata)(php_stream_wrapper *wrapper, const char *url, int options, void *value, php_stream_context *context); } php_stream_wrapper_ops; struct _php_stream_wrapper { @@ -164,24 +166,26 @@ struct _php_stream_wrapper { int is_url; /* so that PG(allow_url_fopen) can be respected */ }; -#define PHP_STREAM_FLAG_NO_SEEK 1 -#define PHP_STREAM_FLAG_NO_BUFFER 2 +#define PHP_STREAM_FLAG_NO_SEEK 0x1 +#define PHP_STREAM_FLAG_NO_BUFFER 0x2 -#define PHP_STREAM_FLAG_EOL_UNIX 0 /* also includes DOS */ -#define PHP_STREAM_FLAG_DETECT_EOL 4 -#define PHP_STREAM_FLAG_EOL_MAC 8 +#define PHP_STREAM_FLAG_EOL_UNIX 0x0 /* also includes DOS */ +#define PHP_STREAM_FLAG_DETECT_EOL 0x4 +#define PHP_STREAM_FLAG_EOL_MAC 0x8 /* set this when the stream might represent "interactive" data. * When set, the read buffer will avoid certain operations that * might otherwise cause the read to block for much longer than * is strictly required. */ -#define PHP_STREAM_FLAG_AVOID_BLOCKING 16 +#define PHP_STREAM_FLAG_AVOID_BLOCKING 0x10 -#define PHP_STREAM_FLAG_NO_CLOSE 32 +#define PHP_STREAM_FLAG_NO_CLOSE 0x20 -#define PHP_STREAM_FLAG_IS_DIR 64 +#define PHP_STREAM_FLAG_IS_DIR 0x40 -#define PHP_STREAM_FLAG_NO_FCLOSE 128 +#define PHP_STREAM_FLAG_NO_FCLOSE 0x80 + +#define PHP_STREAM_FLAG_WAS_WRITTEN 0x80000000 struct _php_stream { php_stream_ops *ops; @@ -191,37 +195,35 @@ struct _php_stream { php_stream_wrapper *wrapper; /* which wrapper was used to open the stream */ void *wrapperthis; /* convenience pointer for a instance of a wrapper */ - zval *wrapperdata; /* fgetwrapperdata retrieves this */ + zval wrapperdata; /* fgetwrapperdata retrieves this */ int fgetss_state; /* for fgetss to handle multiline tags */ int is_persistent; char mode[16]; /* "rwb" etc. ala stdio */ - int rsrc_id; /* used for auto-cleanup */ + zend_resource *res; /* used for auto-cleanup */ int in_free; /* to prevent recursion during free */ /* so we know how to clean it up correctly. This should be set to * PHP_STREAM_FCLOSE_XXX as appropriate */ int fclose_stdiocast; FILE *stdiocast; /* cache this, otherwise we might leak! */ -#if ZEND_DEBUG int __exposed; /* non-zero if exposed as a zval somewhere */ -#endif char *orig_path; - php_stream_context *context; + zend_resource *ctx; int flags; /* PHP_STREAM_FLAG_XXX */ + int eof; + /* buffer */ - off_t position; /* of underlying stream */ + zend_off_t position; /* of underlying stream */ unsigned char *readbuf; size_t readbuflen; - off_t readpos; - off_t writepos; + zend_off_t readpos; + zend_off_t writepos; /* how much data to read when filling buffer */ size_t chunk_size; - int eof; - #if ZEND_DEBUG const char *open_filename; uint open_lineno; @@ -230,6 +232,9 @@ struct _php_stream { struct _php_stream *enclosing_stream; /* this is a private stream owned by enclosing_stream */ }; /* php_stream */ +#define PHP_STREAM_CONTEXT(stream) \ + ((php_stream_context*) ((stream)->ctx ? ((stream)->ctx->ptr) : NULL)) + /* state definitions when closing down; these are private to streams.c */ #define PHP_STREAM_FCLOSE_NONE 0 #define PHP_STREAM_FCLOSE_FDOPEN 1 @@ -238,32 +243,39 @@ struct _php_stream { /* allocate a new stream for a particular ops */ BEGIN_EXTERN_C() PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, - const char *persistent_id, const char *mode STREAMS_DC TSRMLS_DC); + const char *persistent_id, const char *mode STREAMS_DC); END_EXTERN_C() -#define php_stream_alloc(ops, thisptr, persistent_id, mode) _php_stream_alloc((ops), (thisptr), (persistent_id), (mode) STREAMS_CC TSRMLS_CC) +#define php_stream_alloc(ops, thisptr, persistent_id, mode) _php_stream_alloc((ops), (thisptr), (persistent_id), (mode) STREAMS_CC) -#define php_stream_get_resource_id(stream) ((php_stream *)(stream))->rsrc_id -#if ZEND_DEBUG +#define php_stream_get_resource_id(stream) ((php_stream *)(stream))->res->handle /* use this to tell the stream that it is OK if we don't explicitly close it */ -# define php_stream_auto_cleanup(stream) { (stream)->__exposed++; } +#define php_stream_auto_cleanup(stream) { (stream)->__exposed++; } /* use this to assign the stream to a zval and tell the stream that is * has been exported to the engine; it will expect to be closed automatically * when the resources are auto-destructed */ -# define php_stream_to_zval(stream, zval) { ZVAL_RESOURCE(zval, (stream)->rsrc_id); (stream)->__exposed++; } -#else -# define php_stream_auto_cleanup(stream) /* nothing */ -# define php_stream_to_zval(stream, zval) { ZVAL_RESOURCE(zval, (stream)->rsrc_id); } -#endif - -#define php_stream_from_zval(xstr, ppzval) ZEND_FETCH_RESOURCE2((xstr), php_stream *, (ppzval), -1, "stream", php_file_le_stream(), php_file_le_pstream()) -#define php_stream_from_zval_no_verify(xstr, ppzval) (xstr) = (php_stream*)zend_fetch_resource((ppzval) TSRMLS_CC, -1, "stream", NULL, 2, php_file_le_stream(), php_file_le_pstream()) +#define php_stream_to_zval(stream, zval) { ZVAL_RES(zval, (stream)->res); (stream)->__exposed++; } + +#define php_stream_from_zval(xstr, pzval) do { \ + if (((xstr) = (php_stream*)zend_fetch_resource2_ex((pzval), \ + "stream", php_file_le_stream(), php_file_le_pstream())) == NULL) { \ + RETURN_FALSE; \ + } \ +} while (0) +#define php_stream_from_res(xstr, res) do { \ + if (((xstr) = (php_stream*)zend_fetch_resource2((res), \ + "stream", php_file_le_stream(), php_file_le_pstream())) == NULL) { \ + RETURN_FALSE; \ + } \ +} while (0) +#define php_stream_from_res_no_verify(xstr, pzval) (xstr) = (php_stream*)zend_fetch_resource((res), "stream", php_file_le_stream(), php_file_le_pstream()) +#define php_stream_from_zval_no_verify(xstr, pzval) (xstr) = (php_stream*)zend_fetch_resource2_ex((pzval), "stream", php_file_le_stream(), php_file_le_pstream()) BEGIN_EXTERN_C() PHPAPI php_stream *php_stream_encloses(php_stream *enclosing, php_stream *enclosed); -#define php_stream_free_enclosed(stream_enclosed, close_options) _php_stream_free_enclosed((stream_enclosed), (close_options) TSRMLS_CC) -PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options TSRMLS_DC); +#define php_stream_free_enclosed(stream_enclosed, close_options) _php_stream_free_enclosed((stream_enclosed), (close_options)) +PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options); -PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC); +PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream); #define PHP_STREAM_PERSISTENT_SUCCESS 0 /* id exists */ #define PHP_STREAM_PERSISTENT_FAILURE 1 /* id exists but is not a stream! */ #define PHP_STREAM_PERSISTENT_NOT_EXIST 2 /* id does not exist */ @@ -274,94 +286,95 @@ PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream * #define PHP_STREAM_FREE_RSRC_DTOR 8 /* called from the resource list dtor */ #define PHP_STREAM_FREE_PERSISTENT 16 /* manually freeing a persistent connection */ #define PHP_STREAM_FREE_IGNORE_ENCLOSING 32 /* don't close the enclosing stream instead */ +#define PHP_STREAM_FREE_KEEP_RSRC 64 /* keep associated zend_resource */ #define PHP_STREAM_FREE_CLOSE (PHP_STREAM_FREE_CALL_DTOR | PHP_STREAM_FREE_RELEASE_STREAM) #define PHP_STREAM_FREE_CLOSE_CASTED (PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_PRESERVE_HANDLE) #define PHP_STREAM_FREE_CLOSE_PERSISTENT (PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_PERSISTENT) -PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC); -#define php_stream_free(stream, close_options) _php_stream_free((stream), (close_options) TSRMLS_CC) -#define php_stream_close(stream) _php_stream_free((stream), PHP_STREAM_FREE_CLOSE TSRMLS_CC) -#define php_stream_pclose(stream) _php_stream_free((stream), PHP_STREAM_FREE_CLOSE_PERSISTENT TSRMLS_CC) +PHPAPI int _php_stream_free(php_stream *stream, int close_options); +#define php_stream_free(stream, close_options) _php_stream_free((stream), (close_options)) +#define php_stream_close(stream) _php_stream_free((stream), PHP_STREAM_FREE_CLOSE) +#define php_stream_pclose(stream) _php_stream_free((stream), PHP_STREAM_FREE_CLOSE_PERSISTENT) -PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC); -#define php_stream_rewind(stream) _php_stream_seek((stream), 0L, SEEK_SET TSRMLS_CC) -#define php_stream_seek(stream, offset, whence) _php_stream_seek((stream), (offset), (whence) TSRMLS_CC) +PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence); +#define php_stream_rewind(stream) _php_stream_seek((stream), 0L, SEEK_SET) +#define php_stream_seek(stream, offset, whence) _php_stream_seek((stream), (offset), (whence)) -PHPAPI off_t _php_stream_tell(php_stream *stream TSRMLS_DC); -#define php_stream_tell(stream) _php_stream_tell((stream) TSRMLS_CC) +PHPAPI zend_off_t _php_stream_tell(php_stream *stream); +#define php_stream_tell(stream) _php_stream_tell((stream)) -PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC); -#define php_stream_read(stream, buf, count) _php_stream_read((stream), (buf), (count) TSRMLS_CC) +PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t count); +#define php_stream_read(stream, buf, count) _php_stream_read((stream), (buf), (count)) -PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC); -#define php_stream_write_string(stream, str) _php_stream_write(stream, str, strlen(str) TSRMLS_CC) -#define php_stream_write(stream, buf, count) _php_stream_write(stream, (buf), (count) TSRMLS_CC) +PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count); +#define php_stream_write_string(stream, str) _php_stream_write(stream, str, strlen(str)) +#define php_stream_write(stream, buf, count) _php_stream_write(stream, (buf), (count)) -PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_DC); -#define php_stream_fill_read_buffer(stream, size) _php_stream_fill_read_buffer((stream), (size) TSRMLS_CC) +PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size); +#define php_stream_fill_read_buffer(stream, size) _php_stream_fill_read_buffer((stream), (size)) #ifdef ZTS -PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); +PHPAPI size_t _php_stream_printf(php_stream *stream, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); #else -PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); +PHPAPI size_t _php_stream_printf(php_stream *stream, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); #endif -/* php_stream_printf macro & function require TSRMLS_CC */ +/* php_stream_printf macro & function require */ #define php_stream_printf _php_stream_printf -PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC); -#define php_stream_eof(stream) _php_stream_eof((stream) TSRMLS_CC) +PHPAPI int _php_stream_eof(php_stream *stream); +#define php_stream_eof(stream) _php_stream_eof((stream)) -PHPAPI int _php_stream_getc(php_stream *stream TSRMLS_DC); -#define php_stream_getc(stream) _php_stream_getc((stream) TSRMLS_CC) +PHPAPI int _php_stream_getc(php_stream *stream); +#define php_stream_getc(stream) _php_stream_getc((stream)) -PHPAPI int _php_stream_putc(php_stream *stream, int c TSRMLS_DC); -#define php_stream_putc(stream, c) _php_stream_putc((stream), (c) TSRMLS_CC) +PHPAPI int _php_stream_putc(php_stream *stream, int c); +#define php_stream_putc(stream, c) _php_stream_putc((stream), (c)) -PHPAPI int _php_stream_flush(php_stream *stream, int closing TSRMLS_DC); -#define php_stream_flush(stream) _php_stream_flush((stream), 0 TSRMLS_CC) +PHPAPI int _php_stream_flush(php_stream *stream, int closing); +#define php_stream_flush(stream) _php_stream_flush((stream), 0) -PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, size_t *returned_len TSRMLS_DC); -#define php_stream_gets(stream, buf, maxlen) _php_stream_get_line((stream), (buf), (maxlen), NULL TSRMLS_CC) +PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, size_t *returned_len); +#define php_stream_gets(stream, buf, maxlen) _php_stream_get_line((stream), (buf), (maxlen), NULL) -#define php_stream_get_line(stream, buf, maxlen, retlen) _php_stream_get_line((stream), (buf), (maxlen), (retlen) TSRMLS_CC) -PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *returned_len, const char *delim, size_t delim_len TSRMLS_DC); +#define php_stream_get_line(stream, buf, maxlen, retlen) _php_stream_get_line((stream), (buf), (maxlen), (retlen)) +PHPAPI zend_string *php_stream_get_record(php_stream *stream, size_t maxlen, const char *delim, size_t delim_len); /* CAREFUL! this is equivalent to puts NOT fputs! */ -PHPAPI int _php_stream_puts(php_stream *stream, const char *buf TSRMLS_DC); -#define php_stream_puts(stream, buf) _php_stream_puts((stream), (buf) TSRMLS_CC) +PHPAPI int _php_stream_puts(php_stream *stream, const char *buf); +#define php_stream_puts(stream, buf) _php_stream_puts((stream), (buf)) -PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC); -#define php_stream_stat(stream, ssb) _php_stream_stat((stream), (ssb) TSRMLS_CC) +PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb); +#define php_stream_stat(stream, ssb) _php_stream_stat((stream), (ssb)) -PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); -#define php_stream_stat_path(path, ssb) _php_stream_stat_path((path), 0, (ssb), NULL TSRMLS_CC) -#define php_stream_stat_path_ex(path, flags, ssb, context) _php_stream_stat_path((path), (flags), (ssb), (context) TSRMLS_CC) +PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context); +#define php_stream_stat_path(path, ssb) _php_stream_stat_path((path), 0, (ssb), NULL) +#define php_stream_stat_path_ex(path, flags, ssb, context) _php_stream_stat_path((path), (flags), (ssb), (context)) -PHPAPI int _php_stream_mkdir(const char *path, int mode, int options, php_stream_context *context TSRMLS_DC); -#define php_stream_mkdir(path, mode, options, context) _php_stream_mkdir(path, mode, options, context TSRMLS_CC) +PHPAPI int _php_stream_mkdir(const char *path, int mode, int options, php_stream_context *context); +#define php_stream_mkdir(path, mode, options, context) _php_stream_mkdir(path, mode, options, context) -PHPAPI int _php_stream_rmdir(const char *path, int options, php_stream_context *context TSRMLS_DC); -#define php_stream_rmdir(path, options, context) _php_stream_rmdir(path, options, context TSRMLS_CC) +PHPAPI int _php_stream_rmdir(const char *path, int options, php_stream_context *context); +#define php_stream_rmdir(path, options, context) _php_stream_rmdir(path, options, context) -PHPAPI php_stream *_php_stream_opendir(const char *path, int options, php_stream_context *context STREAMS_DC TSRMLS_DC); -#define php_stream_opendir(path, options, context) _php_stream_opendir((path), (options), (context) STREAMS_CC TSRMLS_CC) -PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent TSRMLS_DC); -#define php_stream_readdir(dirstream, dirent) _php_stream_readdir((dirstream), (dirent) TSRMLS_CC) +PHPAPI php_stream *_php_stream_opendir(const char *path, int options, php_stream_context *context STREAMS_DC); +#define php_stream_opendir(path, options, context) _php_stream_opendir((path), (options), (context) STREAMS_CC) +PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent); +#define php_stream_readdir(dirstream, dirent) _php_stream_readdir((dirstream), (dirent)) #define php_stream_closedir(dirstream) php_stream_close((dirstream)) #define php_stream_rewinddir(dirstream) php_stream_rewind((dirstream)) -PHPAPI int php_stream_dirent_alphasort(const char **a, const char **b); -PHPAPI int php_stream_dirent_alphasortr(const char **a, const char **b); +PHPAPI int php_stream_dirent_alphasort(const zend_string **a, const zend_string **b); +PHPAPI int php_stream_dirent_alphasortr(const zend_string **a, const zend_string **b); -PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags, php_stream_context *context, - int (*compare) (const char **a, const char **b) TSRMLS_DC); -#define php_stream_scandir(dirname, namelist, context, compare) _php_stream_scandir((dirname), (namelist), 0, (context), (compare) TSRMLS_CC) +PHPAPI int _php_stream_scandir(const char *dirname, zend_string **namelist[], int flags, php_stream_context *context, + int (*compare) (const zend_string **a, const zend_string **b)); +#define php_stream_scandir(dirname, namelist, context, compare) _php_stream_scandir((dirname), (namelist), 0, (context), (compare)) -PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); -#define php_stream_set_option(stream, option, value, ptrvalue) _php_stream_set_option((stream), (option), (value), (ptrvalue) TSRMLS_CC) +PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam); +#define php_stream_set_option(stream, option, value, ptrvalue) _php_stream_set_option((stream), (option), (value), (ptrvalue)) -#define php_stream_set_chunk_size(stream, size) _php_stream_set_option((stream), PHP_STREAM_OPTION_SET_CHUNK_SIZE, (size), NULL TSRMLS_CC) +#define php_stream_set_chunk_size(stream, size) _php_stream_set_option((stream), PHP_STREAM_OPTION_SET_CHUNK_SIZE, (size), NULL) END_EXTERN_C() @@ -397,11 +410,14 @@ END_EXTERN_C() /* set or release lock on a stream */ #define PHP_STREAM_OPTION_LOCKING 6 +/* Enable/disable blocking reads on anonymous pipes on Windows. */ +#define PHP_STREAM_OPTION_PIPE_BLOCKING 7 + /* whether or not locking is supported */ #define PHP_STREAM_LOCK_SUPPORTED 1 -#define php_stream_supports_lock(stream) _php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, 0, (void *) PHP_STREAM_LOCK_SUPPORTED TSRMLS_CC) == 0 ? 1 : 0 -#define php_stream_lock(stream, mode) _php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, (mode), (void *) NULL TSRMLS_CC) +#define php_stream_supports_lock(stream) _php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, 0, (void *) PHP_STREAM_LOCK_SUPPORTED) == 0 ? 1 : 0 +#define php_stream_lock(stream, mode) _php_stream_set_option((stream), PHP_STREAM_OPTION_LOCKING, (mode), (void *) NULL) /* option code used by the php_stream_xport_XXX api */ #define PHP_STREAM_OPTION_XPORT_API 7 /* see php_stream_transport.h */ @@ -412,15 +428,15 @@ END_EXTERN_C() #define PHP_STREAM_TRUNCATE_SUPPORTED 0 #define PHP_STREAM_TRUNCATE_SET_SIZE 1 /* ptrparam is a pointer to a size_t */ -#define php_stream_truncate_supported(stream) (_php_stream_set_option((stream), PHP_STREAM_OPTION_TRUNCATE_API, PHP_STREAM_TRUNCATE_SUPPORTED, NULL TSRMLS_CC) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0) +#define php_stream_truncate_supported(stream) (_php_stream_set_option((stream), PHP_STREAM_OPTION_TRUNCATE_API, PHP_STREAM_TRUNCATE_SUPPORTED, NULL) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0) BEGIN_EXTERN_C() -PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize TSRMLS_DC); -#define php_stream_truncate_set_size(stream, size) _php_stream_truncate_set_size((stream), (size) TSRMLS_CC) +PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize); +#define php_stream_truncate_set_size(stream, size) _php_stream_truncate_set_size((stream), (size)) END_EXTERN_C() #define PHP_STREAM_OPTION_META_DATA_API 11 /* ptrparam is a zval* to which to add meta data information */ -#define php_stream_populate_meta_data(stream, zv) (_php_stream_set_option((stream), PHP_STREAM_OPTION_META_DATA_API, 0, zv TSRMLS_CC) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0) +#define php_stream_populate_meta_data(stream, zv) (_php_stream_set_option((stream), PHP_STREAM_OPTION_META_DATA_API, 0, zv) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0) /* Check if the stream is still "live"; for sockets/pipes this means the socket * is still connected; for files, this does not really have meaning */ @@ -436,21 +452,20 @@ END_EXTERN_C() BEGIN_EXTERN_C() ZEND_ATTRIBUTE_DEPRECATED -PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC); -#define php_stream_copy_to_stream(src, dest, maxlen) _php_stream_copy_to_stream((src), (dest), (maxlen) STREAMS_CC TSRMLS_CC) -PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC); -#define php_stream_copy_to_stream_ex(src, dest, maxlen, len) _php_stream_copy_to_stream_ex((src), (dest), (maxlen), (len) STREAMS_CC TSRMLS_CC) +PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC); +#define php_stream_copy_to_stream(src, dest, maxlen) _php_stream_copy_to_stream((src), (dest), (maxlen) STREAMS_CC) +PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC); +#define php_stream_copy_to_stream_ex(src, dest, maxlen, len) _php_stream_copy_to_stream_ex((src), (dest), (maxlen), (len) STREAMS_CC) /* read all data from stream and put into a buffer. Caller must free buffer * when done. */ -PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen, - int persistent STREAMS_DC TSRMLS_DC); -#define php_stream_copy_to_mem(src, buf, maxlen, persistent) _php_stream_copy_to_mem((src), (buf), (maxlen), (persistent) STREAMS_CC TSRMLS_CC) +PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int persistent STREAMS_DC); +#define php_stream_copy_to_mem(src, maxlen, persistent) _php_stream_copy_to_mem((src), (maxlen), (persistent) STREAMS_CC) /* output all data from a stream */ -PHPAPI size_t _php_stream_passthru(php_stream * src STREAMS_DC TSRMLS_DC); -#define php_stream_passthru(stream) _php_stream_passthru((stream) STREAMS_CC TSRMLS_CC) +PHPAPI size_t _php_stream_passthru(php_stream * src STREAMS_DC); +#define php_stream_passthru(stream) _php_stream_passthru((stream) STREAMS_CC) END_EXTERN_C() #include "streams/php_stream_transport.h" @@ -475,11 +490,11 @@ END_EXTERN_C() #define PHP_STREAM_CAST_INTERNAL 0x20000000 /* stream cast for internal use */ #define PHP_STREAM_CAST_MASK (PHP_STREAM_CAST_TRY_HARD | PHP_STREAM_CAST_RELEASE | PHP_STREAM_CAST_INTERNAL) BEGIN_EXTERN_C() -PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err TSRMLS_DC); +PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err); END_EXTERN_C() /* use this to check if a stream can be cast into another form */ -#define php_stream_can_cast(stream, as) _php_stream_cast((stream), (as), NULL, 0 TSRMLS_CC) -#define php_stream_cast(stream, as, ret, show_err) _php_stream_cast((stream), (as), (ret), (show_err) TSRMLS_CC) +#define php_stream_can_cast(stream, as) _php_stream_cast((stream), (as), NULL, 0) +#define php_stream_cast(stream, as, ret, show_err) _php_stream_cast((stream), (as), (ret), (show_err)) /* use this to check if a stream is of a particular type: * PHPAPI int php_stream_is(php_stream *stream, php_stream_ops *ops); */ @@ -494,7 +509,6 @@ END_EXTERN_C() #define USE_PATH 0x00000001 #define IGNORE_URL 0x00000002 #define REPORT_ERRORS 0x00000008 -#define ENFORCE_SAFE_MODE 0 /* for BC only */ /* If you don't need to write to the stream, but really need to * be able to seek, use this flag in your options. */ @@ -535,25 +549,28 @@ END_EXTERN_C() /* assume the path passed in exists and is fully expanded, avoiding syscalls */ #define STREAM_ASSUME_REALPATH 0x00004000 +/* Allow blocking reads on anonymous pipes on Windows. */ +#define STREAM_USE_BLOCKING_PIPE 0x00008000 + /* Antique - no longer has meaning */ #define IGNORE_URL_WIN 0 -int php_init_stream_wrappers(int module_number TSRMLS_DC); -int php_shutdown_stream_wrappers(int module_number TSRMLS_DC); -void php_shutdown_stream_hashes(TSRMLS_D); +int php_init_stream_wrappers(int module_number); +int php_shutdown_stream_wrappers(int module_number); +void php_shutdown_stream_hashes(void); PHP_RSHUTDOWN_FUNCTION(streams); BEGIN_EXTERN_C() -PHPAPI int php_register_url_stream_wrapper(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); -PHPAPI int php_unregister_url_stream_wrapper(const char *protocol TSRMLS_DC); -PHPAPI int php_register_url_stream_wrapper_volatile(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC); -PHPAPI int php_unregister_url_stream_wrapper_volatile(const char *protocol TSRMLS_DC); -PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); -PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options TSRMLS_DC); -PHPAPI const char *php_stream_locate_eol(php_stream *stream, const char *buf, size_t buf_len TSRMLS_DC); +PHPAPI int php_register_url_stream_wrapper(const char *protocol, php_stream_wrapper *wrapper); +PHPAPI int php_unregister_url_stream_wrapper(const char *protocol); +PHPAPI int php_register_url_stream_wrapper_volatile(const char *protocol, php_stream_wrapper *wrapper); +PHPAPI int php_unregister_url_stream_wrapper_volatile(const char *protocol); +PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC); +PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options); +PHPAPI const char *php_stream_locate_eol(php_stream *stream, zend_string *buf); -#define php_stream_open_wrapper(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_CC TSRMLS_CC) -#define php_stream_open_wrapper_ex(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_CC TSRMLS_CC) +#define php_stream_open_wrapper(path, mode, options, opened) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), NULL STREAMS_CC) +#define php_stream_open_wrapper_ex(path, mode, options, opened, context) _php_stream_open_wrapper_ex((path), (mode), (options), (opened), (context) STREAMS_CC) #define php_stream_get_from_zval(stream, zstream, mode, options, opened, context) \ if (Z_TYPE_PP((zstream)) == IS_RESOURCE) { \ @@ -563,9 +580,9 @@ PHPAPI const char *php_stream_locate_eol(php_stream *stream, const char *buf, si /* pushes an error message onto the stack for a wrapper instance */ #ifdef ZTS -PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 4, 5); +PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 4, 5); #else -PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); +PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options, const char *fmt, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); #endif #define PHP_STREAM_UNCHANGED 0 /* orig stream was seekable anyway */ @@ -576,15 +593,15 @@ PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int option #define PHP_STREAM_PREFER_STDIO 1 #define PHP_STREAM_FORCE_CONVERSION 2 /* DO NOT call this on streams that are referenced by resources! */ -PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC TSRMLS_DC); -#define php_stream_make_seekable(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_CC TSRMLS_CC) +PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC); +#define php_stream_make_seekable(origstream, newstream, flags) _php_stream_make_seekable((origstream), (newstream), (flags) STREAMS_CC) /* Give other modules access to the url_stream_wrappers_hash and stream_filters_hash */ -PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(TSRMLS_D); -#define php_stream_get_url_stream_wrappers_hash() _php_stream_get_url_stream_wrappers_hash(TSRMLS_C) +PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(void); +#define php_stream_get_url_stream_wrappers_hash() _php_stream_get_url_stream_wrappers_hash() PHPAPI HashTable *php_stream_get_url_stream_wrappers_hash_global(void); -PHPAPI HashTable *_php_get_stream_filters_hash(TSRMLS_D); -#define php_get_stream_filters_hash() _php_get_stream_filters_hash(TSRMLS_C) +PHPAPI HashTable *_php_get_stream_filters_hash(void); +#define php_get_stream_filters_hash() _php_get_stream_filters_hash() PHPAPI HashTable *php_get_stream_filters_hash_global(void); extern php_stream_wrapper_ops *php_stream_user_wrapper_ops; END_EXTERN_C() diff --git a/main/php_syslog.h b/main/php_syslog.h index 804cde4d5b..f748833bfd 100644 --- a/main/php_syslog.h +++ b/main/php_syslog.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -30,7 +30,7 @@ #endif #endif -/* +/* * The SCO OpenServer 5 Development System (not the UDK) * defines syslog to std_syslog. */ diff --git a/main/php_ticks.c b/main/php_ticks.c index d9d0f0b3fa..4b9f95f666 100644 --- a/main/php_ticks.c +++ b/main/php_ticks.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -21,59 +21,56 @@ #include "php.h" #include "php_ticks.h" -int php_startup_ticks(TSRMLS_D) +struct st_tick_function { - zend_llist_init(&PG(tick_functions), sizeof(void(*)(int)), NULL, 1); + void (*func)(int, void *); + void *arg; +}; + +int php_startup_ticks(void) +{ + zend_llist_init(&PG(tick_functions), sizeof(struct st_tick_function), NULL, 1); return SUCCESS; } -void php_deactivate_ticks(TSRMLS_D) +void php_deactivate_ticks(void) { zend_llist_clean(&PG(tick_functions)); } -void php_shutdown_ticks(TSRMLS_D) +void php_shutdown_ticks(void) { zend_llist_destroy(&PG(tick_functions)); } static int php_compare_tick_functions(void *elem1, void *elem2) { - void(*func1)(int); - void(*func2)(int); - memcpy(&func1, elem1, sizeof(void(*)(int))); - memcpy(&func2, elem2, sizeof(void(*)(int))); - return (func1 == func2); + struct st_tick_function *e1 = (struct st_tick_function *)elem1; + struct st_tick_function *e2 = (struct st_tick_function *)elem2; + return e1->func == e2->func && e1->arg == e2->arg; } -PHPAPI void php_add_tick_function(void (*func)(int)) +PHPAPI void php_add_tick_function(void (*func)(int, void*), void * arg) { - TSRMLS_FETCH(); - - zend_llist_add_element(&PG(tick_functions), (void *)&func); + struct st_tick_function tmp = {func, arg}; + zend_llist_add_element(&PG(tick_functions), (void *)&tmp); } -PHPAPI void php_remove_tick_function(void (*func)(int)) +PHPAPI void php_remove_tick_function(void (*func)(int, void *), void * arg) { - TSRMLS_FETCH(); - - zend_llist_del_element(&PG(tick_functions), (void *)func, - (int(*)(void*, void*))php_compare_tick_functions); + struct st_tick_function tmp = {func, arg}; + zend_llist_del_element(&PG(tick_functions), (void *)&tmp, (int(*)(void*, void*))php_compare_tick_functions); } -static void php_tick_iterator(void *data, void *arg TSRMLS_DC) +static void php_tick_iterator(void *d, void *arg) { - void (*func)(int); - - memcpy(&func, data, sizeof(void(*)(int))); - func(*((int *)arg)); + struct st_tick_function *data = (struct st_tick_function *)d; + data->func(*((int *)arg), data->arg); } void php_run_ticks(int count) { - TSRMLS_FETCH(); - - zend_llist_apply_with_argument(&PG(tick_functions), (llist_apply_with_arg_func_t) php_tick_iterator, &count TSRMLS_CC); + zend_llist_apply_with_argument(&PG(tick_functions), (llist_apply_with_arg_func_t) php_tick_iterator, &count); } /* diff --git a/main/php_ticks.h b/main/php_ticks.h index c9f67442c7..4f42239131 100644 --- a/main/php_ticks.h +++ b/main/php_ticks.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -21,14 +21,14 @@ #ifndef PHP_TICKS_H #define PHP_TICKS_H -int php_startup_ticks(TSRMLS_D); -void php_deactivate_ticks(TSRMLS_D); -void php_shutdown_ticks(TSRMLS_D); +int php_startup_ticks(void); +void php_deactivate_ticks(void); +void php_shutdown_ticks(void); void php_run_ticks(int count); BEGIN_EXTERN_C() -PHPAPI void php_add_tick_function(void (*func)(int)); -PHPAPI void php_remove_tick_function(void (*func)(int)); +PHPAPI void php_add_tick_function(void (*func)(int, void *), void *arg); +PHPAPI void php_remove_tick_function(void (*func)(int, void *), void * arg); END_EXTERN_C() #endif diff --git a/main/php_variables.c b/main/php_variables.c index fa7d5591df..2dac0ed0ea 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -23,7 +23,7 @@ #include "php.h" #include "ext/standard/php_standard.h" #include "ext/standard/credits.h" -#include "ext/standard/php_smart_str.h" +#include "zend_smart_str.h" #include "php_variables.h" #include "php_globals.h" #include "php_content_types.h" @@ -34,43 +34,40 @@ #endif /* for systems that need to override reading of environment variables */ -void _php_import_environment_variables(zval *array_ptr TSRMLS_DC); -PHPAPI void (*php_import_environment_variables)(zval *array_ptr TSRMLS_DC) = _php_import_environment_variables; +void _php_import_environment_variables(zval *array_ptr); +PHPAPI void (*php_import_environment_variables)(zval *array_ptr) = _php_import_environment_variables; -PHPAPI void php_register_variable(char *var, char *strval, zval *track_vars_array TSRMLS_DC) +PHPAPI void php_register_variable(char *var, char *strval, zval *track_vars_array) { - php_register_variable_safe(var, strval, strlen(strval), track_vars_array TSRMLS_CC); + php_register_variable_safe(var, strval, strlen(strval), track_vars_array); } /* binary-safe version */ -PHPAPI void php_register_variable_safe(char *var, char *strval, int str_len, zval *track_vars_array TSRMLS_DC) +PHPAPI void php_register_variable_safe(char *var, char *strval, size_t str_len, zval *track_vars_array) { zval new_entry; assert(strval != NULL); - - /* Prepare value */ - Z_STRLEN(new_entry) = str_len; - Z_STRVAL(new_entry) = estrndup(strval, Z_STRLEN(new_entry)); - Z_TYPE(new_entry) = IS_STRING; - php_register_variable_ex(var, &new_entry, track_vars_array TSRMLS_CC); + /* Prepare value */ + ZVAL_NEW_STR(&new_entry, zend_string_init(strval, str_len, 0)); + php_register_variable_ex(var, &new_entry, track_vars_array); } -PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars_array TSRMLS_DC) +PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars_array) { char *p = NULL; char *ip = NULL; /* index pointer */ char *index; char *var, *var_orig; - int var_len, index_len; - zval *gpc_element, **gpc_element_p; + size_t var_len, index_len; + zval gpc_element, *gpc_element_p; zend_bool is_array = 0; HashTable *symtable1 = NULL; ALLOCA_FLAG(use_heap) assert(var_name != NULL); - if (track_vars_array) { + if (track_vars_array && Z_TYPE_P(track_vars_array) == IS_ARRAY) { symtable1 = Z_ARRVAL_P(track_vars_array); } @@ -85,7 +82,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars while (*var_name && *var_name==' ') { var_name++; } - + /* * Prepare variable name */ @@ -113,7 +110,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars } /* GLOBALS hijack attempt, reject parameter */ - if (symtable1 == EG(active_symbol_table) && + if (symtable1 == &EG(symbol_table) && var_len == sizeof("GLOBALS")-1 && !memcmp(var, "GLOBALS", sizeof("GLOBALS")-1)) { zval_dtor(val); @@ -128,7 +125,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars int nest_level = 0; while (1) { char *index_s; - int new_idx_len = 0; + size_t new_idx_len = 0; if(++nest_level > PG(max_input_nesting_level)) { HashTable *ht; @@ -136,7 +133,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars if (track_vars_array) { ht = Z_ARRVAL_P(track_vars_array); - zend_symtable_del(ht, var, var_len + 1); + zend_symtable_str_del(ht, var, var_len); } zval_dtor(val); @@ -144,7 +141,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars /* do not output the error message to the screen, this helps us to to avoid "information disclosure" */ if (!PG(display_errors)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variable nesting level exceeded %ld. To increase the limit change max_input_nesting_level in php.ini.", PG(max_input_nesting_level)); + php_error_docref(NULL, E_WARNING, "Input variable nesting level exceeded " ZEND_LONG_FMT ". To increase the limit change max_input_nesting_level in php.ini.", PG(max_input_nesting_level)); } free_alloca(var_orig, use_heap); return; @@ -171,27 +168,34 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars return; } *ip = 0; - new_idx_len = strlen(index_s); + new_idx_len = strlen(index_s); } if (!index) { - MAKE_STD_ZVAL(gpc_element); - array_init(gpc_element); - if (zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p) == FAILURE) { + array_init(&gpc_element); + if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) { zval_ptr_dtor(&gpc_element); zval_dtor(val); free_alloca(var_orig, use_heap); return; } } else { - if (zend_symtable_find(symtable1, index, index_len + 1, (void **) &gpc_element_p) == FAILURE - || Z_TYPE_PP(gpc_element_p) != IS_ARRAY) { - MAKE_STD_ZVAL(gpc_element); - array_init(gpc_element); - zend_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + gpc_element_p = zend_symtable_str_find(symtable1, index, index_len); + if (!gpc_element_p) { + zval tmp; + array_init(&tmp); + gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp); + } else { + if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) { + gpc_element_p = Z_INDIRECT_P(gpc_element_p); + } + if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) { + zval_ptr_dtor(gpc_element_p); + array_init(gpc_element_p); + } } } - symtable1 = Z_ARRVAL_PP(gpc_element_p); + symtable1 = Z_ARRVAL_P(gpc_element_p); /* ip pointed to the '[' character, now obtain the key */ index = index_s; index_len = new_idx_len; @@ -206,26 +210,24 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars } } else { plain_var: - MAKE_STD_ZVAL(gpc_element); - gpc_element->value = val->value; - Z_TYPE_P(gpc_element) = Z_TYPE_P(val); + ZVAL_COPY_VALUE(&gpc_element, val); if (!index) { - if (zend_hash_next_index_insert(symtable1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p) == FAILURE) { + if ((gpc_element_p = zend_hash_next_index_insert(symtable1, &gpc_element)) == NULL) { zval_ptr_dtor(&gpc_element); } } else { - /* + /* * According to rfc2965, more specific paths are listed above the less specific ones. * If we encounter a duplicate cookie name, we should skip it, since it is not possible * to have the same (plain text) cookie name for the same path and we should not overwrite * more specific cookies with the less specific ones. */ - if (PG(http_globals)[TRACK_VARS_COOKIE] && - symtable1 == Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) && - zend_symtable_exists(symtable1, index, index_len + 1)) { + if (Z_TYPE(PG(http_globals)[TRACK_VARS_COOKIE]) != IS_UNDEF && + symtable1 == Z_ARRVAL(PG(http_globals)[TRACK_VARS_COOKIE]) && + zend_symtable_str_exists(symtable1, index, index_len)) { zval_ptr_dtor(&gpc_element); } else { - zend_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p); + gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &gpc_element); } } } @@ -239,12 +241,11 @@ typedef struct post_var_data { uint64_t cnt; } post_var_data_t; -static zend_bool add_post_var(zval *arr, post_var_data_t *var, zend_bool eof TSRMLS_DC) +static zend_bool add_post_var(zval *arr, post_var_data_t *var, zend_bool eof) { char *ksep, *vsep, *val; size_t klen, vlen; - /* FIXME: string-size_t */ - unsigned int new_vlen; + size_t new_vlen; if (var->ptr >= var->end) { return 0; @@ -279,8 +280,8 @@ static zend_bool add_post_var(zval *arr, post_var_data_t *var, zend_bool eof TSR vlen = php_url_decode(val, vlen); } - if (sapi_module.input_filter(PARSE_POST, var->ptr, &val, vlen, &new_vlen TSRMLS_CC)) { - php_register_variable_safe(var->ptr, val, new_vlen, arr TSRMLS_CC); + if (sapi_module.input_filter(PARSE_POST, var->ptr, &val, vlen, &new_vlen)) { + php_register_variable_safe(var->ptr, val, new_vlen, arr); } efree(val); @@ -288,15 +289,15 @@ static zend_bool add_post_var(zval *arr, post_var_data_t *var, zend_bool eof TSR return 1; } -static inline int add_post_vars(zval *arr, post_var_data_t *vars, zend_bool eof TSRMLS_DC) +static inline int add_post_vars(zval *arr, post_var_data_t *vars, zend_bool eof) { uint64_t max_vars = PG(max_input_vars); - vars->ptr = vars->str.c; - vars->end = vars->str.c + vars->str.len; - while (add_post_var(arr, vars, eof TSRMLS_CC)) { + vars->ptr = ZSTR_VAL(vars->str.s); + vars->end = ZSTR_VAL(vars->str.s) + ZSTR_LEN(vars->str.s); + while (add_post_var(arr, vars, eof)) { if (++vars->cnt > max_vars) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Input variables exceeded %" PRIu64 ". " "To increase the limit change max_input_vars in php.ini.", max_vars); @@ -305,7 +306,7 @@ static inline int add_post_vars(zval *arr, post_var_data_t *vars, zend_bool eof } if (!eof) { - memmove(vars->str.c, vars->ptr, vars->str.len = vars->end - vars->ptr); + memmove(ZSTR_VAL(vars->str.s), vars->ptr, ZSTR_LEN(vars->str.s) = vars->end - vars->ptr); } return SUCCESS; } @@ -331,10 +332,8 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler) if (len && len != (size_t) -1) { smart_str_appendl(&post_data.str, buf, len); - if (SUCCESS != add_post_vars(arr, &post_data, 0 TSRMLS_CC)) { - if (post_data.str.c) { - efree(post_data.str.c); - } + if (SUCCESS != add_post_vars(arr, &post_data, 0)) { + smart_str_free(&post_data.str); return; } } @@ -344,9 +343,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler) } } - add_post_vars(arr, &post_data, 1 TSRMLS_CC); - if (post_data.str.c) { - efree(post_data.str.c); + if (post_data.str.s) { + add_post_vars(arr, &post_data, 1); + smart_str_free(&post_data.str); } } } @@ -363,46 +362,39 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) { char *res = NULL, *var, *val, *separator = NULL; const char *c_var; - zval *array_ptr; + zval array; int free_buffer = 0; char *strtok_buf = NULL; - long count = 0; - + zend_long count = 0; + + ZVAL_UNDEF(&array); switch (arg) { case PARSE_POST: case PARSE_GET: case PARSE_COOKIE: - ALLOC_ZVAL(array_ptr); - array_init(array_ptr); - INIT_PZVAL(array_ptr); + array_init(&array); switch (arg) { case PARSE_POST: - if (PG(http_globals)[TRACK_VARS_POST]) { - zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]); - } - PG(http_globals)[TRACK_VARS_POST] = array_ptr; + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]); + ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_POST], &array); break; case PARSE_GET: - if (PG(http_globals)[TRACK_VARS_GET]) { - zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_GET]); - } - PG(http_globals)[TRACK_VARS_GET] = array_ptr; + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_GET]); + ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_GET], &array); break; case PARSE_COOKIE: - if (PG(http_globals)[TRACK_VARS_COOKIE]) { - zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_COOKIE]); - } - PG(http_globals)[TRACK_VARS_COOKIE] = array_ptr; + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_COOKIE]); + ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_COOKIE], &array); break; } break; default: - array_ptr = destArray; + ZVAL_COPY_VALUE(&array, destArray); break; } if (arg == PARSE_POST) { - sapi_handle_post(array_ptr TSRMLS_CC); + sapi_handle_post(&array); return; } @@ -440,9 +432,9 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) separator = ";\0"; break; } - + var = php_strtok_r(res, separator, &strtok_buf); - + while (var) { val = strchr(var, '='); @@ -457,31 +449,31 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data) } if (++count > PG(max_input_vars)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); + php_error_docref(NULL, E_WARNING, "Input variables exceeded " ZEND_LONG_FMT ". To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); break; } if (val) { /* have a value */ - int val_len; - unsigned int new_val_len; + size_t val_len; + size_t new_val_len; *val++ = '\0'; php_url_decode(var, strlen(var)); val_len = php_url_decode(val, strlen(val)); val = estrndup(val, val_len); - if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { - php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); + if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) { + php_register_variable_safe(var, val, new_val_len, &array); } efree(val); } else { - int val_len; - unsigned int new_val_len; + size_t val_len; + size_t new_val_len; php_url_decode(var, strlen(var)); val_len = 0; val = estrndup("", val_len); - if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len TSRMLS_CC)) { - php_register_variable_safe(var, val, new_val_len, array_ptr TSRMLS_CC); + if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) { + php_register_variable_safe(var, val, new_val_len, &array); } efree(val); } @@ -498,7 +490,7 @@ next_cookie: } } -void _php_import_environment_variables(zval *array_ptr TSRMLS_DC) +void _php_import_environment_variables(zval *array_ptr) { char buf[128]; char **env, *p, *t = buf; @@ -517,14 +509,14 @@ void _php_import_environment_variables(zval *array_ptr TSRMLS_DC) } memcpy(t, *env, nlen); t[nlen] = '\0'; - php_register_variable(t, p + 1, array_ptr TSRMLS_CC); + php_register_variable(t, p + 1, array_ptr); } if (t != buf && t != NULL) { efree(t); } } -zend_bool php_std_auto_global_callback(char *name, uint name_len TSRMLS_DC) +zend_bool php_std_auto_global_callback(char *name, uint name_len) { zend_printf("%s\n", name); return 0; /* don't rearm */ @@ -532,32 +524,25 @@ zend_bool php_std_auto_global_callback(char *name, uint name_len TSRMLS_DC) /* {{{ php_build_argv */ -static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC) +PHPAPI void php_build_argv(char *s, zval *track_vars_array) { - zval *arr, *argc, *tmp; + zval arr, argc, tmp; int count = 0; char *ss, *space; - + if (!(SG(request_info).argc || track_vars_array)) { return; } - - ALLOC_INIT_ZVAL(arr); - array_init(arr); + + array_init(&arr); /* Prepare argv */ if (SG(request_info).argc) { /* are we in cli sapi? */ int i; for (i = 0; i < SG(request_info).argc; i++) { - ALLOC_ZVAL(tmp); - Z_TYPE_P(tmp) = IS_STRING; - Z_STRLEN_P(tmp) = strlen(SG(request_info).argv[i]); - Z_STRVAL_P(tmp) = estrndup(SG(request_info).argv[i], Z_STRLEN_P(tmp)); - INIT_PZVAL(tmp); - if (zend_hash_next_index_insert(Z_ARRVAL_P(arr), &tmp, sizeof(zval *), NULL) == FAILURE) { - if (Z_TYPE_P(tmp) == IS_STRING) { - efree(Z_STRVAL_P(tmp)); - } + ZVAL_STRING(&tmp, SG(request_info).argv[i]); + if (zend_hash_next_index_insert(Z_ARRVAL(arr), &tmp) == NULL) { + zend_string_free(Z_STR(tmp)); } } } else if (s && *s) { @@ -568,16 +553,10 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC) *space = '\0'; } /* auto-type */ - ALLOC_ZVAL(tmp); - Z_TYPE_P(tmp) = IS_STRING; - Z_STRLEN_P(tmp) = strlen(ss); - Z_STRVAL_P(tmp) = estrndup(ss, Z_STRLEN_P(tmp)); - INIT_PZVAL(tmp); + ZVAL_STRING(&tmp, ss); count++; - if (zend_hash_next_index_insert(Z_ARRVAL_P(arr), &tmp, sizeof(zval *), NULL) == FAILURE) { - if (Z_TYPE_P(tmp) == IS_STRING) { - efree(Z_STRVAL_P(tmp)); - } + if (zend_hash_next_index_insert(Z_ARRVAL(arr), &tmp) == NULL) { + zend_string_free(Z_STR(tmp)); } if (space) { *space = '+'; @@ -589,289 +568,221 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC) } /* prepare argc */ - ALLOC_INIT_ZVAL(argc); if (SG(request_info).argc) { - Z_LVAL_P(argc) = SG(request_info).argc; + ZVAL_LONG(&argc, SG(request_info).argc); } else { - Z_LVAL_P(argc) = count; + ZVAL_LONG(&argc, count); } - Z_TYPE_P(argc) = IS_LONG; if (SG(request_info).argc) { - Z_ADDREF_P(arr); - Z_ADDREF_P(argc); - zend_hash_update(&EG(symbol_table), "argv", sizeof("argv"), &arr, sizeof(zval *), NULL); - zend_hash_update(&EG(symbol_table), "argc", sizeof("argc"), &argc, sizeof(zval *), NULL); - } - if (track_vars_array) { - Z_ADDREF_P(arr); - Z_ADDREF_P(argc); - zend_hash_update(Z_ARRVAL_P(track_vars_array), "argv", sizeof("argv"), &arr, sizeof(zval *), NULL); - zend_hash_update(Z_ARRVAL_P(track_vars_array), "argc", sizeof("argc"), &argc, sizeof(zval *), NULL); + Z_ADDREF(arr); + zend_hash_str_update(&EG(symbol_table), "argv", sizeof("argv")-1, &arr); + zend_hash_str_add(&EG(symbol_table), "argc", sizeof("argc")-1, &argc); + } + if (track_vars_array && Z_TYPE_P(track_vars_array) == IS_ARRAY) { + Z_ADDREF(arr); + zend_hash_str_update(Z_ARRVAL_P(track_vars_array), "argv", sizeof("argv")-1, &arr); + zend_hash_str_update(Z_ARRVAL_P(track_vars_array), "argc", sizeof("argc")-1, &argc); } zval_ptr_dtor(&arr); - zval_ptr_dtor(&argc); } /* }}} */ /* {{{ php_register_server_variables */ -static inline void php_register_server_variables(TSRMLS_D) +static inline void php_register_server_variables(void) { - zval *array_ptr = NULL; + zval request_time_float, request_time_long; - ALLOC_ZVAL(array_ptr); - array_init(array_ptr); - INIT_PZVAL(array_ptr); - if (PG(http_globals)[TRACK_VARS_SERVER]) { - zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_SERVER]); - } - PG(http_globals)[TRACK_VARS_SERVER] = array_ptr; + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_SERVER]); + array_init(&PG(http_globals)[TRACK_VARS_SERVER]); /* Server variables */ if (sapi_module.register_server_variables) { - sapi_module.register_server_variables(array_ptr TSRMLS_CC); + sapi_module.register_server_variables(&PG(http_globals)[TRACK_VARS_SERVER]); } /* PHP Authentication support */ if (SG(request_info).auth_user) { - php_register_variable("PHP_AUTH_USER", SG(request_info).auth_user, array_ptr TSRMLS_CC); + php_register_variable("PHP_AUTH_USER", SG(request_info).auth_user, &PG(http_globals)[TRACK_VARS_SERVER]); } if (SG(request_info).auth_password) { - php_register_variable("PHP_AUTH_PW", SG(request_info).auth_password, array_ptr TSRMLS_CC); + php_register_variable("PHP_AUTH_PW", SG(request_info).auth_password, &PG(http_globals)[TRACK_VARS_SERVER]); } if (SG(request_info).auth_digest) { - php_register_variable("PHP_AUTH_DIGEST", SG(request_info).auth_digest, array_ptr TSRMLS_CC); - } - /* store request init time */ - { - zval request_time_float, request_time_long; - Z_TYPE(request_time_float) = IS_DOUBLE; - Z_DVAL(request_time_float) = sapi_get_request_time(TSRMLS_C); - php_register_variable_ex("REQUEST_TIME_FLOAT", &request_time_float, array_ptr TSRMLS_CC); - Z_TYPE(request_time_long) = IS_LONG; - Z_LVAL(request_time_long) = zend_dval_to_lval(Z_DVAL(request_time_float)); - php_register_variable_ex("REQUEST_TIME", &request_time_long, array_ptr TSRMLS_CC); + php_register_variable("PHP_AUTH_DIGEST", SG(request_info).auth_digest, &PG(http_globals)[TRACK_VARS_SERVER]); } + /* store request init time */ + ZVAL_DOUBLE(&request_time_float, sapi_get_request_time()); + php_register_variable_ex("REQUEST_TIME_FLOAT", &request_time_float, &PG(http_globals)[TRACK_VARS_SERVER]); + ZVAL_LONG(&request_time_long, zend_dval_to_lval(Z_DVAL(request_time_float))); + php_register_variable_ex("REQUEST_TIME", &request_time_long, &PG(http_globals)[TRACK_VARS_SERVER]); } /* }}} */ /* {{{ php_autoglobal_merge */ -static void php_autoglobal_merge(HashTable *dest, HashTable *src TSRMLS_DC) +static void php_autoglobal_merge(HashTable *dest, HashTable *src) { - zval **src_entry, **dest_entry; - char *string_key; - uint string_key_len; - ulong num_key; - HashPosition pos; - int key_type; + zval *src_entry, *dest_entry; + zend_string *string_key; + zend_ulong num_key; int globals_check = (dest == (&EG(symbol_table))); - zend_hash_internal_pointer_reset_ex(src, &pos); - while (zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS) { - key_type = zend_hash_get_current_key_ex(src, &string_key, &string_key_len, &num_key, 0, &pos); - if (Z_TYPE_PP(src_entry) != IS_ARRAY - || (key_type == HASH_KEY_IS_STRING && zend_hash_find(dest, string_key, string_key_len, (void **) &dest_entry) != SUCCESS) - || (key_type == HASH_KEY_IS_LONG && zend_hash_index_find(dest, num_key, (void **)&dest_entry) != SUCCESS) - || Z_TYPE_PP(dest_entry) != IS_ARRAY - ) { - Z_ADDREF_PP(src_entry); - if (key_type == HASH_KEY_IS_STRING) { - if (!globals_check || string_key_len != sizeof("GLOBALS") || memcmp(string_key, "GLOBALS", sizeof("GLOBALS") - 1)) { - zend_hash_update(dest, string_key, string_key_len, src_entry, sizeof(zval *), NULL); - } else { - Z_DELREF_PP(src_entry); + ZEND_HASH_FOREACH_KEY_VAL(src, num_key, string_key, src_entry) { + if (Z_TYPE_P(src_entry) != IS_ARRAY + || (string_key && (dest_entry = zend_hash_find(dest, string_key)) == NULL) + || (string_key == NULL && (dest_entry = zend_hash_index_find(dest, num_key)) == NULL) + || Z_TYPE_P(dest_entry) != IS_ARRAY) { + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } + if (string_key) { + if (!globals_check || ZSTR_LEN(string_key) != sizeof("GLOBALS") - 1 + || memcmp(ZSTR_VAL(string_key), "GLOBALS", sizeof("GLOBALS") - 1)) { + zend_hash_update(dest, string_key, src_entry); + } else if (Z_REFCOUNTED_P(src_entry)) { + Z_DELREF_P(src_entry); } } else { - zend_hash_index_update(dest, num_key, src_entry, sizeof(zval *), NULL); + zend_hash_index_update(dest, num_key, src_entry); } } else { - SEPARATE_ZVAL(dest_entry); - php_autoglobal_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_PP(src_entry) TSRMLS_CC); + SEPARATE_ARRAY(dest_entry); + php_autoglobal_merge(Z_ARRVAL_P(dest_entry), Z_ARRVAL_P(src_entry)); } - zend_hash_move_forward_ex(src, &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ -static zend_bool php_auto_globals_create_server(const char *name, uint name_len TSRMLS_DC); -static zend_bool php_auto_globals_create_env(const char *name, uint name_len TSRMLS_DC); -static zend_bool php_auto_globals_create_request(const char *name, uint name_len TSRMLS_DC); - /* {{{ php_hash_environment */ -PHPAPI int php_hash_environment(TSRMLS_D) +PHPAPI int php_hash_environment(void) { memset(PG(http_globals), 0, sizeof(PG(http_globals))); - zend_activate_auto_globals(TSRMLS_C); + zend_activate_auto_globals(); if (PG(register_argc_argv)) { - php_build_argv(SG(request_info).query_string, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC); + php_build_argv(SG(request_info).query_string, &PG(http_globals)[TRACK_VARS_SERVER]); } return SUCCESS; } /* }}} */ -static zend_bool php_auto_globals_create_get(const char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_get(zend_string *name) { - zval *vars; - if (PG(variables_order) && (strchr(PG(variables_order),'G') || strchr(PG(variables_order),'g'))) { - sapi_module.treat_data(PARSE_GET, NULL, NULL TSRMLS_CC); - vars = PG(http_globals)[TRACK_VARS_GET]; + sapi_module.treat_data(PARSE_GET, NULL, NULL); } else { - ALLOC_ZVAL(vars); - array_init(vars); - INIT_PZVAL(vars); - if (PG(http_globals)[TRACK_VARS_GET]) { - zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_GET]); - } - PG(http_globals)[TRACK_VARS_GET] = vars; + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_GET]); + array_init(&PG(http_globals)[TRACK_VARS_GET]); } - zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL); - Z_ADDREF_P(vars); - + zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_GET]); + Z_ADDREF(PG(http_globals)[TRACK_VARS_GET]); + return 0; /* don't rearm */ } -static zend_bool php_auto_globals_create_post(const char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_post(zend_string *name) { - zval *vars; - if (PG(variables_order) && (strchr(PG(variables_order),'P') || strchr(PG(variables_order),'p')) && + !SG(headers_sent) && SG(request_info).request_method && !strcasecmp(SG(request_info).request_method, "POST")) { - sapi_module.treat_data(PARSE_POST, NULL, NULL TSRMLS_CC); - vars = PG(http_globals)[TRACK_VARS_POST]; + sapi_module.treat_data(PARSE_POST, NULL, NULL); } else { - ALLOC_ZVAL(vars); - array_init(vars); - INIT_PZVAL(vars); - if (PG(http_globals)[TRACK_VARS_POST]) { - zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]); - } - PG(http_globals)[TRACK_VARS_POST] = vars; + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]); + array_init(&PG(http_globals)[TRACK_VARS_POST]); } - zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL); - Z_ADDREF_P(vars); - + zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_POST]); + Z_ADDREF(PG(http_globals)[TRACK_VARS_POST]); + return 0; /* don't rearm */ } -static zend_bool php_auto_globals_create_cookie(const char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_cookie(zend_string *name) { - zval *vars; - if (PG(variables_order) && (strchr(PG(variables_order),'C') || strchr(PG(variables_order),'c'))) { - sapi_module.treat_data(PARSE_COOKIE, NULL, NULL TSRMLS_CC); - vars = PG(http_globals)[TRACK_VARS_COOKIE]; + sapi_module.treat_data(PARSE_COOKIE, NULL, NULL); } else { - ALLOC_ZVAL(vars); - array_init(vars); - INIT_PZVAL(vars); - if (PG(http_globals)[TRACK_VARS_COOKIE]) { - zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_COOKIE]); - } - PG(http_globals)[TRACK_VARS_COOKIE] = vars; + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_COOKIE]); + array_init(&PG(http_globals)[TRACK_VARS_COOKIE]); } - zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL); - Z_ADDREF_P(vars); - + zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_COOKIE]); + Z_ADDREF(PG(http_globals)[TRACK_VARS_COOKIE]); + return 0; /* don't rearm */ } -static zend_bool php_auto_globals_create_files(const char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_files(zend_string *name) { - zval *vars; - - if (PG(http_globals)[TRACK_VARS_FILES]) { - vars = PG(http_globals)[TRACK_VARS_FILES]; - } else { - ALLOC_ZVAL(vars); - array_init(vars); - INIT_PZVAL(vars); - PG(http_globals)[TRACK_VARS_FILES] = vars; + if (Z_TYPE(PG(http_globals)[TRACK_VARS_FILES]) == IS_UNDEF) { + array_init(&PG(http_globals)[TRACK_VARS_FILES]); } - zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL); - Z_ADDREF_P(vars); - + zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_FILES]); + Z_ADDREF(PG(http_globals)[TRACK_VARS_FILES]); + return 0; /* don't rearm */ } -static zend_bool php_auto_globals_create_server(const char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_server(zend_string *name) { if (PG(variables_order) && (strchr(PG(variables_order),'S') || strchr(PG(variables_order),'s'))) { - php_register_server_variables(TSRMLS_C); + php_register_server_variables(); if (PG(register_argc_argv)) { if (SG(request_info).argc) { - zval **argc, **argv; - - if (zend_hash_find(&EG(symbol_table), "argc", sizeof("argc"), (void**)&argc) == SUCCESS && - zend_hash_find(&EG(symbol_table), "argv", sizeof("argv"), (void**)&argv) == SUCCESS) { - Z_ADDREF_PP(argc); - Z_ADDREF_PP(argv); - zend_hash_update(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv"), argv, sizeof(zval *), NULL); - zend_hash_update(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]), "argc", sizeof("argc"), argc, sizeof(zval *), NULL); + zval *argc, *argv; + + if ((argc = zend_hash_str_find_ind(&EG(symbol_table), "argc", sizeof("argc")-1)) != NULL && + (argv = zend_hash_str_find_ind(&EG(symbol_table), "argv", sizeof("argv")-1)) != NULL) { + Z_ADDREF_P(argv); + zend_hash_str_update(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv")-1, argv); + zend_hash_str_update(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "argc", sizeof("argc")-1, argc); } } else { - php_build_argv(SG(request_info).query_string, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC); + php_build_argv(SG(request_info).query_string, &PG(http_globals)[TRACK_VARS_SERVER]); } } - + } else { - zval *server_vars=NULL; - ALLOC_ZVAL(server_vars); - array_init(server_vars); - INIT_PZVAL(server_vars); - if (PG(http_globals)[TRACK_VARS_SERVER]) { - zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_SERVER]); - } - PG(http_globals)[TRACK_VARS_SERVER] = server_vars; + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_SERVER]); + array_init(&PG(http_globals)[TRACK_VARS_SERVER]); } - zend_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_SERVER], sizeof(zval *), NULL); - Z_ADDREF_P(PG(http_globals)[TRACK_VARS_SERVER]); - + zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_SERVER]); + Z_ADDREF(PG(http_globals)[TRACK_VARS_SERVER]); + return 0; /* don't rearm */ } -static zend_bool php_auto_globals_create_env(const char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_env(zend_string *name) { - zval *env_vars = NULL; - ALLOC_ZVAL(env_vars); - array_init(env_vars); - INIT_PZVAL(env_vars); - if (PG(http_globals)[TRACK_VARS_ENV]) { - zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_ENV]); - } - PG(http_globals)[TRACK_VARS_ENV] = env_vars; - + zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_ENV]); + array_init(&PG(http_globals)[TRACK_VARS_ENV]); + if (PG(variables_order) && (strchr(PG(variables_order),'E') || strchr(PG(variables_order),'e'))) { - php_import_environment_variables(PG(http_globals)[TRACK_VARS_ENV] TSRMLS_CC); + php_import_environment_variables(&PG(http_globals)[TRACK_VARS_ENV]); } - zend_hash_update(&EG(symbol_table), name, name_len + 1, &PG(http_globals)[TRACK_VARS_ENV], sizeof(zval *), NULL); - Z_ADDREF_P(PG(http_globals)[TRACK_VARS_ENV]); + zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_ENV]); + Z_ADDREF(PG(http_globals)[TRACK_VARS_ENV]); return 0; /* don't rearm */ } -static zend_bool php_auto_globals_create_request(const char *name, uint name_len TSRMLS_DC) +static zend_bool php_auto_globals_create_request(zend_string *name) { - zval *form_variables; + zval form_variables; unsigned char _gpc_flags[3] = {0, 0, 0}; char *p; - ALLOC_ZVAL(form_variables); - array_init(form_variables); - INIT_PZVAL(form_variables); + array_init(&form_variables); if (PG(request_order) != NULL) { p = PG(request_order); @@ -884,40 +795,40 @@ static zend_bool php_auto_globals_create_request(const char *name, uint name_len case 'g': case 'G': if (!_gpc_flags[0]) { - php_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]) TSRMLS_CC); + php_autoglobal_merge(Z_ARRVAL(form_variables), Z_ARRVAL(PG(http_globals)[TRACK_VARS_GET])); _gpc_flags[0] = 1; } break; case 'p': case 'P': if (!_gpc_flags[1]) { - php_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]) TSRMLS_CC); + php_autoglobal_merge(Z_ARRVAL(form_variables), Z_ARRVAL(PG(http_globals)[TRACK_VARS_POST])); _gpc_flags[1] = 1; } break; case 'c': case 'C': if (!_gpc_flags[2]) { - php_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) TSRMLS_CC); + php_autoglobal_merge(Z_ARRVAL(form_variables), Z_ARRVAL(PG(http_globals)[TRACK_VARS_COOKIE])); _gpc_flags[2] = 1; } break; } } - zend_hash_update(&EG(symbol_table), name, name_len + 1, &form_variables, sizeof(zval *), NULL); + zend_hash_update(&EG(symbol_table), name, &form_variables); return 0; } -void php_startup_auto_globals(TSRMLS_D) +void php_startup_auto_globals(void) { - zend_register_auto_global(ZEND_STRL("_GET"), 0, php_auto_globals_create_get TSRMLS_CC); - zend_register_auto_global(ZEND_STRL("_POST"), 0, php_auto_globals_create_post TSRMLS_CC); - zend_register_auto_global(ZEND_STRL("_COOKIE"), 0, php_auto_globals_create_cookie TSRMLS_CC); - zend_register_auto_global(ZEND_STRL("_SERVER"), PG(auto_globals_jit), php_auto_globals_create_server TSRMLS_CC); - zend_register_auto_global(ZEND_STRL("_ENV"), PG(auto_globals_jit), php_auto_globals_create_env TSRMLS_CC); - zend_register_auto_global(ZEND_STRL("_REQUEST"), PG(auto_globals_jit), php_auto_globals_create_request TSRMLS_CC); - zend_register_auto_global(ZEND_STRL("_FILES"), 0, php_auto_globals_create_files TSRMLS_CC); + zend_register_auto_global(zend_string_init("_GET", sizeof("_GET")-1, 1), 0, php_auto_globals_create_get); + zend_register_auto_global(zend_string_init("_POST", sizeof("_POST")-1, 1), 0, php_auto_globals_create_post); + zend_register_auto_global(zend_string_init("_COOKIE", sizeof("_COOKIE")-1, 1), 0, php_auto_globals_create_cookie); + zend_register_auto_global(zend_string_init("_SERVER", sizeof("_SERVER")-1, 1), PG(auto_globals_jit), php_auto_globals_create_server); + zend_register_auto_global(zend_string_init("_ENV", sizeof("_ENV")-1, 1), PG(auto_globals_jit), php_auto_globals_create_env); + zend_register_auto_global(zend_string_init("_REQUEST", sizeof("_REQUEST")-1, 1), PG(auto_globals_jit), php_auto_globals_create_request); + zend_register_auto_global(zend_string_init("_FILES", sizeof("_FILES")-1, 1), 0, php_auto_globals_create_files); } /* diff --git a/main/php_variables.h b/main/php_variables.h index 76a013e8c7..d34a09035e 100644 --- a/main/php_variables.h +++ b/main/php_variables.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -34,14 +34,15 @@ #define PARSE_SESSION 6 BEGIN_EXTERN_C() -void php_startup_auto_globals(TSRMLS_D); -extern PHPAPI void (*php_import_environment_variables)(zval *array_ptr TSRMLS_DC); -PHPAPI void php_register_variable(char *var, char *val, zval *track_vars_array TSRMLS_DC); +void php_startup_auto_globals(void); +extern PHPAPI void (*php_import_environment_variables)(zval *array_ptr); +PHPAPI void php_register_variable(char *var, char *val, zval *track_vars_array); /* binary-safe version */ -PHPAPI void php_register_variable_safe(char *var, char *val, int val_len, zval *track_vars_array TSRMLS_DC); -PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_array TSRMLS_DC); +PHPAPI void php_register_variable_safe(char *var, char *val, size_t val_len, zval *track_vars_array); +PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_array); -PHPAPI int php_hash_environment(TSRMLS_D); +PHPAPI void php_build_argv(char *s, zval *track_vars_array); +PHPAPI int php_hash_environment(void); END_EXTERN_C() #define NUM_TRACK_VARS 6 diff --git a/main/php_version.h b/main/php_version.h index 92c8af871e..d48ab24141 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -1,8 +1,8 @@ /* automatically generated by configure */ /* edit configure.in to change version number */ -#define PHP_MAJOR_VERSION 5 -#define PHP_MINOR_VERSION 6 -#define PHP_RELEASE_VERSION 15 +#define PHP_MAJOR_VERSION 7 +#define PHP_MINOR_VERSION 0 +#define PHP_RELEASE_VERSION 0 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "5.6.15-dev" -#define PHP_VERSION_ID 50615 +#define PHP_VERSION "7.0.0-dev" +#define PHP_VERSION_ID 70000 diff --git a/main/reentrancy.c b/main/reentrancy.c index a467d03e85..b69d6cc450 100644 --- a/main/reentrancy.c +++ b/main/reentrancy.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -125,19 +125,19 @@ PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm) #if !defined(HAVE_POSIX_READDIR_R) -PHPAPI int php_readdir_r(DIR *dirp, struct dirent *entry, +PHPAPI int php_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) { #if defined(HAVE_OLD_READDIR_R) int ret = 0; - + /* We cannot rely on the return value of readdir_r as it differs between various platforms (HPUX returns 0 on success whereas Solaris returns non-zero) */ entry->d_name[0] = '\0'; readdir_r(dirp, entry); - + if (entry->d_name[0] == '\0') { *result = NULL; ret = errno; @@ -150,11 +150,11 @@ PHPAPI int php_readdir_r(DIR *dirp, struct dirent *entry, int ret = 0; local_lock(READDIR_R); - + errno = 0; - + ptr = readdir(dirp); - + if (!ptr && errno != 0) ret = errno; @@ -176,7 +176,7 @@ PHPAPI int php_readdir_r(DIR *dirp, struct dirent *entry, PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm) { struct tm *tmp; - + local_lock(LOCALTIME_R); tmp = localtime(timep); @@ -184,7 +184,7 @@ PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm) memcpy(p_tm, tmp, sizeof(struct tm)); tmp = p_tm; } - + local_unlock(LOCALTIME_R); return tmp; @@ -197,14 +197,14 @@ PHPAPI struct tm *php_localtime_r(const time_t *const timep, struct tm *p_tm) PHPAPI char *php_ctime_r(const time_t *clock, char *buf) { char *tmp; - + local_lock(CTIME_R); tmp = ctime(clock); strcpy(buf, tmp); local_unlock(CTIME_R); - + return buf; } @@ -215,7 +215,7 @@ PHPAPI char *php_ctime_r(const time_t *clock, char *buf) PHPAPI char *php_asctime_r(const struct tm *tm, char *buf) { char *tmp; - + local_lock(ASCTIME_R); tmp = asctime(tm); @@ -233,7 +233,7 @@ PHPAPI char *php_asctime_r(const struct tm *tm, char *buf) PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm) { struct tm *tmp; - + local_lock(GMTIME_R); tmp = gmtime(timep); @@ -241,7 +241,7 @@ PHPAPI struct tm *php_gmtime_r(const time_t *const timep, struct tm *p_tm) memcpy(p_tm, tmp, sizeof(struct tm)); tmp = p_tm; } - + local_unlock(GMTIME_R); return tmp; @@ -346,11 +346,11 @@ php_rand_r(unsigned int *ctx) * * 1. Redistributions of source code must retain the above copyright * notices, this list of conditions and the following disclaimer. - * + * * 2. Redistributions in binary form must reproduce the above copyright * notices, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * + * * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * diff --git a/main/rfc1867.c b/main/rfc1867.c index ca8f28b553..1db3cd303f 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -33,7 +33,7 @@ #include "php_variables.h" #include "rfc1867.h" #include "ext/standard/php_string.h" -#include "ext/standard/php_smart_str.h" +#include "ext/standard/php_smart_string.h" #if defined(PHP_WIN32) && !defined(HAVE_ATOLL) # define atoll(s) _atoi64(s) @@ -42,13 +42,13 @@ #define DEBUG_FILE_UPLOAD ZEND_DEBUG -static int dummy_encoding_translation(TSRMLS_D) +static int dummy_encoding_translation(void) { return 0; } -static char *php_ap_getword(const zend_encoding *encoding, char **line, char stop TSRMLS_DC); -static char *php_ap_getword_conf(const zend_encoding *encoding, char *str TSRMLS_DC); +static char *php_ap_getword(const zend_encoding *encoding, char **line, char stop); +static char *php_ap_getword_conf(const zend_encoding *encoding, char *str); static php_rfc1867_encoding_translation_t php_rfc1867_encoding_translation = dummy_encoding_translation; static php_rfc1867_get_detect_order_t php_rfc1867_get_detect_order = NULL; @@ -57,9 +57,9 @@ static php_rfc1867_getword_t php_rfc1867_getword = php_ap_getword; static php_rfc1867_getword_conf_t php_rfc1867_getword_conf = php_ap_getword_conf; static php_rfc1867_basename_t php_rfc1867_basename = NULL; -PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC) = NULL; +PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra) = NULL; -static void safe_php_register_variable(char *var, char *strval, int val_len, zval *track_vars_array, zend_bool override_protection TSRMLS_DC); +static void safe_php_register_variable(char *var, char *strval, size_t val_len, zval *track_vars_array, zend_bool override_protection); /* The longest property name we use in an uploaded file array */ #define MAX_SIZE_OF_INDEX sizeof("[tmp_name]") @@ -77,7 +77,7 @@ static void safe_php_register_variable(char *var, char *strval, int val_len, zva #define UPLOAD_ERROR_F 7 /* Failed to write file to disk */ #define UPLOAD_ERROR_X 8 /* File upload stopped by extension */ -void php_rfc1867_register_constants(TSRMLS_D) /* {{{ */ +void php_rfc1867_register_constants(void) /* {{{ */ { REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_OK", UPLOAD_ERROR_OK, CONST_CS | CONST_PERSISTENT); REGISTER_MAIN_LONG_CONSTANT("UPLOAD_ERR_INI_SIZE", UPLOAD_ERROR_A, CONST_CS | CONST_PERSISTENT); @@ -90,7 +90,7 @@ void php_rfc1867_register_constants(TSRMLS_D) /* {{{ */ } /* }}} */ -static void normalize_protected_variable(char *varname TSRMLS_DC) /* {{{ */ +static void normalize_protected_variable(char *varname) /* {{{ */ { char *s = varname, *index = NULL, *indexend = NULL, *p; @@ -148,60 +148,65 @@ static void normalize_protected_variable(char *varname TSRMLS_DC) /* {{{ */ } /* }}} */ -static void add_protected_variable(char *varname TSRMLS_DC) /* {{{ */ +static void add_protected_variable(char *varname) /* {{{ */ { - int dummy = 1; - - normalize_protected_variable(varname TSRMLS_CC); - zend_hash_add(&PG(rfc1867_protected_variables), varname, strlen(varname)+1, &dummy, sizeof(int), NULL); + normalize_protected_variable(varname); + zend_hash_str_add_empty_element(&PG(rfc1867_protected_variables), varname, strlen(varname)); } /* }}} */ -static zend_bool is_protected_variable(char *varname TSRMLS_DC) /* {{{ */ +static zend_bool is_protected_variable(char *varname) /* {{{ */ { - normalize_protected_variable(varname TSRMLS_CC); - return zend_hash_exists(&PG(rfc1867_protected_variables), varname, strlen(varname)+1); + normalize_protected_variable(varname); + return zend_hash_str_exists(&PG(rfc1867_protected_variables), varname, strlen(varname)); } /* }}} */ -static void safe_php_register_variable(char *var, char *strval, int val_len, zval *track_vars_array, zend_bool override_protection TSRMLS_DC) /* {{{ */ +static void safe_php_register_variable(char *var, char *strval, size_t val_len, zval *track_vars_array, zend_bool override_protection) /* {{{ */ { - if (override_protection || !is_protected_variable(var TSRMLS_CC)) { - php_register_variable_safe(var, strval, val_len, track_vars_array TSRMLS_CC); + if (override_protection || !is_protected_variable(var)) { + php_register_variable_safe(var, strval, val_len, track_vars_array); } } /* }}} */ -static void safe_php_register_variable_ex(char *var, zval *val, zval *track_vars_array, zend_bool override_protection TSRMLS_DC) /* {{{ */ +static void safe_php_register_variable_ex(char *var, zval *val, zval *track_vars_array, zend_bool override_protection) /* {{{ */ { - if (override_protection || !is_protected_variable(var TSRMLS_CC)) { - php_register_variable_ex(var, val, track_vars_array TSRMLS_CC); + if (override_protection || !is_protected_variable(var)) { + php_register_variable_ex(var, val, track_vars_array); } } /* }}} */ -static void register_http_post_files_variable(char *strvar, char *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC) /* {{{ */ +static void register_http_post_files_variable(char *strvar, char *val, zval *http_post_files, zend_bool override_protection) /* {{{ */ { - safe_php_register_variable(strvar, val, strlen(val), http_post_files, override_protection TSRMLS_CC); + safe_php_register_variable(strvar, val, strlen(val), http_post_files, override_protection); } /* }}} */ -static void register_http_post_files_variable_ex(char *var, zval *val, zval *http_post_files, zend_bool override_protection TSRMLS_DC) /* {{{ */ +static void register_http_post_files_variable_ex(char *var, zval *val, zval *http_post_files, zend_bool override_protection) /* {{{ */ { - safe_php_register_variable_ex(var, val, http_post_files, override_protection TSRMLS_CC); + safe_php_register_variable_ex(var, val, http_post_files, override_protection); } /* }}} */ -static int unlink_filename(char **filename TSRMLS_DC) /* {{{ */ +static int unlink_filename(zval *el) /* {{{ */ { - VCWD_UNLINK(*filename); + zend_string *filename = Z_STR_P(el); + VCWD_UNLINK(ZSTR_VAL(filename)); return 0; } /* }}} */ -void destroy_uploaded_files_hash(TSRMLS_D) /* {{{ */ + +static void free_filename(zval *el) { + zend_string *filename = Z_STR_P(el); + zend_string_release(filename); +} + +PHPAPI void destroy_uploaded_files_hash(void) /* {{{ */ { - zend_hash_apply(SG(rfc1867_uploaded_files), (apply_func_t) unlink_filename TSRMLS_CC); + zend_hash_apply(SG(rfc1867_uploaded_files), unlink_filename); zend_hash_destroy(SG(rfc1867_uploaded_files)); FREE_HASHTABLE(SG(rfc1867_uploaded_files)); } @@ -238,7 +243,7 @@ typedef struct { * Fill up the buffer with client data. * Returns number of bytes added to buffer. */ -static int fill_buffer(multipart_buffer *self TSRMLS_DC) +static int fill_buffer(multipart_buffer *self) { int bytes_to_read, total_read = 0, actual_read = 0; @@ -257,7 +262,7 @@ static int fill_buffer(multipart_buffer *self TSRMLS_DC) char *buf = self->buffer + self->bytes_in_buffer; - actual_read = sapi_module.read_post(buf, bytes_to_read TSRMLS_CC); + actual_read = (int)sapi_module.read_post(buf, bytes_to_read); /* update the buffer length */ if (actual_read > 0) { @@ -274,9 +279,9 @@ static int fill_buffer(multipart_buffer *self TSRMLS_DC) } /* eof if we are out of bytes, or if we hit the final boundary */ -static int multipart_buffer_eof(multipart_buffer *self TSRMLS_DC) +static int multipart_buffer_eof(multipart_buffer *self) { - if ( (self->bytes_in_buffer == 0 && fill_buffer(self TSRMLS_CC) < 1) ) { + if ( (self->bytes_in_buffer == 0 && fill_buffer(self) < 1) ) { return 1; } else { return 0; @@ -284,7 +289,7 @@ static int multipart_buffer_eof(multipart_buffer *self TSRMLS_DC) } /* create new multipart_buffer structure */ -static multipart_buffer *multipart_buffer_new(char *boundary, int boundary_len TSRMLS_DC) +static multipart_buffer *multipart_buffer_new(char *boundary, int boundary_len) { multipart_buffer *self = (multipart_buffer *) ecalloc(1, sizeof(multipart_buffer)); @@ -296,13 +301,13 @@ static multipart_buffer *multipart_buffer_new(char *boundary, int boundary_len T spprintf(&self->boundary, 0, "--%s", boundary); - self->boundary_next_len = spprintf(&self->boundary_next, 0, "\n--%s", boundary); + self->boundary_next_len = (int)spprintf(&self->boundary_next, 0, "\n--%s", boundary); self->buf_begin = self->buffer; self->bytes_in_buffer = 0; - if (php_rfc1867_encoding_translation(TSRMLS_C)) { - php_rfc1867_get_detect_order(&self->detect_order, &self->detect_order_size TSRMLS_CC); + if (php_rfc1867_encoding_translation()) { + php_rfc1867_get_detect_order(&self->detect_order, &self->detect_order_size); } else { self->detect_order = NULL; self->detect_order_size = 0; @@ -359,12 +364,12 @@ static char *next_line(multipart_buffer *self) } /* Returns the next CRLF terminated line from the client */ -static char *get_line(multipart_buffer *self TSRMLS_DC) +static char *get_line(multipart_buffer *self) { char* ptr = next_line(self); if (!ptr) { - fill_buffer(self TSRMLS_CC); + fill_buffer(self); ptr = next_line(self); } @@ -383,12 +388,12 @@ static void php_free_hdr_entry(mime_header_entry *h) } /* finds a boundary */ -static int find_boundary(multipart_buffer *self, char *boundary TSRMLS_DC) +static int find_boundary(multipart_buffer *self, char *boundary) { char *line; /* loop thru lines */ - while( (line = get_line(self TSRMLS_CC)) ) + while( (line = get_line(self)) ) { /* finished if we found the boundary */ if (!strcmp(line, boundary)) { @@ -401,27 +406,26 @@ static int find_boundary(multipart_buffer *self, char *boundary TSRMLS_DC) } /* parse headers */ -static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header TSRMLS_DC) +static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header) { char *line; mime_header_entry entry = {0}; - smart_str buf_value = {0}; + smart_string buf_value = {0}; char *key = NULL; /* didn't find boundary, abort */ - if (!find_boundary(self, self->boundary TSRMLS_CC)) { + if (!find_boundary(self, self->boundary)) { return 0; } /* get lines of text, or CRLF_CRLF */ - while( (line = get_line(self TSRMLS_CC)) && line[0] != '\0' ) - { + while ((line = get_line(self)) && line[0] != '\0') { /* add header to table */ char *value = NULL; - if (php_rfc1867_encoding_translation(TSRMLS_C)) { - self->input_encoding = zend_multibyte_encoding_detector((unsigned char *)line, strlen(line), self->detect_order, self->detect_order_size TSRMLS_CC); + if (php_rfc1867_encoding_translation()) { + self->input_encoding = zend_multibyte_encoding_detector((const unsigned char *) line, strlen(line), self->detect_order, self->detect_order_size); } /* space in the beginning means same header */ @@ -430,9 +434,9 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T } if (value) { - if(buf_value.c && key) { + if (buf_value.c && key) { /* new entry, add the old one to the list */ - smart_str_0(&buf_value); + smart_string_0(&buf_value); entry.key = key; entry.value = buf_value.c; zend_llist_add_element(header, &entry); @@ -441,19 +445,20 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T } *value = '\0'; - do { value++; } while(isspace(*value)); + do { value++; } while (isspace(*value)); key = estrdup(line); - smart_str_appends(&buf_value, value); + smart_string_appends(&buf_value, value); } else if (buf_value.c) { /* If no ':' on the line, add to previous line */ - smart_str_appends(&buf_value, line); + smart_string_appends(&buf_value, line); } else { continue; } } - if(buf_value.c && key) { + + if (buf_value.c && key) { /* add the last one to the list */ - smart_str_0(&buf_value); + smart_string_0(&buf_value); entry.key = key; entry.value = buf_value.c; zend_llist_add_element(header, &entry); @@ -481,7 +486,7 @@ static char *php_mime_get_hdr_value(zend_llist header, char *key) return NULL; } -static char *php_ap_getword(const zend_encoding *encoding, char **line, char stop TSRMLS_DC) +static char *php_ap_getword(const zend_encoding *encoding, char **line, char stop) { char *pos = *line, quote; char *res; @@ -535,7 +540,7 @@ static char *substring_conf(char *start, int len, char quote) return result; } -static char *php_ap_getword_conf(const zend_encoding *encoding, char *str TSRMLS_DC) +static char *php_ap_getword_conf(const zend_encoding *encoding, char *str) { while (*str && isspace(*str)) { ++str; @@ -549,7 +554,7 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str TSRMLS char quote = *str; str++; - return substring_conf(str, strlen(str), quote); + return substring_conf(str, (int)strlen(str), quote); } else { char *strend = str; @@ -560,7 +565,7 @@ static char *php_ap_getword_conf(const zend_encoding *encoding, char *str TSRMLS } } -static char *php_ap_basename(const zend_encoding *encoding, char *path TSRMLS_DC) +static char *php_ap_basename(const zend_encoding *encoding, char *path) { char *s = strrchr(path, '\\'); char *s2 = strrchr(path, '/'); @@ -609,14 +614,14 @@ static void *php_ap_memstr(char *haystack, int haystacklen, char *needle, int ne } /* read until a boundary condition */ -static int multipart_buffer_read(multipart_buffer *self, char *buf, int bytes, int *end TSRMLS_DC) +static int multipart_buffer_read(multipart_buffer *self, char *buf, size_t bytes, int *end) { - int len, max; + size_t len, max; char *bound; /* fill buffer if needed */ if (bytes > self->bytes_in_buffer) { - fill_buffer(self TSRMLS_CC); + fill_buffer(self); } /* look for a potential boundary match, only read data up to that point */ @@ -644,23 +649,23 @@ static int multipart_buffer_read(multipart_buffer *self, char *buf, int bytes, i } /* update the buffer */ - self->bytes_in_buffer -= len; + self->bytes_in_buffer -= (int)len; self->buf_begin += len; } - return len; + return (int)len; } /* XXX: this is horrible memory-usage-wise, but we only expect to do this on small pieces of form data. */ -static char *multipart_buffer_read_body(multipart_buffer *self, unsigned int *len TSRMLS_DC) +static char *multipart_buffer_read_body(multipart_buffer *self, size_t *len) { char buf[FILLUNIT], *out=NULL; int total_bytes=0, read_bytes=0; - while((read_bytes = multipart_buffer_read(self, buf, sizeof(buf), NULL TSRMLS_CC))) { + while((read_bytes = multipart_buffer_read(self, buf, sizeof(buf), NULL))) { out = erealloc(out, total_bytes + read_bytes + 1); memcpy(out + total_bytes, buf, read_bytes); total_bytes += read_bytes; @@ -683,11 +688,11 @@ static char *multipart_buffer_read_body(multipart_buffer *self, unsigned int *le SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ { char *boundary, *s = NULL, *boundary_end = NULL, *start_arr = NULL, *array_index = NULL; - char *temp_filename = NULL, *lbuf = NULL, *abuf = NULL; + char *lbuf = NULL, *abuf = NULL; + zend_string *temp_filename = NULL; int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0; int64_t total_bytes = 0, max_file_size = 0; int skip_upload = 0, anonindex = 0, is_anonymous; - zval *http_post_files = NULL; HashTable *uploaded_files = NULL; multipart_buffer *mbuff; zval *array_ptr = (zval *) arg; @@ -696,13 +701,13 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ void *event_extra_data = NULL; unsigned int llen = 0; int upload_cnt = INI_INT("max_file_uploads"); - const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C); + const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(); php_rfc1867_getword_t getword; php_rfc1867_getword_conf_t getword_conf; php_rfc1867_basename_t _basename; - long count = 0; + zend_long count = 0; - if (php_rfc1867_encoding_translation(TSRMLS_C) && internal_encoding) { + if (php_rfc1867_encoding_translation() && internal_encoding) { getword = php_rfc1867_getword; getword_conf = php_rfc1867_getword_conf; _basename = php_rfc1867_basename; @@ -713,14 +718,14 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } if (SG(post_max_size) > 0 && SG(request_info).content_length > SG(post_max_size)) { - sapi_module.sapi_error(E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size)); + sapi_module.sapi_error(E_WARNING, "POST Content-Length of " ZEND_LONG_FMT " bytes exceeds the limit of " ZEND_LONG_FMT " bytes", SG(request_info).content_length, SG(post_max_size)); return; } /* Get the boundary */ boundary = strstr(content_type_dup, "boundary"); if (!boundary) { - int content_type_len = strlen(content_type_dup); + int content_type_len = (int)strlen(content_type_dup); char *content_type_lcase = estrndup(content_type_dup, content_type_len); php_strtolower(content_type_lcase, content_type_len); @@ -737,7 +742,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } boundary++; - boundary_len = strlen(boundary); + boundary_len = (int)strlen(boundary); if (boundary[0] == '"') { boundary++; @@ -756,22 +761,22 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } /* Initialize the buffer */ - if (!(mbuff = multipart_buffer_new(boundary, boundary_len TSRMLS_CC))) { + if (!(mbuff = multipart_buffer_new(boundary, boundary_len))) { sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer"); return; } /* Initialize $_FILES[] */ - zend_hash_init(&PG(rfc1867_protected_variables), 5, NULL, NULL, 0); + zend_hash_init(&PG(rfc1867_protected_variables), 8, NULL, NULL, 0); ALLOC_HASHTABLE(uploaded_files); - zend_hash_init(uploaded_files, 5, NULL, (dtor_func_t) free_estring, 0); + zend_hash_init(uploaded_files, 8, NULL, free_filename, 0); SG(rfc1867_uploaded_files) = uploaded_files; - ALLOC_ZVAL(http_post_files); - array_init(http_post_files); - INIT_PZVAL(http_post_files); - PG(http_globals)[TRACK_VARS_FILES] = http_post_files; + if (Z_TYPE(PG(http_globals)[TRACK_VARS_FILES]) != IS_ARRAY) { + /* php_auto_globals_create_files() might have already done that */ + array_init(&PG(http_globals)[TRACK_VARS_FILES]); + } zend_llist_init(&header, sizeof(mime_header_entry), (llist_dtor_func_t) php_free_hdr_entry, 0); @@ -779,21 +784,21 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ multipart_event_start event_start; event_start.content_length = SG(request_info).content_length; - if (php_rfc1867_callback(MULTIPART_EVENT_START, &event_start, &event_extra_data TSRMLS_CC) == FAILURE) { + if (php_rfc1867_callback(MULTIPART_EVENT_START, &event_start, &event_extra_data) == FAILURE) { goto fileupload_done; } } - while (!multipart_buffer_eof(mbuff TSRMLS_CC)) + while (!multipart_buffer_eof(mbuff)) { char buff[FILLUNIT]; char *cd = NULL, *param = NULL, *filename = NULL, *tmp = NULL; size_t blen = 0, wlen = 0; - off_t offset; + zend_off_t offset; zend_llist_clean(&header); - if (!multipart_buffer_headers(mbuff, &header TSRMLS_CC)) { + if (!multipart_buffer_headers(mbuff, &header)) { goto fileupload_done; } @@ -805,7 +810,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ ++cd; } - while (*cd && (pair = getword(mbuff->input_encoding, &cd, ';' TSRMLS_CC))) + while (*cd && (pair = getword(mbuff->input_encoding, &cd, ';'))) { char *key = NULL, *word = pair; @@ -814,17 +819,17 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } if (strchr(pair, '=')) { - key = getword(mbuff->input_encoding, &pair, '=' TSRMLS_CC); + key = getword(mbuff->input_encoding, &pair, '='); if (!strcasecmp(key, "name")) { if (param) { efree(param); } - param = getword_conf(mbuff->input_encoding, pair TSRMLS_CC); + param = getword_conf(mbuff->input_encoding, pair); if (mbuff->input_encoding && internal_encoding) { unsigned char *new_param; size_t new_param_len; - if ((size_t)-1 != zend_multibyte_encoding_converter(&new_param, &new_param_len, (unsigned char *)param, strlen(param), internal_encoding, mbuff->input_encoding TSRMLS_CC)) { + if ((size_t)-1 != zend_multibyte_encoding_converter(&new_param, &new_param_len, (unsigned char *)param, strlen(param), internal_encoding, mbuff->input_encoding)) { efree(param); param = (char *)new_param; } @@ -833,11 +838,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ if (filename) { efree(filename); } - filename = getword_conf(mbuff->input_encoding, pair TSRMLS_CC); + filename = getword_conf(mbuff->input_encoding, pair); if (mbuff->input_encoding && internal_encoding) { unsigned char *new_filename; size_t new_filename_len; - if ((size_t)-1 != zend_multibyte_encoding_converter(&new_filename, &new_filename_len, (unsigned char *)filename, strlen(filename), internal_encoding, mbuff->input_encoding TSRMLS_CC)) { + if ((size_t)-1 != zend_multibyte_encoding_converter(&new_filename, &new_filename_len, (unsigned char *)filename, strlen(filename), internal_encoding, mbuff->input_encoding)) { efree(filename); filename = (char *)new_filename; } @@ -852,9 +857,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ /* Normal form variable, safe to read all data into memory */ if (!filename && param) { - unsigned int value_len; - char *value = multipart_buffer_read_body(mbuff, &value_len TSRMLS_CC); - unsigned int new_val_len; /* Dummy variable */ + size_t value_len; + char *value = multipart_buffer_read_body(mbuff, &value_len); + size_t new_val_len; /* Dummy variable */ if (!value) { value = estrdup(""); @@ -864,14 +869,14 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ if (mbuff->input_encoding && internal_encoding) { unsigned char *new_value; size_t new_value_len; - if ((size_t)-1 != zend_multibyte_encoding_converter(&new_value, &new_value_len, (unsigned char *)value, value_len, internal_encoding, mbuff->input_encoding TSRMLS_CC)) { + if ((size_t)-1 != zend_multibyte_encoding_converter(&new_value, &new_value_len, (unsigned char *)value, value_len, internal_encoding, mbuff->input_encoding)) { efree(value); value = (char *)new_value; value_len = new_value_len; } } - if (++count <= PG(max_input_vars) && sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC)) { + if (++count <= PG(max_input_vars) && sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len)) { if (php_rfc1867_callback != NULL) { multipart_event_formdata event_formdata; size_t newlength = new_val_len; @@ -881,17 +886,17 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ event_formdata.value = &value; event_formdata.length = new_val_len; event_formdata.newlength = &newlength; - if (php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC) == FAILURE) { + if (php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data) == FAILURE) { efree(param); efree(value); continue; } new_val_len = newlength; } - safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC); + safe_php_register_variable(param, value, new_val_len, array_ptr, 0); } else { if (count == PG(max_input_vars) + 1) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); + php_error_docref(NULL, E_WARNING, "Input variables exceeded " ZEND_LONG_FMT ". To increase the limit change max_input_vars in php.ini.", PG(max_input_vars)); } if (php_rfc1867_callback != NULL) { @@ -902,7 +907,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ event_formdata.value = &value; event_formdata.length = value_len; event_formdata.newlength = NULL; - php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC); + php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data); } } @@ -978,8 +983,8 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ event_file_start.post_bytes_processed = SG(read_post_bytes); event_file_start.name = param; event_file_start.filename = &filename; - if (php_rfc1867_callback(MULTIPART_EVENT_FILE_START, &event_file_start, &event_extra_data TSRMLS_CC) == FAILURE) { - temp_filename = ""; + if (php_rfc1867_callback(MULTIPART_EVENT_FILE_START, &event_file_start, &event_extra_data) == FAILURE) { + temp_filename = NULL; efree(param); efree(filename); continue; @@ -1004,14 +1009,14 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ if (!cancel_upload) { /* only bother to open temp file if we have data */ - blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC); + blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end); #if DEBUG_FILE_UPLOAD if (blen > 0) { #else /* in non-debug mode we have no problem with 0-length files */ { #endif - fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, 1 TSRMLS_CC); + fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, 1); upload_cnt--; if (fd == -1) { sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file"); @@ -1030,24 +1035,28 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ event_file_data.data = buff; event_file_data.length = blen; event_file_data.newlength = &blen; - if (php_rfc1867_callback(MULTIPART_EVENT_FILE_DATA, &event_file_data, &event_extra_data TSRMLS_CC) == FAILURE) { + if (php_rfc1867_callback(MULTIPART_EVENT_FILE_DATA, &event_file_data, &event_extra_data) == FAILURE) { cancel_upload = UPLOAD_ERROR_X; continue; } } - if (PG(upload_max_filesize) > 0 && (long)(total_bytes+blen) > PG(upload_max_filesize)) { + if (PG(upload_max_filesize) > 0 && (zend_long)(total_bytes+blen) > PG(upload_max_filesize)) { #if DEBUG_FILE_UPLOAD - sapi_module.sapi_error(E_NOTICE, "upload_max_filesize of %ld bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename); + sapi_module.sapi_error(E_NOTICE, "upload_max_filesize of " ZEND_LONG_FMT " bytes exceeded - file [%s=%s] not saved", PG(upload_max_filesize), param, filename); #endif cancel_upload = UPLOAD_ERROR_A; - } else if (max_file_size && ((long)(total_bytes+blen) > max_file_size)) { + } else if (max_file_size && ((zend_long)(total_bytes+blen) > max_file_size)) { #if DEBUG_FILE_UPLOAD - sapi_module.sapi_error(E_NOTICE, "MAX_FILE_SIZE of %ld bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); + sapi_module.sapi_error(E_NOTICE, "MAX_FILE_SIZE of " ZEND_LONG_FMT " bytes exceeded - file [%s=%s] not saved", max_file_size, param, filename); #endif cancel_upload = UPLOAD_ERROR_B; } else if (blen > 0) { +#ifdef PHP_WIN32 + wlen = write(fd, buff, (unsigned int)blen); +#else wlen = write(fd, buff, blen); +#endif if (wlen == -1) { /* write failed */ @@ -1067,7 +1076,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } /* read data for next iteration */ - blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end TSRMLS_CC); + blen = multipart_buffer_read(mbuff, buff, sizeof(buff), &end); } if (fd != -1) { /* may not be initialized if file could not be created */ @@ -1090,9 +1099,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ multipart_event_file_end event_file_end; event_file_end.post_bytes_processed = SG(read_post_bytes); - event_file_end.temp_filename = temp_filename; + event_file_end.temp_filename = ZSTR_VAL(temp_filename); event_file_end.cancel_upload = cancel_upload; - if (php_rfc1867_callback(MULTIPART_EVENT_FILE_END, &event_file_end, &event_extra_data TSRMLS_CC) == FAILURE) { + if (php_rfc1867_callback(MULTIPART_EVENT_FILE_END, &event_file_end, &event_extra_data) == FAILURE) { cancel_upload = UPLOAD_ERROR_X; } } @@ -1100,13 +1109,13 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ if (cancel_upload) { if (temp_filename) { if (cancel_upload != UPLOAD_ERROR_E) { /* file creation failed */ - unlink(temp_filename); + unlink(ZSTR_VAL(temp_filename)); } - efree(temp_filename); + zend_string_release(temp_filename); } - temp_filename = ""; + temp_filename = NULL; } else { - zend_hash_add(SG(rfc1867_uploaded_files), temp_filename, strlen(temp_filename) + 1, &temp_filename, sizeof(char *), NULL); + zend_hash_add_ptr(SG(rfc1867_uploaded_files), temp_filename, temp_filename); } /* is_arr_upload is true when name of file upload field @@ -1115,7 +1124,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ is_arr_upload = (start_arr = strchr(param,'[')) && (param[strlen(param)-1] == ']'); if (is_arr_upload) { - array_len = strlen(start_arr); + array_len = (int)strlen(start_arr); if (array_index) { efree(array_index); } @@ -1124,7 +1133,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ /* Add $foo_name */ if (llen < strlen(param) + MAX_SIZE_OF_INDEX + 1) { - llen = strlen(param); + llen = (int)strlen(param); lbuf = (char *) safe_erealloc(lbuf, llen, 1, MAX_SIZE_OF_INDEX + 1); llen += MAX_SIZE_OF_INDEX + 1; } @@ -1142,13 +1151,13 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ * the full path of the file on the user's filesystem, which means that unless * the user does basename() they get a bogus file name. Until IE's user base drops * to nill or problem is fixed this code must remain enabled for all systems. */ - s = _basename(internal_encoding, filename TSRMLS_CC); + s = _basename(internal_encoding, filename); if (!s) { s = filename; } if (!is_anonymous) { - safe_php_register_variable(lbuf, s, strlen(s), NULL, 0 TSRMLS_CC); + safe_php_register_variable(lbuf, s, strlen(s), NULL, 0); } /* Add $foo[name] */ @@ -1157,7 +1166,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } else { snprintf(lbuf, llen, "%s[name]", param); } - register_http_post_files_variable(lbuf, s, http_post_files, 0 TSRMLS_CC); + register_http_post_files_variable(lbuf, s, &PG(http_globals)[TRACK_VARS_FILES], 0); efree(filename); s = NULL; @@ -1179,7 +1188,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ snprintf(lbuf, llen, "%s_type", param); } if (!is_anonymous) { - safe_php_register_variable(lbuf, cd, strlen(cd), NULL, 0 TSRMLS_CC); + safe_php_register_variable(lbuf, cd, strlen(cd), NULL, 0); } /* Add $foo[type] */ @@ -1188,7 +1197,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } else { snprintf(lbuf, llen, "%s[type]", param); } - register_http_post_files_variable(lbuf, cd, http_post_files, 0 TSRMLS_CC); + register_http_post_files_variable(lbuf, cd, &PG(http_globals)[TRACK_VARS_FILES], 0); /* Restore Content-Type Header */ if (s != NULL) { @@ -1202,12 +1211,16 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ zval zfilename; /* Initialize variables */ - add_protected_variable(param TSRMLS_CC); + add_protected_variable(param); /* if param is of form xxx[.*] this will cut it to xxx */ if (!is_anonymous) { - ZVAL_STRING(&zfilename, temp_filename, 1); - safe_php_register_variable_ex(param, &zfilename, NULL, 1 TSRMLS_CC); + if (temp_filename) { + ZVAL_STR_COPY(&zfilename, temp_filename); + } else { + ZVAL_EMPTY_STRING(&zfilename); + } + safe_php_register_variable_ex(param, &zfilename, NULL, 1); } /* Add $foo[tmp_name] */ @@ -1216,9 +1229,13 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } else { snprintf(lbuf, llen, "%s[tmp_name]", param); } - add_protected_variable(lbuf TSRMLS_CC); - ZVAL_STRING(&zfilename, temp_filename, 1); - register_http_post_files_variable_ex(lbuf, &zfilename, http_post_files, 1 TSRMLS_CC); + add_protected_variable(lbuf); + if (temp_filename) { + ZVAL_STR_COPY(&zfilename, temp_filename); + } else { + ZVAL_EMPTY_STRING(&zfilename); + } + register_http_post_files_variable_ex(lbuf, &zfilename, &PG(http_globals)[TRACK_VARS_FILES], 1); } { @@ -1232,7 +1249,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ if (cancel_upload) { ZVAL_LONG(&file_size, 0); } else { - if (total_bytes > LONG_MAX) { + if (total_bytes > ZEND_LONG_MAX) { #ifdef PHP_WIN32 if (_i64toa_s(total_bytes, file_size_buf, 65, 10)) { file_size_buf[0] = '0'; @@ -1256,7 +1273,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } else { snprintf(lbuf, llen, "%s[error]", param); } - register_http_post_files_variable_ex(lbuf, &error_type, http_post_files, 0 TSRMLS_CC); + register_http_post_files_variable_ex(lbuf, &error_type, &PG(http_globals)[TRACK_VARS_FILES], 0); /* Add $foo_size */ if (is_arr_upload) { @@ -1266,9 +1283,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ } if (!is_anonymous) { if (size_overflow) { - ZVAL_STRING(&file_size, file_size_buf, 1); + ZVAL_STRING(&file_size, file_size_buf); } - safe_php_register_variable_ex(lbuf, &file_size, NULL, size_overflow TSRMLS_CC); + safe_php_register_variable_ex(lbuf, &file_size, NULL, size_overflow); } /* Add $foo[size] */ @@ -1278,9 +1295,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ snprintf(lbuf, llen, "%s[size]", param); } if (size_overflow) { - ZVAL_STRING(&file_size, file_size_buf, 1); + ZVAL_STRING(&file_size, file_size_buf); } - register_http_post_files_variable_ex(lbuf, &file_size, http_post_files, size_overflow TSRMLS_CC); + register_http_post_files_variable_ex(lbuf, &file_size, &PG(http_globals)[TRACK_VARS_FILES], size_overflow); } efree(param); } @@ -1291,7 +1308,7 @@ fileupload_done: multipart_event_end event_end; event_end.post_bytes_processed = SG(read_post_bytes); - php_rfc1867_callback(MULTIPART_EVENT_END, &event_end, &event_extra_data TSRMLS_CC); + php_rfc1867_callback(MULTIPART_EVENT_END, &event_end, &event_extra_data); } if (lbuf) efree(lbuf); diff --git a/main/rfc1867.h b/main/rfc1867.h index 50dd5287f1..1015e6e591 100644 --- a/main/rfc1867.h +++ b/main/rfc1867.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -51,10 +51,10 @@ typedef struct _multipart_event_file_start { typedef struct _multipart_event_file_data { size_t post_bytes_processed; - off_t offset; + zend_off_t offset; char *data; size_t length; - size_t *newlength; + size_t *newlength; } multipart_event_file_data; typedef struct _multipart_event_file_end { @@ -67,18 +67,18 @@ typedef struct _multipart_event_end { size_t post_bytes_processed; } multipart_event_end; -typedef int (*php_rfc1867_encoding_translation_t)(TSRMLS_D); -typedef void (*php_rfc1867_get_detect_order_t)(const zend_encoding ***list, size_t *list_size TSRMLS_DC); -typedef void (*php_rfc1867_set_input_encoding_t)(const zend_encoding *encoding TSRMLS_DC); -typedef char* (*php_rfc1867_getword_t)(const zend_encoding *encoding, char **line, char stop TSRMLS_DC); -typedef char* (*php_rfc1867_getword_conf_t)(const zend_encoding *encoding, char *str TSRMLS_DC); -typedef char* (*php_rfc1867_basename_t)(const zend_encoding *encoding, char *str TSRMLS_DC); +typedef int (*php_rfc1867_encoding_translation_t)(void); +typedef void (*php_rfc1867_get_detect_order_t)(const zend_encoding ***list, size_t *list_size); +typedef void (*php_rfc1867_set_input_encoding_t)(const zend_encoding *encoding); +typedef char* (*php_rfc1867_getword_t)(const zend_encoding *encoding, char **line, char stop); +typedef char* (*php_rfc1867_getword_conf_t)(const zend_encoding *encoding, char *str); +typedef char* (*php_rfc1867_basename_t)(const zend_encoding *encoding, char *str); SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler); -void destroy_uploaded_files_hash(TSRMLS_D); -void php_rfc1867_register_constants(TSRMLS_D); -extern PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra TSRMLS_DC); +PHPAPI void destroy_uploaded_files_hash(void); +void php_rfc1867_register_constants(void); +extern PHPAPI int (*php_rfc1867_callback)(unsigned int event, void *event_data, void **extra); SAPI_API void php_rfc1867_set_multibyte_callbacks( php_rfc1867_encoding_translation_t encoding_translation, @@ -86,6 +86,6 @@ SAPI_API void php_rfc1867_set_multibyte_callbacks( php_rfc1867_set_input_encoding_t set_input_encoding, php_rfc1867_getword_t getword, php_rfc1867_getword_conf_t getword_conf, - php_rfc1867_basename_t basename); + php_rfc1867_basename_t basename); #endif /* RFC1867_H */ diff --git a/main/snprintf.c b/main/snprintf.c index e5167d7459..aff6a8cbda 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -317,7 +317,7 @@ PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, c */ /* char * ap_php_conv_10() {{{ */ PHPAPI char * ap_php_conv_10(register wide_int num, register bool_int is_unsigned, - register bool_int * is_negative, char *buf_end, register int *len) + register bool_int * is_negative, char *buf_end, register size_t *len) { register char *p = buf_end; register u_wide_int magnitude; @@ -375,7 +375,7 @@ PHPAPI char * ap_php_conv_10(register wide_int num, register bool_int is_unsigne */ /* PHPAPI char * php_conv_fp() {{{ */ PHPAPI char * php_conv_fp(register char format, register double num, - boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, int *len) + boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, size_t *len) { register char *s = buf; register char *p, *p_orig; @@ -443,7 +443,7 @@ PHPAPI char * php_conv_fp(register char format, register double num, if (format != 'F') { char temp[EXPONENT_LENGTH]; /* for exponent conversion */ - int t_len; + size_t t_len; bool_int exponent_is_negative; *s++ = format; /* either e or E */ @@ -479,7 +479,7 @@ PHPAPI char * php_conv_fp(register char format, register double num, * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) */ -PHPAPI char * ap_php_conv_p2(register u_wide_int num, register int nbits, char format, char *buf_end, register int *len) /* {{{ */ +PHPAPI char * ap_php_conv_p2(register u_wide_int num, register int nbits, char format, char *buf_end, register size_t *len) /* {{{ */ { register int mask = (1 << nbits) - 1; register char *p = buf_end; @@ -589,10 +589,11 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / char *sp; char *bep; int cc = 0; - int i; + size_t i; char *s = NULL; - int s_len, free_zcopy; + size_t s_len; + int free_zcopy; zval *zvp, zcopy; int min_width = 0; @@ -701,7 +702,7 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / precision = 0; } else precision = 0; - + if (precision > FORMAT_CONV_MAX_PRECISION) { precision = FORMAT_CONV_MAX_PRECISION; } @@ -767,6 +768,10 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / modifier = LM_SIZE_T; #endif break; + case 'p': + fmt++; + modifier = LM_PHP_INT_T; + break; case 'h': fmt++; if (*fmt == 'h') { @@ -790,9 +795,9 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / * It is reset to ' ' by non-numeric formats */ switch (*fmt) { - case 'Z': - zvp = (zval*) va_arg(ap, zval*); - zend_make_printable_zval(zvp, &zcopy, &free_zcopy); + case 'Z': { + zvp = (zval*) va_arg(ap, zval*); + free_zcopy = zend_make_printable_zval(zvp, &zcopy); if (free_zcopy) { zvp = &zcopy; } @@ -802,6 +807,7 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / s_len = precision; } break; + } case 'u': switch(modifier) { default: @@ -830,6 +836,9 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / i_num = (wide_int) va_arg(ap, ptrdiff_t); break; #endif + case LM_PHP_INT_T: + i_num = (wide_int) va_arg(ap, zend_ulong); + break; } /* * The rest also applies to other integer formats, so fall @@ -872,6 +881,9 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / i_num = (wide_int) va_arg(ap, ptrdiff_t); break; #endif + case LM_PHP_INT_T: + i_num = (wide_int) va_arg(ap, zend_long); + break; } } s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative, @@ -918,6 +930,9 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); break; #endif + case LM_PHP_INT_T: + ui_num = (u_wide_int) va_arg(ap, zend_ulong); + break; } s = ap_php_conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); FIX_PRECISION(adjust_precision, precision, s, s_len); @@ -957,6 +972,9 @@ static int format_converter(register buffy * odp, const char *fmt, va_list ap) / ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); break; #endif + case LM_PHP_INT_T: + ui_num = (u_wide_int) va_arg(ap, zend_ulong); + break; } s = ap_php_conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); FIX_PRECISION(adjust_precision, precision, s, s_len); @@ -1239,14 +1257,14 @@ static void strx_printv(int *ccp, char *buf, size_t len, const char *format, va_ PHPAPI int ap_php_slprintf(char *buf, size_t len, const char *format,...) /* {{{ */ { - unsigned int cc; + int cc; va_list ap; va_start(ap, format); strx_printv(&cc, buf, len, format, ap); va_end(ap); if (cc >= len) { - cc = len -1; + cc = (int)len -1; buf[cc] = '\0'; } return cc; @@ -1255,11 +1273,11 @@ PHPAPI int ap_php_slprintf(char *buf, size_t len, const char *format,...) /* {{{ PHPAPI int ap_php_vslprintf(char *buf, size_t len, const char *format, va_list ap) /* {{{ */ { - unsigned int cc; + int cc; strx_printv(&cc, buf, len, format, ap); if (cc >= len) { - cc = len -1; + cc = (int)len -1; buf[cc] = '\0'; } return cc; diff --git a/main/snprintf.h b/main/snprintf.h index b8d0496405..c40147ec2d 100644 --- a/main/snprintf.h +++ b/main/snprintf.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -31,7 +31,7 @@ sprintf offers the ability to make a lot of failures since it does not know snprintf knows the buffers size and will not write behind it. But you will have to use either a static buffer or allocate a dynamic buffer - before beeing able to call the function. In other words you must + before being able to call the function. In other words you must be sure that you really know the maximum size of the buffer required. A bad thing is having a big maximum while in most cases you would only need a small buffer. If the size of the resulting string is @@ -87,7 +87,7 @@ PHPAPI int ap_php_asprintf(char **buf, const char *format, ...); PHPAPI int php_sprintf (char* s, const char* format, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); PHPAPI char * php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf); PHPAPI char * php_conv_fp(register char format, register double num, - boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, int *len); + boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, size_t *len); END_EXTERN_C() @@ -137,7 +137,8 @@ typedef enum { #endif LM_SIZE_T, LM_LONG, - LM_LONG_DOUBLE + LM_LONG_DOUBLE, + LM_PHP_INT_T } length_modifier_e; #ifdef PHP_WIN32 @@ -153,10 +154,10 @@ typedef WIDE_INT wide_int; typedef unsigned WIDE_INT u_wide_int; PHPAPI char * ap_php_conv_10(register wide_int num, register bool_int is_unsigned, - register bool_int * is_negative, char *buf_end, register int *len); + register bool_int * is_negative, char *buf_end, register size_t *len); PHPAPI char * ap_php_conv_p2(register u_wide_int num, register int nbits, - char format, char *buf_end, register int *len); + char format, char *buf_end, register size_t *len); /* The maximum precision that's allowed for float conversion. Does not include * decimal separator, exponent, sign, terminator. Currently does not affect diff --git a/main/spprintf.c b/main/spprintf.c index 56ffe515c8..4594fb7605 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -116,10 +116,40 @@ #define FLOAT_DIGITS 6 #define EXPONENT_LENGTH 10 -#include "ext/standard/php_smart_str.h" +#include "zend_smart_str.h" +#include "ext/standard/php_smart_string.h" /* {{{ macros */ +#define INS_CHAR(xbuf, ch, is_char) do { \ + if ((is_char)) { \ + smart_string_appendc((smart_string *)(xbuf), (ch)); \ + } else { \ + smart_str_appendc((smart_str *)(xbuf), (ch)); \ + } \ +} while (0); + +#define INS_STRING(xbuf, str, len, is_char) do { \ + if ((is_char)) { \ + smart_string_appendl((smart_string *)(xbuf), (str), (len)); \ + } else { \ + smart_str_appendl((smart_str *)(xbuf), (str), (len)); \ + } \ +} while (0); + +#define PAD_CHAR(xbuf, ch, count, is_char) do { \ + size_t newlen; \ + if ((is_char)) { \ + smart_string_alloc(((smart_string *)(xbuf)), (count), 0); \ + memset(((smart_string *)(xbuf))->c + ((smart_string *)(xbuf))->len, (ch), (count)); \ + ((smart_string *)(xbuf))->len += (count); \ + } else { \ + smart_str_alloc(((smart_str *)(xbuf)), (count), 0); \ + memset(ZSTR_VAL(((smart_str *)(xbuf))->s) + ZSTR_LEN(((smart_str *)(xbuf))->s), (ch), (count)); \ + ZSTR_LEN(((smart_str *)(xbuf))->s) += (count); \ + } \ +} while (0); + /* * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions * @@ -130,35 +160,6 @@ */ #define NUM_BUF_SIZE 2048 -/* - * The INS_CHAR macro inserts a character in the buffer. - * - * NOTE: Evaluation of the ch argument should not have any side-effects - */ -#define INS_CHAR_NR(xbuf, ch) do { \ - smart_str_appendc(xbuf, ch); \ -} while (0) - -#define INS_STRING(xbuf, s, slen) do { \ - smart_str_appendl(xbuf, s, slen); \ -} while (0) - -#define INS_CHAR(xbuf, ch) \ - INS_CHAR_NR(xbuf, ch) - -/* - * Macro that does padding. The padding is done by printing - * the character ch. - */ -#define PAD(xbuf, count, ch) do { \ - if ((count) > 0) { \ - size_t newlen; \ - smart_str_alloc(xbuf, (count), 0); \ - memset(xbuf->c + xbuf->len, ch, (count)); \ - xbuf->len += (count); \ - } \ -} while (0) - #define NUM(c) (c - '0') #define STR_TO_DEC(str, num) do { \ @@ -189,7 +190,6 @@ /* }}} */ - #if !HAVE_STRNLEN static size_t strnlen(const char *s, size_t maxlen) { char *r = memchr(s, '\0', maxlen); @@ -200,10 +200,11 @@ static size_t strnlen(const char *s, size_t maxlen) { /* * Do format conversion placing the output in buffer */ -static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) /* {{{ */ +static void xbuf_format_converter(void *xbuf, zend_bool is_char, const char *fmt, va_list ap) /* {{{ */ { char *s = NULL; - int s_len, free_zcopy; + size_t s_len; + int free_zcopy; zval *zvp, zcopy; int min_width = 0; @@ -242,7 +243,7 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) while (*fmt) { if (*fmt != '%') { - INS_CHAR(xbuf, *fmt); + INS_CHAR(xbuf, *fmt, is_char); } else { /* * Default variable settings @@ -309,7 +310,7 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) precision = 0; } else precision = 0; - + if (precision > FORMAT_CONV_MAX_PRECISION) { precision = FORMAT_CONV_MAX_PRECISION; } @@ -375,6 +376,16 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) modifier = LM_SIZE_T; #endif break; + case 'p': { + char __next = *(fmt+1); + if ('d' == __next || 'u' == __next || 'x' == __next || 'o' == __next) { + fmt++; + modifier = LM_PHP_INT_T; + } else { + modifier = LM_STD; + } + } + break; case 'h': fmt++; if (*fmt == 'h') { @@ -398,9 +409,9 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) * It is reset to ' ' by non-numeric formats */ switch (*fmt) { - case 'Z': - zvp = (zval*) va_arg(ap, zval*); - zend_make_printable_zval(zvp, &zcopy, &free_zcopy); + case 'Z': { + zvp = (zval*) va_arg(ap, zval*); + free_zcopy = zend_make_printable_zval(zvp, &zcopy); if (free_zcopy) { zvp = &zcopy; } @@ -410,6 +421,7 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) s_len = precision; } break; + } case 'u': switch(modifier) { default: @@ -438,6 +450,9 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) i_num = (wide_int) va_arg(ap, ptrdiff_t); break; #endif + case LM_PHP_INT_T: + i_num = (wide_int) va_arg(ap, zend_ulong); + break; } /* * The rest also applies to other integer formats, so fall @@ -480,6 +495,9 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) i_num = (wide_int) va_arg(ap, ptrdiff_t); break; #endif + case LM_PHP_INT_T: + i_num = (wide_int) va_arg(ap, zend_long); + break; } } s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative, @@ -525,6 +543,9 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); break; #endif + case LM_PHP_INT_T: + ui_num = (u_wide_int) va_arg(ap, zend_ulong); + break; } s = ap_php_conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); @@ -565,6 +586,9 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) ui_num = (u_wide_int) va_arg(ap, ptrdiff_t); break; #endif + case LM_PHP_INT_T: + ui_num = (u_wide_int) va_arg(ap, zend_ulong); + break; } s = ap_php_conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); @@ -717,7 +741,7 @@ static void xbuf_format_converter(smart_str *xbuf, const char *fmt, va_list ap) case 'n': - *(va_arg(ap, int *)) = xbuf->len; + *(va_arg(ap, int *)) = is_char? (int)((smart_string *)xbuf)->len : (int)ZSTR_LEN(((smart_str *)xbuf)->s); goto skip_output; /* @@ -781,20 +805,22 @@ fmt_error: } if (adjust_width && adjust == RIGHT && min_width > s_len) { if (pad_char == '0' && prefix_char != NUL) { - INS_CHAR(xbuf, *s); + INS_CHAR(xbuf, *s, is_char); s++; s_len--; min_width--; } - PAD(xbuf, min_width - s_len, pad_char); + PAD_CHAR(xbuf, pad_char, min_width - s_len, is_char); } /* * Print the string s. */ - INS_STRING(xbuf, s, s_len); + INS_STRING(xbuf, s, s_len, is_char); + + if (adjust_width && adjust == LEFT && min_width > s_len) { + PAD_CHAR(xbuf, pad_char, min_width - s_len, is_char); + } - if (adjust_width && adjust == LEFT && min_width > s_len) - PAD(xbuf, min_width - s_len, pad_char); if (free_zcopy) { zval_dtor(&zcopy); } @@ -809,31 +835,36 @@ skip_output: /* * This is the general purpose conversion function. */ -PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */ +PHPAPI size_t vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */ { - smart_str xbuf = {0}; + smart_string buf = {0}; /* since there are places where (v)spprintf called without checking for null, a bit of defensive coding here */ if(!pbuf) { return 0; } - xbuf_format_converter(&xbuf, format, ap); + xbuf_format_converter(&buf, 1, format, ap); - if (max_len && xbuf.len > max_len) { - xbuf.len = max_len; + if (max_len && buf.len > max_len) { + buf.len = max_len; } - smart_str_0(&xbuf); - *pbuf = xbuf.c; + smart_string_0(&buf); - return xbuf.len; + if (buf.c) { + *pbuf = buf.c; + return buf.len; + } else { + *pbuf = estrndup("", 0); + return 0; + } } /* }}} */ -PHPAPI int spprintf(char **pbuf, size_t max_len, const char *format, ...) /* {{{ */ +PHPAPI size_t spprintf(char **pbuf, size_t max_len, const char *format, ...) /* {{{ */ { - int cc; + size_t cc; va_list ap; va_start(ap, format); @@ -843,6 +874,37 @@ PHPAPI int spprintf(char **pbuf, size_t max_len, const char *format, ...) /* {{{ } /* }}} */ +PHPAPI zend_string *vstrpprintf(size_t max_len, const char *format, va_list ap) /* {{{ */ +{ + smart_str buf = {0}; + + xbuf_format_converter(&buf, 0, format, ap); + + if (!buf.s) { + return ZSTR_EMPTY_ALLOC(); + } + + if (max_len && ZSTR_LEN(buf.s) > max_len) { + ZSTR_LEN(buf.s) = max_len; + } + + smart_str_0(&buf); + return buf.s; +} +/* }}} */ + +PHPAPI zend_string *strpprintf(size_t max_len, const char *format, ...) /* {{{ */ +{ + va_list ap; + zend_string *str; + + va_start(ap, format); + str = vstrpprintf(max_len, format, ap); + va_end(ap); + return str; +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/main/spprintf.h b/main/spprintf.h index d69e32e5b4..296e2f3012 100644 --- a/main/spprintf.h +++ b/main/spprintf.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -37,9 +37,13 @@ There is also snprintf: See difference explained in snprintf.h #include "snprintf.h" BEGIN_EXTERN_C() -PHPAPI int spprintf( char **pbuf, size_t max_len, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); +PHPAPI size_t spprintf( char **pbuf, size_t max_len, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4); -PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) PHP_ATTRIBUTE_FORMAT(printf, 3, 0); +PHPAPI size_t vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) PHP_ATTRIBUTE_FORMAT(printf, 3, 0); + +PHPAPI zend_string *vstrpprintf(size_t max_len, const char *format, va_list ap) PHP_ATTRIBUTE_FORMAT(printf, 2, 0); + +PHPAPI zend_string *strpprintf(size_t max_len, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); END_EXTERN_C() #endif /* SNPRINTF_H */ diff --git a/main/streams/cast.c b/main/streams/cast.c index e8956100cd..286541324e 100644 --- a/main/streams/cast.c +++ b/main/streams/cast.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -63,7 +63,6 @@ FILE *fopencookie(void *cookie, const char *mode, COOKIE_IO_FUNCTIONS_T *funcs) static int stream_cookie_reader(void *cookie, char *buffer, int size) { int ret; - TSRMLS_FETCH(); ret = php_stream_read((php_stream*)cookie, buffer, size); return ret; @@ -71,14 +70,12 @@ static int stream_cookie_reader(void *cookie, char *buffer, int size) static int stream_cookie_writer(void *cookie, const char *buffer, int size) { - TSRMLS_FETCH(); return php_stream_write((php_stream *)cookie, (char *)buffer, size); } -static PHP_FPOS_T stream_cookie_seeker(void *cookie, off_t position, int whence) +static PHP_FPOS_T stream_cookie_seeker(void *cookie, zend_off_t position, int whence) { - TSRMLS_FETCH(); return (PHP_FPOS_T)php_stream_seek((php_stream *)cookie, position, whence); } @@ -86,17 +83,15 @@ static PHP_FPOS_T stream_cookie_seeker(void *cookie, off_t position, int whence) static int stream_cookie_closer(void *cookie) { php_stream *stream = (php_stream*)cookie; - TSRMLS_FETCH(); /* prevent recursion */ stream->fclose_stdiocast = PHP_STREAM_FCLOSE_NONE; - return php_stream_close(stream); + return php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_KEEP_RSRC); } #elif defined(HAVE_FOPENCOOKIE) static ssize_t stream_cookie_reader(void *cookie, char *buffer, size_t size) { ssize_t ret; - TSRMLS_FETCH(); ret = php_stream_read(((php_stream *)cookie), buffer, size); return ret; @@ -104,7 +99,6 @@ static ssize_t stream_cookie_reader(void *cookie, char *buffer, size_t size) static ssize_t stream_cookie_writer(void *cookie, const char *buffer, size_t size) { - TSRMLS_FETCH(); return php_stream_write(((php_stream *)cookie), (char *)buffer, size); } @@ -112,9 +106,8 @@ static ssize_t stream_cookie_writer(void *cookie, const char *buffer, size_t siz # ifdef COOKIE_SEEKER_USES_OFF64_T static int stream_cookie_seeker(void *cookie, __off64_t *position, int whence) { - TSRMLS_FETCH(); - *position = php_stream_seek((php_stream *)cookie, (off_t)*position, whence); + *position = php_stream_seek((php_stream *)cookie, (zend_off_t)*position, whence); if (*position == -1) { return -1; @@ -122,9 +115,8 @@ static int stream_cookie_seeker(void *cookie, __off64_t *position, int whence) return 0; } # else -static int stream_cookie_seeker(void *cookie, off_t position, int whence) +static int stream_cookie_seeker(void *cookie, zend_off_t position, int whence) { - TSRMLS_FETCH(); return php_stream_seek((php_stream *)cookie, position, whence); } @@ -133,11 +125,10 @@ static int stream_cookie_seeker(void *cookie, off_t position, int whence) static int stream_cookie_closer(void *cookie) { php_stream *stream = (php_stream*)cookie; - TSRMLS_FETCH(); /* prevent recursion */ stream->fclose_stdiocast = PHP_STREAM_FCLOSE_NONE; - return php_stream_close(stream); + return php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_KEEP_RSRC); } #endif /* elif defined(HAVE_FOPENCOOKIE) */ @@ -156,7 +147,7 @@ static COOKIE_IO_FUNCTIONS_T stream_cookie_functions = * Result should have at least size 5, e.g. to write wbx+\0 */ void php_stream_mode_sanitize_fdopen_fopencookie(php_stream *stream, char *result) { - /* replace modes not supported by fdopen and fopencookie, but supported + /* replace modes not supported by fdopen and fopencookie, but supported * by PHP's fread(), so that their calls won't fail */ const char *cur_mode = stream->mode; int has_plus = 0, @@ -174,7 +165,7 @@ void php_stream_mode_sanitize_fdopen_fopencookie(php_stream *stream, char *resul /* x is allowed (at least by glibc & compat), but not as the 1st mode * as in PHP and in any case is (at best) ignored by fdopen and fopencookie */ } - + /* assume current mode has at most length 4 (e.g. wbn+) */ for (i = 1; i < 4 && cur_mode[i] != '\0'; i++) { if (cur_mode[i] == 'b') { @@ -197,7 +188,7 @@ void php_stream_mode_sanitize_fdopen_fopencookie(php_stream *stream, char *resul /* }}} */ /* {{{ php_stream_cast */ -PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err TSRMLS_DC) +PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show_err) { int flags = castas & PHP_STREAM_CAST_MASK; castas &= ~PHP_STREAM_CAST_MASK; @@ -206,9 +197,9 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show if (ret && castas != PHP_STREAM_AS_FD_FOR_SELECT) { php_stream_flush(stream); if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) { - off_t dummy; + zend_off_t dummy; - stream->ops->seek(stream, stream->position, SEEK_SET, &dummy TSRMLS_CC); + stream->ops->seek(stream, stream->position, SEEK_SET, &dummy); stream->readpos = stream->writepos = 0; } } @@ -228,7 +219,7 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show if (php_stream_is(stream, PHP_STREAM_IS_STDIO) && stream->ops->cast && !php_stream_is_filtered(stream) && - stream->ops->cast(stream, castas, ret TSRMLS_CC) == SUCCESS + stream->ops->cast(stream, castas, ret) == SUCCESS ) { goto exit_success; } @@ -246,7 +237,7 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show } if (*ret != NULL) { - off_t pos; + zend_off_t pos; stream->fclose_stdiocast = PHP_STREAM_FCLOSE_FOPENCOOKIE; @@ -254,7 +245,7 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show * the stdio layer to believe it's real location. */ pos = php_stream_tell(stream); if (pos > 0) { - fseek(*ret, pos, SEEK_SET); + zend_fseek(*ret, pos, SEEK_SET); } goto exit_success; @@ -265,12 +256,12 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show b) no memory -> lets bail */ - php_error_docref(NULL TSRMLS_CC, E_ERROR, "fopencookie failed"); + php_error_docref(NULL, E_ERROR, "fopencookie failed"); return FAILURE; #endif - if (!php_stream_is_filtered(stream) && stream->ops->cast && stream->ops->cast(stream, castas, NULL TSRMLS_CC) == SUCCESS) { - if (FAILURE == stream->ops->cast(stream, castas, ret TSRMLS_CC)) { + if (!php_stream_is_filtered(stream) && stream->ops->cast && stream->ops->cast(stream, castas, NULL) == SUCCESS) { + if (FAILURE == stream->ops->cast(stream, castas, ret)) { return FAILURE; } goto exit_success; @@ -304,9 +295,9 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show } if (php_stream_is_filtered(stream)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot cast a filtered stream on this system"); + php_error_docref(NULL, E_WARNING, "cannot cast a filtered stream on this system"); return FAILURE; - } else if (stream->ops->cast && stream->ops->cast(stream, castas, ret TSRMLS_CC) == SUCCESS) { + } else if (stream->ops->cast && stream->ops->cast(stream, castas, ret) == SUCCESS) { goto exit_success; } @@ -319,7 +310,7 @@ PHPAPI int _php_stream_cast(php_stream *stream, int castas, void **ret, int show "select()able descriptor" }; - php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot represent a stream of type %s as a %s", stream->ops->label, cast_names[castas]); + php_error_docref(NULL, E_WARNING, "cannot represent a stream of type %s as a %s", stream->ops->label, cast_names[castas]); } return FAILURE; @@ -334,7 +325,7 @@ exit_success: * will be accessing the stream. Emit a warning so that the end-user will * know that they should try something else */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%ld bytes of buffered data lost during stream conversion!", (long)(stream->writepos - stream->readpos)); + php_error_docref(NULL, E_WARNING, ZEND_LONG_FMT " bytes of buffered data lost during stream conversion!", (zend_long)(stream->writepos - stream->readpos)); } if (castas == PHP_STREAM_AS_STDIO && ret) { @@ -351,7 +342,7 @@ exit_success: /* }}} */ /* {{{ php_stream_open_wrapper_as_file */ -PHPAPI FILE * _php_stream_open_wrapper_as_file(char *path, char *mode, int options, char **opened_path STREAMS_DC TSRMLS_DC) +PHPAPI FILE * _php_stream_open_wrapper_as_file(char *path, char *mode, int options, zend_string **opened_path STREAMS_DC) { FILE *fp = NULL; php_stream *stream = NULL; @@ -365,7 +356,7 @@ PHPAPI FILE * _php_stream_open_wrapper_as_file(char *path, char *mode, int optio if (php_stream_cast(stream, PHP_STREAM_AS_STDIO|PHP_STREAM_CAST_TRY_HARD|PHP_STREAM_CAST_RELEASE, (void**)&fp, REPORT_ERRORS) == FAILURE) { php_stream_close(stream); if (opened_path && *opened_path) { - efree(*opened_path); + zend_string_release(*opened_path); } return NULL; } @@ -374,7 +365,7 @@ PHPAPI FILE * _php_stream_open_wrapper_as_file(char *path, char *mode, int optio /* }}} */ /* {{{ php_stream_make_seekable */ -PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC TSRMLS_DC) +PHPAPI int _php_stream_make_seekable(php_stream *origstream, php_stream **newstream, int flags STREAMS_DC) { if (newstream == NULL) { return PHP_STREAM_FAILED; diff --git a/main/streams/filter.c b/main/streams/filter.c index f349be4914..b4705aa113 100644 --- a/main/streams/filter.c +++ b/main/streams/filter.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -38,39 +38,37 @@ PHPAPI HashTable *php_get_stream_filters_hash_global(void) } /* Normal hash selection/retrieval call */ -PHPAPI HashTable *_php_get_stream_filters_hash(TSRMLS_D) +PHPAPI HashTable *_php_get_stream_filters_hash(void) { return (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash); } /* API for registering GLOBAL filters */ -PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC) +PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory) { - return zend_hash_add(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern) + 1, factory, sizeof(*factory), NULL); + return zend_hash_str_add_ptr(&stream_filters_hash, filterpattern, strlen(filterpattern), factory) ? SUCCESS : FAILURE; } -PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern TSRMLS_DC) +PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern) { - return zend_hash_del(&stream_filters_hash, (char*)filterpattern, strlen(filterpattern) + 1); + return zend_hash_str_del(&stream_filters_hash, filterpattern, strlen(filterpattern)); } /* API for registering VOLATILE wrappers */ -PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC) +PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory) { if (!FG(stream_filters)) { - php_stream_filter_factory tmpfactory; - ALLOC_HASHTABLE(FG(stream_filters)); zend_hash_init(FG(stream_filters), zend_hash_num_elements(&stream_filters_hash), NULL, NULL, 1); - zend_hash_copy(FG(stream_filters), &stream_filters_hash, NULL, &tmpfactory, sizeof(php_stream_filter_factory)); + zend_hash_copy(FG(stream_filters), &stream_filters_hash, NULL); } - return zend_hash_add(FG(stream_filters), (char*)filterpattern, strlen(filterpattern) + 1, factory, sizeof(*factory), NULL); + return zend_hash_str_add_ptr(FG(stream_filters), (char*)filterpattern, strlen(filterpattern), factory) ? SUCCESS : FAILURE; } /* Buckets */ -PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent TSRMLS_DC) +PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent) { int is_persistent = php_stream_is_persistent(stream); php_stream_bucket *bucket; @@ -80,18 +78,18 @@ PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, s if (bucket == NULL) { return NULL; } - + bucket->next = bucket->prev = NULL; if (is_persistent && !buf_persistent) { /* all data in a persistent bucket must also be persistent */ bucket->buf = pemalloc(buflen, 1); - + if (bucket->buf == NULL) { pefree(bucket, 1); return NULL; } - + memcpy(bucket->buf, buf, buflen); bucket->buflen = buflen; bucket->own_buf = 1; @@ -114,12 +112,12 @@ PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, s * In both cases, the original bucket is unlinked from its brigade. * If a copy is made, the original bucket is delref'd. * */ -PHPAPI php_stream_bucket *php_stream_bucket_make_writeable(php_stream_bucket *bucket TSRMLS_DC) +PHPAPI php_stream_bucket *php_stream_bucket_make_writeable(php_stream_bucket *bucket) { php_stream_bucket *retval; - php_stream_bucket_unlink(bucket TSRMLS_CC); - + php_stream_bucket_unlink(bucket); + if (bucket->refcount == 1 && bucket->own_buf) { return bucket; } @@ -133,12 +131,12 @@ PHPAPI php_stream_bucket *php_stream_bucket_make_writeable(php_stream_bucket *bu retval->refcount = 1; retval->own_buf = 1; - php_stream_bucket_delref(bucket TSRMLS_CC); - + php_stream_bucket_delref(bucket); + return retval; } -PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length TSRMLS_DC) +PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length) { *left = (php_stream_bucket*)pecalloc(1, sizeof(php_stream_bucket), in->is_persistent); *right = (php_stream_bucket*)pecalloc(1, sizeof(php_stream_bucket), in->is_persistent); @@ -153,16 +151,16 @@ PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **le (*left)->refcount = 1; (*left)->own_buf = 1; (*left)->is_persistent = in->is_persistent; - + (*right)->buflen = in->buflen - length; (*right)->buf = pemalloc((*right)->buflen, in->is_persistent); memcpy((*right)->buf, in->buf + length, (*right)->buflen); (*right)->refcount = 1; (*right)->own_buf = 1; (*right)->is_persistent = in->is_persistent; - + return SUCCESS; - + exit_fail: if (*right) { if ((*right)->buf) { @@ -179,7 +177,7 @@ exit_fail: return FAILURE; } -PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket TSRMLS_DC) +PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket) { if (--bucket->refcount == 0) { if (bucket->own_buf) { @@ -189,7 +187,7 @@ PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket TSRMLS_DC) } } -PHPAPI void php_stream_bucket_prepend(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC) +PHPAPI void php_stream_bucket_prepend(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket) { bucket->next = brigade->head; bucket->prev = NULL; @@ -203,7 +201,7 @@ PHPAPI void php_stream_bucket_prepend(php_stream_bucket_brigade *brigade, php_st bucket->brigade = brigade; } -PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC) +PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket) { if (brigade->tail == bucket) { return; @@ -221,7 +219,7 @@ PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_str bucket->brigade = brigade; } -PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket TSRMLS_DC) +PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket) { if (bucket->prev) { bucket->prev->next = bucket->next; @@ -236,7 +234,7 @@ PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket TSRMLS_DC) bucket->brigade = NULL; bucket->next = bucket->prev = NULL; } - + @@ -249,7 +247,7 @@ PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket TSRMLS_DC) * match. If that fails, we try "convert.charset.*", then "convert.*" * This means that we don't need to clog up the hashtable with a zillion * charsets (for example) but still be able to provide them all as filters */ -PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent TSRMLS_DC) +PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent) { HashTable *filter_hash = (FG(stream_filters) ? FG(stream_filters) : &stream_filters_hash); php_stream_filter_factory *factory = NULL; @@ -257,10 +255,10 @@ PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval int n; char *period; - n = strlen(filtername); - - if (SUCCESS == zend_hash_find(filter_hash, (char*)filtername, n + 1, (void**)&factory)) { - filter = factory->create_filter(filtername, filterparams, persistent TSRMLS_CC); + n = (int)strlen(filtername); + + if (NULL != (factory = zend_hash_str_find_ptr(filter_hash, filtername, n))) { + filter = factory->create_filter(filtername, filterparams, persistent); } else if ((period = strrchr(filtername, '.'))) { /* try a wildcard */ char *wildname; @@ -271,8 +269,8 @@ PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval while (period && !filter) { *period = '\0'; strncat(wildname, ".*", 2); - if (SUCCESS == zend_hash_find(filter_hash, wildname, strlen(wildname) + 1, (void**)&factory)) { - filter = factory->create_filter(filtername, filterparams, persistent TSRMLS_CC); + if (NULL != (factory = zend_hash_str_find_ptr(filter_hash, wildname, strlen(wildname)))) { + filter = factory->create_filter(filtername, filterparams, persistent); } *period = '\0'; @@ -284,15 +282,15 @@ PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval if (filter == NULL) { /* TODO: these need correct docrefs */ if (factory == NULL) - php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to locate filter \"%s\"", filtername); + php_error_docref(NULL, E_WARNING, "unable to locate filter \"%s\"", filtername); else - php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to create or locate filter \"%s\"", filtername); + php_error_docref(NULL, E_WARNING, "unable to create or locate filter \"%s\"", filtername); } - + return filter; } -PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC) +PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC) { php_stream_filter *filter; @@ -300,20 +298,20 @@ PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, memset(filter, 0, sizeof(php_stream_filter)); filter->fops = fops; - filter->abstract = abstract; + Z_PTR(filter->abstract) = abstract; filter->is_persistent = persistent; - + return filter; } -PHPAPI void php_stream_filter_free(php_stream_filter *filter TSRMLS_DC) +PHPAPI void php_stream_filter_free(php_stream_filter *filter) { if (filter->fops->dtor) - filter->fops->dtor(filter TSRMLS_CC); + filter->fops->dtor(filter); pefree(filter, filter->is_persistent); } -PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) +PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter) { filter->next = chain->head; filter->prev = NULL; @@ -329,12 +327,12 @@ PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stre return SUCCESS; } -PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) +PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter) { - php_stream_filter_prepend_ex(chain, filter TSRMLS_CC); + php_stream_filter_prepend_ex(chain, filter); } -PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) +PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter) { php_stream *stream = chain->stream; @@ -356,9 +354,9 @@ PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_strea php_stream_bucket *bucket; size_t consumed = 0; - bucket = php_stream_bucket_new(stream, (char*) stream->readbuf + stream->readpos, stream->writepos - stream->readpos, 0, 0 TSRMLS_CC); - php_stream_bucket_append(brig_inp, bucket TSRMLS_CC); - status = filter->fops->filter(stream, filter, brig_inp, brig_outp, &consumed, PSFS_FLAG_NORMAL TSRMLS_CC); + bucket = php_stream_bucket_new(stream, (char*) stream->readbuf + stream->readpos, stream->writepos - stream->readpos, 0, 0); + php_stream_bucket_append(brig_inp, bucket); + status = filter->fops->filter(stream, filter, brig_inp, brig_outp, &consumed, PSFS_FLAG_NORMAL); if (stream->readpos + consumed > (uint)stream->writepos) { /* No behaving filter should cause this. */ @@ -369,19 +367,19 @@ PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_strea case PSFS_ERR_FATAL: while (brig_in.head) { bucket = brig_in.head; - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); } while (brig_out.head) { bucket = brig_out.head; - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); } - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filter failed to process pre-buffered data"); + php_error_docref(NULL, E_WARNING, "Filter failed to process pre-buffered data"); return FAILURE; case PSFS_FEED_ME: /* We don't actually need data yet, - leave this filter in a feed me state until data is needed. + leave this filter in a feed me state until data is needed. Reset stream's internal read buffer since the filter is "holding" it. */ stream->readpos = 0; stream->writepos = 0; @@ -405,8 +403,8 @@ PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_strea memcpy(stream->readbuf + stream->writepos, bucket->buf, bucket->buflen); stream->writepos += bucket->buflen; - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); } break; } @@ -415,9 +413,9 @@ PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_strea return SUCCESS; } -PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC) +PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter) { - if (php_stream_filter_append_ex(chain, filter TSRMLS_CC) != SUCCESS) { + if (php_stream_filter_append_ex(chain, filter) != SUCCESS) { if (chain->head == filter) { chain->head = NULL; chain->tail = NULL; @@ -428,7 +426,7 @@ PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream } } -PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS_DC) +PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish) { php_stream_bucket_brigade brig_a = { NULL, NULL }, brig_b = { NULL, NULL }, *inp = &brig_a, *outp = &brig_b, *brig_temp; php_stream_bucket *bucket; @@ -449,7 +447,7 @@ PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS for(current = filter; current; current = current->next) { php_stream_filter_status_t status; - status = filter->fops->filter(stream, current, inp, outp, NULL, flags TSRMLS_CC); + status = filter->fops->filter(stream, current, inp, outp, NULL, flags); if (status == PSFS_FEED_ME) { /* We've flushed the data far enough */ return SUCCESS; @@ -495,22 +493,22 @@ PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS while ((bucket = inp->head)) { memcpy(stream->readbuf + stream->writepos, bucket->buf, bucket->buflen); stream->writepos += bucket->buflen; - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); } } else if (chain == &(stream->writefilters)) { /* Send flushed data to the stream */ while ((bucket = inp->head)) { - stream->ops->write(stream, bucket->buf, bucket->buflen TSRMLS_CC); - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); + stream->ops->write(stream, bucket->buf, bucket->buflen); + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); } } return SUCCESS; } -PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor TSRMLS_DC) +PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor) { if (filter->prev) { filter->prev->next = filter->next; @@ -523,12 +521,12 @@ PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, in filter->chain->tail = filter->prev; } - if (filter->rsrc_id > 0) { - zend_list_delete(filter->rsrc_id); + if (filter->res) { + zend_list_delete(filter->res); } if (call_dtor) { - php_stream_filter_free(filter TSRMLS_CC); + php_stream_filter_free(filter); return NULL; } return filter; diff --git a/main/streams/glob_wrapper.c b/main/streams/glob_wrapper.c index c4f9eb0781..4dffc27ade 100644 --- a/main/streams/glob_wrapper.c +++ b/main/streams/glob_wrapper.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -47,7 +47,7 @@ typedef struct { size_t pattern_len; } glob_s_t; -PHPAPI char* _php_glob_stream_get_path(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC) /* {{{ */ +PHPAPI char* _php_glob_stream_get_path(php_stream *stream, int copy, size_t *plen STREAMS_DC) /* {{{ */ { glob_s_t *pglob = (glob_s_t *)stream->abstract; @@ -69,10 +69,10 @@ PHPAPI char* _php_glob_stream_get_path(php_stream *stream, int copy, int *plen S } /* }}} */ -PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC) /* {{{ */ +PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, int copy, size_t *plen STREAMS_DC) /* {{{ */ { glob_s_t *pglob = (glob_s_t *)stream->abstract; - + if (pglob && pglob->pattern) { if (plen) { *plen = pglob->pattern_len; @@ -91,7 +91,7 @@ PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, int copy, int *ple } /* }}} */ -PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC TSRMLS_DC) /* {{{ */ +PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC) /* {{{ */ { glob_s_t *pglob = (glob_s_t *)stream->abstract; @@ -109,7 +109,7 @@ PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC } /* }}} */ -static void php_glob_stream_path_split(glob_s_t *pglob, const char *path, int get_path, const char **p_file TSRMLS_DC) /* {{{ */ +static void php_glob_stream_path_split(glob_s_t *pglob, const char *path, int get_path, const char **p_file) /* {{{ */ { const char *pos, *gpath = path; @@ -137,7 +137,7 @@ static void php_glob_stream_path_split(glob_s_t *pglob, const char *path, int ge } /* }}} */ -static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */ +static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count) /* {{{ */ { glob_s_t *pglob = (glob_s_t *)stream->abstract; php_stream_dirent *ent = (php_stream_dirent*)buf; @@ -146,7 +146,7 @@ static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count T /* avoid problems if someone mis-uses the stream */ if (count == sizeof(php_stream_dirent) && pglob) { if (pglob->index < (size_t)pglob->glob.gl_pathc) { - php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[pglob->index++], pglob->flags & GLOB_APPEND, &path TSRMLS_CC); + php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[pglob->index++], pglob->flags & GLOB_APPEND, &path); PHP_STRLCPY(ent->d_name, path, sizeof(ent->d_name), strlen(path)); return sizeof(php_stream_dirent); } @@ -161,7 +161,7 @@ static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count T } /* }}} */ -static int php_glob_stream_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */ +static int php_glob_stream_close(php_stream *stream, int close_handle) /* {{{ */ { glob_s_t *pglob = (glob_s_t *)stream->abstract; @@ -180,7 +180,7 @@ static int php_glob_stream_close(php_stream *stream, int close_handle TSRMLS_DC) } /* {{{ */ -static int php_glob_stream_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) /* {{{ */ +static int php_glob_stream_rewind(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs) /* {{{ */ { glob_s_t *pglob = (glob_s_t *)stream->abstract; @@ -207,25 +207,25 @@ php_stream_ops php_glob_stream_ops = { /* {{{ php_glob_stream_opener */ static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, const char *path, const char *mode, - int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) + int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) { glob_s_t *pglob; int ret; const char *tmp, *pos; - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) { + if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path)) { return NULL; } if (!strncmp(path, "glob://", sizeof("glob://")-1)) { path += sizeof("glob://")-1; if (opened_path) { - *opened_path = estrdup(path); + *opened_path = zend_string_init(path, strlen(path), 0); } } pglob = ecalloc(sizeof(*pglob), 1); - + if (0 != (ret = glob(path, pglob->flags & GLOB_FLAGMASK, NULL, &pglob->glob))) { #ifdef GLOB_NOMATCH if (GLOB_NOMATCH != ret) @@ -252,9 +252,9 @@ static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, const cha pglob->flags |= GLOB_APPEND; if (pglob->glob.gl_pathc) { - php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[0], 1, &tmp TSRMLS_CC); + php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[0], 1, &tmp); } else { - php_glob_stream_path_split(pglob, path, 1, &tmp TSRMLS_CC); + php_glob_stream_path_split(pglob, path, 1, &tmp); } return php_stream_alloc(&php_glob_stream_ops, pglob, 0, mode); diff --git a/main/streams/memory.c b/main/streams/memory.c index e5b65728a1..5145776f7e 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -20,9 +20,9 @@ #define _GNU_SOURCE #include "php.h" +#include "ext/standard/base64.h" PHPAPI int php_url_decode(char *str, int len); -PHPAPI unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length); /* Memory streams use a dynamic memory buffer to emulate a stream. * You can use php_stream_memory_open to create a readonly stream @@ -46,7 +46,7 @@ typedef struct { /* {{{ */ -static size_t php_stream_memory_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t php_stream_memory_write(php_stream *stream, const char *buf, size_t count) { php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; assert(ms != NULL); @@ -82,7 +82,7 @@ static size_t php_stream_memory_write(php_stream *stream, const char *buf, size_ /* {{{ */ -static size_t php_stream_memory_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_stream_memory_read(php_stream *stream, char *buf, size_t count) { php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; assert(ms != NULL); @@ -107,7 +107,7 @@ static size_t php_stream_memory_read(php_stream *stream, char *buf, size_t count /* {{{ */ -static int php_stream_memory_close(php_stream *stream, int close_handle TSRMLS_DC) +static int php_stream_memory_close(php_stream *stream, int close_handle) { php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; assert(ms != NULL); @@ -122,7 +122,7 @@ static int php_stream_memory_close(php_stream *stream, int close_handle TSRMLS_D /* {{{ */ -static int php_stream_memory_flush(php_stream *stream TSRMLS_DC) +static int php_stream_memory_flush(php_stream *stream) { /* nothing to do here */ return 0; @@ -131,7 +131,7 @@ static int php_stream_memory_flush(php_stream *stream TSRMLS_DC) /* {{{ */ -static int php_stream_memory_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) +static int php_stream_memory_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs) { php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; assert(ms != NULL); @@ -195,13 +195,13 @@ static int php_stream_memory_seek(php_stream *stream, off_t offset, int whence, /* }}} */ /* {{{ */ -static int php_stream_memory_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) +static int php_stream_memory_cast(php_stream *stream, int castas, void **ret) { return FAILURE; } /* }}} */ -static int php_stream_memory_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) /* {{{ */ +static int php_stream_memory_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ */ { time_t timestamp = 0; php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; @@ -209,7 +209,7 @@ static int php_stream_memory_stat(php_stream *stream, php_stream_statbuf *ssb TS memset(ssb, 0, sizeof(php_stream_statbuf)); /* read-only across the board */ - + ssb->sb.st_mode = ms->mode & TEMP_STREAM_READONLY ? 0444 : 0666; ssb->sb.st_size = ms->fsize; @@ -244,11 +244,11 @@ static int php_stream_memory_stat(php_stream *stream, php_stream_statbuf *ssb TS } /* }}} */ -static int php_stream_memory_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) /* {{{ */ +static int php_stream_memory_set_option(php_stream *stream, int option, int value, void *ptrparam) /* {{{ */ { php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; size_t newsize; - + switch(option) { case PHP_STREAM_OPTION_TRUNCATE_API: switch (value) { @@ -277,7 +277,7 @@ static int php_stream_memory_set_option(php_stream *stream, int option, int valu } } /* }}} */ - + PHPAPI php_stream_ops php_stream_memory_ops = { php_stream_memory_write, php_stream_memory_read, php_stream_memory_close, php_stream_memory_flush, @@ -290,7 +290,7 @@ PHPAPI php_stream_ops php_stream_memory_ops = { /* {{{ */ -PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC) { php_stream_memory_data *self; php_stream *stream; @@ -301,7 +301,7 @@ PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC TSRMLS_DC) self->fsize = 0; self->smax = ~0u; self->mode = mode; - + stream = php_stream_alloc_rel(&php_stream_memory_ops, self, 0, mode & TEMP_STREAM_READONLY ? "rb" : "w+b"); stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; return stream; @@ -310,14 +310,14 @@ PHPAPI php_stream *_php_stream_memory_create(int mode STREAMS_DC TSRMLS_DC) /* {{{ */ -PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length STREAMS_DC) { php_stream *stream; php_stream_memory_data *ms; if ((stream = php_stream_memory_create_rel(mode)) != NULL) { ms = (php_stream_memory_data*)stream->abstract; - + if (mode == TEMP_STREAM_READONLY || mode == TEMP_STREAM_TAKE_BUFFER) { /* use the buffer directly */ ms->data = buf; @@ -335,7 +335,7 @@ PHPAPI php_stream *_php_stream_memory_open(int mode, char *buf, size_t length ST /* {{{ */ -PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length STREAMS_DC TSRMLS_DC) +PHPAPI char *_php_stream_memory_get_buffer(php_stream *stream, size_t *length STREAMS_DC) { php_stream_memory_data *ms = (php_stream_memory_data*)stream->abstract; @@ -355,13 +355,13 @@ typedef struct { php_stream *innerstream; size_t smax; int mode; - zval* meta; + zval meta; char* tmpdir; } php_stream_temp_data; /* {{{ */ -static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t count) { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; assert(ts != NULL); @@ -376,7 +376,7 @@ static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t if (memsize + count >= ts->smax) { php_stream *file = php_stream_fopen_temporary_file(ts->tmpdir, "php", NULL); if (file == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create temporary file, Check permissions in temporary files directory."); + php_error_docref(NULL, E_WARNING, "Unable to create temporary file, Check permissions in temporary files directory."); return 0; } php_stream_write(file, membuf, memsize); @@ -391,7 +391,7 @@ static size_t php_stream_temp_write(php_stream *stream, const char *buf, size_t /* {{{ */ -static size_t php_stream_temp_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_stream_temp_read(php_stream *stream, char *buf, size_t count) { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; size_t got; @@ -401,18 +401,18 @@ static size_t php_stream_temp_read(php_stream *stream, char *buf, size_t count T if (!ts->innerstream) { return -1; } - + got = php_stream_read(ts->innerstream, buf, count); - + stream->eof = ts->innerstream->eof; - + return got; } /* }}} */ /* {{{ */ -static int php_stream_temp_close(php_stream *stream, int close_handle TSRMLS_DC) +static int php_stream_temp_close(php_stream *stream, int close_handle) { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; int ret; @@ -424,10 +424,8 @@ static int php_stream_temp_close(php_stream *stream, int close_handle TSRMLS_DC) } else { ret = 0; } - - if (ts->meta) { - zval_ptr_dtor(&ts->meta); - } + + zval_ptr_dtor(&ts->meta); if (ts->tmpdir) { efree(ts->tmpdir); @@ -441,7 +439,7 @@ static int php_stream_temp_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */ -static int php_stream_temp_flush(php_stream *stream TSRMLS_DC) +static int php_stream_temp_flush(php_stream *stream) { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; assert(ts != NULL); @@ -452,7 +450,7 @@ static int php_stream_temp_flush(php_stream *stream TSRMLS_DC) /* {{{ */ -static int php_stream_temp_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) +static int php_stream_temp_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs) { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; int ret; @@ -466,19 +464,19 @@ static int php_stream_temp_seek(php_stream *stream, off_t offset, int whence, of ret = php_stream_seek(ts->innerstream, offset, whence); *newoffs = php_stream_tell(ts->innerstream); stream->eof = ts->innerstream->eof; - + return ret; } /* }}} */ /* {{{ */ -static int php_stream_temp_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) +static int php_stream_temp_cast(php_stream *stream, int castas, void **ret) { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; php_stream *file; size_t memsize; char *membuf; - off_t pos; + zend_off_t pos; assert(ts != NULL); @@ -508,7 +506,7 @@ static int php_stream_temp_cast(php_stream *stream, int castas, void **ret TSRML file = php_stream_fopen_tmpfile(); php_stream_write(file, membuf, memsize); pos = php_stream_tell(ts->innerstream); - + php_stream_free_enclosed(ts->innerstream, PHP_STREAM_FREE_CLOSE); ts->innerstream = file; php_stream_encloses(stream, ts->innerstream); @@ -518,7 +516,7 @@ static int php_stream_temp_cast(php_stream *stream, int castas, void **ret TSRML } /* }}} */ -static int php_stream_temp_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) /* {{{ */ +static int php_stream_temp_stat(php_stream *stream, php_stream_statbuf *ssb) /* {{{ */ { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; @@ -529,14 +527,14 @@ static int php_stream_temp_stat(php_stream *stream, php_stream_statbuf *ssb TSRM } /* }}} */ -static int php_stream_temp_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) /* {{{ */ +static int php_stream_temp_set_option(php_stream *stream, int option, int value, void *ptrparam) /* {{{ */ { php_stream_temp_data *ts = (php_stream_temp_data*)stream->abstract; - + switch(option) { case PHP_STREAM_OPTION_META_DATA_API: - if (ts->meta) { - zend_hash_copy(Z_ARRVAL_P((zval*)ptrparam), Z_ARRVAL_P(ts->meta), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*)); + if (Z_TYPE(ts->meta) != IS_UNDEF) { + zend_hash_copy(Z_ARRVAL_P((zval*)ptrparam), Z_ARRVAL(ts->meta), zval_add_ref); } return PHP_STREAM_OPTION_RETURN_OK; default: @@ -561,7 +559,7 @@ PHPAPI php_stream_ops php_stream_temp_ops = { /* }}} */ /* {{{ _php_stream_temp_create_ex */ -PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, const char *tmpdir STREAMS_DC) { php_stream_temp_data *self; php_stream *stream; @@ -569,6 +567,7 @@ PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, self = ecalloc(1, sizeof(*self)); self->smax = max_memory_usage; self->mode = mode; + ZVAL_UNDEF(&self->meta); if (tmpdir) { self->tmpdir = estrdup(tmpdir); } @@ -582,24 +581,24 @@ PHPAPI php_stream *_php_stream_temp_create_ex(int mode, size_t max_memory_usage, /* }}} */ /* {{{ _php_stream_temp_create */ -PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STREAMS_DC) { return php_stream_temp_create_ex(mode, max_memory_usage, NULL); } /* }}} */ /* {{{ _php_stream_temp_open */ -PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_temp_open(int mode, size_t max_memory_usage, char *buf, size_t length STREAMS_DC) { php_stream *stream; php_stream_temp_data *ts; - off_t newoffs; + zend_off_t newoffs; if ((stream = php_stream_temp_create_rel(mode, max_memory_usage)) != NULL) { if (length) { assert(buf != NULL); - php_stream_temp_write(stream, buf, length TSRMLS_CC); - php_stream_temp_seek(stream, 0, SEEK_SET, &newoffs TSRMLS_CC); + php_stream_temp_write(stream, buf, length); + php_stream_temp_seek(stream, 0, SEEK_SET, &newoffs); } ts = (php_stream_temp_data*)stream->abstract; assert(ts != NULL); @@ -620,17 +619,19 @@ PHPAPI php_stream_ops php_stream_rfc2397_ops = { }; static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, const char *path, - const char *mode, int options, char **opened_path, - php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ + const char *mode, int options, zend_string **opened_path, + php_stream_context *context STREAMS_DC) /* {{{ */ { php_stream *stream; php_stream_temp_data *ts; char *comma, *semi, *sep, *key; size_t mlen, dlen, plen, vlen; - off_t newoffs; - zval *meta = NULL; + zend_off_t newoffs; + zval meta; int base64 = 0, ilen; + zend_string *base64_comma = NULL; + ZVAL_NULL(&meta); if (memcmp(path, "data:", 5)) { return NULL; } @@ -644,7 +645,7 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con } if ((comma = memchr(path, ',', dlen)) == NULL) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: no comma in URL"); + php_stream_wrapper_log_error(wrapper, options, "rfc2397: no comma in URL"); return NULL; } @@ -654,25 +655,24 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con dlen -= mlen; semi = memchr(path, ';', mlen); sep = memchr(path, '/', mlen); - + if (!semi && !sep) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: illegal media type"); + php_stream_wrapper_log_error(wrapper, options, "rfc2397: illegal media type"); return NULL; } - MAKE_STD_ZVAL(meta); - array_init(meta); + array_init(&meta); if (!semi) { /* there is only a mime type */ - add_assoc_stringl(meta, "mediatype", (char *) path, mlen, 1); + add_assoc_stringl(&meta, "mediatype", (char *) path, mlen); mlen = 0; } else if (sep && sep < semi) { /* there is a mime type */ plen = semi - path; - add_assoc_stringl(meta, "mediatype", (char *) path, plen, 1); + add_assoc_stringl(&meta, "mediatype", (char *) path, plen); mlen -= plen; path += plen; } else if (semi != path || mlen != sizeof(";base64")-1 || memcmp(path, ";base64", sizeof(";base64")-1)) { /* must be error since parameters are only allowed after mediatype */ zval_ptr_dtor(&meta); - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: illegal media type"); + php_stream_wrapper_log_error(wrapper, options, "rfc2397: illegal media type"); return NULL; } /* get parameters and potentially ';base64' */ @@ -685,7 +685,7 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con if (mlen != sizeof("base64")-1 || memcmp(path, "base64", sizeof("base64")-1)) { /* must be error since parameters are only allowed after mediatype and we have no '=' sign */ zval_ptr_dtor(&meta); - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: illegal parameter"); + php_stream_wrapper_log_error(wrapper, options, "rfc2397: illegal parameter"); return NULL; } base64 = 1; @@ -697,7 +697,7 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con plen = sep - path; vlen = (semi ? semi - sep : mlen - plen) - 1 /* '=' */; key = estrndup(path, plen); - add_assoc_stringl_ex(meta, key, plen + 1, sep + 1, vlen, 1); + add_assoc_stringl_ex(&meta, key, plen, sep + 1, vlen); efree(key); plen += vlen + 1; mlen -= plen; @@ -705,35 +705,37 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con } if (mlen) { zval_ptr_dtor(&meta); - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: illegal URL"); + php_stream_wrapper_log_error(wrapper, options, "rfc2397: illegal URL"); return NULL; } } else { - MAKE_STD_ZVAL(meta); - array_init(meta); + array_init(&meta); } - add_assoc_bool(meta, "base64", base64); + add_assoc_bool(&meta, "base64", base64); /* skip ',' */ comma++; dlen--; if (base64) { - comma = (char*)php_base64_decode((const unsigned char *)comma, dlen, &ilen); - if (!comma) { + base64_comma = php_base64_decode((const unsigned char *)comma, dlen); + if (!base64_comma) { zval_ptr_dtor(&meta); - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "rfc2397: unable to decode"); + php_stream_wrapper_log_error(wrapper, options, "rfc2397: unable to decode"); return NULL; } + comma = ZSTR_VAL(base64_comma); + ilen = (int)ZSTR_LEN(base64_comma); } else { comma = estrndup(comma, dlen); - ilen = dlen = php_url_decode(comma, dlen); + dlen = php_url_decode(comma, (int)dlen); + ilen = (int)dlen; } if ((stream = php_stream_temp_create_rel(0, ~0u)) != NULL) { /* store data */ - php_stream_temp_write(stream, comma, ilen TSRMLS_CC); - php_stream_temp_seek(stream, 0, SEEK_SET, &newoffs TSRMLS_CC); + php_stream_temp_write(stream, comma, ilen); + php_stream_temp_seek(stream, 0, SEEK_SET, &newoffs); /* set special stream stuff (enforce exact mode) */ vlen = strlen(mode); if (vlen >= sizeof(stream->mode)) { @@ -745,9 +747,13 @@ static php_stream * php_stream_url_wrap_rfc2397(php_stream_wrapper *wrapper, con ts = (php_stream_temp_data*)stream->abstract; assert(ts != NULL); ts->mode = mode && mode[0] == 'r' && mode[1] != '+' ? TEMP_STREAM_READONLY : 0; - ts->meta = meta; + ZVAL_COPY_VALUE(&ts->meta, &meta); + } + if (base64_comma) { + zend_string_free(base64_comma); + } else { + efree(comma); } - efree(comma); return stream; } diff --git a/main/streams/mmap.c b/main/streams/mmap.c index ee2b210f66..04427ed5c4 100644 --- a/main/streams/mmap.c +++ b/main/streams/mmap.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -22,10 +22,10 @@ #include "php.h" #include "php_streams_int.h" -PHPAPI char *_php_stream_mmap_range(php_stream *stream, size_t offset, size_t length, php_stream_mmap_operation_t mode, size_t *mapped_len TSRMLS_DC) +PHPAPI char *_php_stream_mmap_range(php_stream *stream, size_t offset, size_t length, php_stream_mmap_access_t mode, size_t *mapped_len) { php_stream_mmap_range range; - + range.offset = offset; range.length = length; range.mode = mode; @@ -36,7 +36,7 @@ PHPAPI char *_php_stream_mmap_range(php_stream *stream, size_t offset, size_t le if (length > 4 * 1024 * 1024) { return NULL; } - + if (PHP_STREAM_OPTION_RETURN_OK == php_stream_set_option(stream, PHP_STREAM_OPTION_MMAP_API, PHP_STREAM_MMAP_MAP_RANGE, &range)) { if (mapped_len) { *mapped_len = range.length; @@ -46,12 +46,12 @@ PHPAPI char *_php_stream_mmap_range(php_stream *stream, size_t offset, size_t le return NULL; } -PHPAPI int _php_stream_mmap_unmap(php_stream *stream TSRMLS_DC) +PHPAPI int _php_stream_mmap_unmap(php_stream *stream) { return php_stream_set_option(stream, PHP_STREAM_OPTION_MMAP_API, PHP_STREAM_MMAP_UNMAP, NULL) == PHP_STREAM_OPTION_RETURN_OK ? 1 : 0; } -PHPAPI int _php_stream_mmap_unmap_ex(php_stream *stream, off_t readden TSRMLS_DC) +PHPAPI int _php_stream_mmap_unmap_ex(php_stream *stream, zend_off_t readden) { int ret = 1; diff --git a/main/streams/php_stream_context.h b/main/streams/php_stream_context.h index c31f1fa984..25f5bb3f58 100644 --- a/main/streams/php_stream_context.h +++ b/main/streams/php_stream_context.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -25,7 +25,7 @@ typedef void (*php_stream_notification_func)(php_stream_context *context, int notifycode, int severity, char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, - void * ptr TSRMLS_DC); + void * ptr); #define PHP_STREAM_NOTIFIER_PROGRESS 1 @@ -33,34 +33,34 @@ typedef void (*php_stream_notification_func)(php_stream_context *context, If no context was passed, use the default context The default context has not yet been created, do it now. */ #define php_stream_context_from_zval(zcontext, nocontext) ( \ - (zcontext) ? zend_fetch_resource(&(zcontext) TSRMLS_CC, -1, "Stream-Context", NULL, 1, php_le_stream_context(TSRMLS_C)) : \ + (zcontext) ? zend_fetch_resource_ex(zcontext, "Stream-Context", php_le_stream_context()) : \ (nocontext) ? NULL : \ FG(default_context) ? FG(default_context) : \ - (FG(default_context) = php_stream_context_alloc(TSRMLS_C)) ) + (FG(default_context) = php_stream_context_alloc()) ) -#define php_stream_context_to_zval(context, zval) { ZVAL_RESOURCE(zval, (context)->rsrc_id); zend_list_addref((context)->rsrc_id); } +#define php_stream_context_to_zval(context, zval) { ZVAL_RES(zval, (context)->res); GC_REFCOUNT((context)->res)++; } typedef struct _php_stream_notifier php_stream_notifier; struct _php_stream_notifier { php_stream_notification_func func; void (*dtor)(php_stream_notifier *notifier); - void *ptr; + zval ptr; int mask; size_t progress, progress_max; /* position for progress notification */ }; struct _php_stream_context { php_stream_notifier *notifier; - zval *options; /* hash keyed by wrapper family or specific wrapper */ - int rsrc_id; /* used for auto-cleanup */ + zval options; /* hash keyed by wrapper family or specific wrapper */ + zend_resource *res; /* used for auto-cleanup */ }; BEGIN_EXTERN_C() PHPAPI void php_stream_context_free(php_stream_context *context); -PHPAPI php_stream_context *php_stream_context_alloc(TSRMLS_D); -PHPAPI int php_stream_context_get_option(php_stream_context *context, - const char *wrappername, const char *optionname, zval ***optionvalue); +PHPAPI php_stream_context *php_stream_context_alloc(void); +PHPAPI zval *php_stream_context_get_option(php_stream_context *context, + const char *wrappername, const char *optionname); PHPAPI int php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue); @@ -86,17 +86,17 @@ END_EXTERN_C() BEGIN_EXTERN_C() PHPAPI void php_stream_notification_notify(php_stream_context *context, int notifycode, int severity, - char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr TSRMLS_DC); + char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr); PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context); END_EXTERN_C() #define php_stream_notify_info(context, code, xmsg, xcode) do { if ((context) && (context)->notifier) { \ php_stream_notification_notify((context), (code), PHP_STREAM_NOTIFY_SEVERITY_INFO, \ - (xmsg), (xcode), 0, 0, NULL TSRMLS_CC); } } while (0) - + (xmsg), (xcode), 0, 0, NULL); } } while (0) + #define php_stream_notify_progress(context, bsofar, bmax) do { if ((context) && (context)->notifier) { \ php_stream_notification_notify((context), PHP_STREAM_NOTIFY_PROGRESS, PHP_STREAM_NOTIFY_SEVERITY_INFO, \ - NULL, 0, (bsofar), (bmax), NULL TSRMLS_CC); } } while(0) + NULL, 0, (bsofar), (bmax), NULL); } } while(0) #define php_stream_notify_progress_init(context, sofar, bmax) do { if ((context) && (context)->notifier) { \ (context)->notifier->progress = (sofar); \ @@ -111,12 +111,12 @@ END_EXTERN_C() #define php_stream_notify_file_size(context, file_size, xmsg, xcode) do { if ((context) && (context)->notifier) { \ php_stream_notification_notify((context), PHP_STREAM_NOTIFY_FILE_SIZE_IS, PHP_STREAM_NOTIFY_SEVERITY_INFO, \ - (xmsg), (xcode), 0, (file_size), NULL TSRMLS_CC); } } while(0) - + (xmsg), (xcode), 0, (file_size), NULL); } } while(0) + #define php_stream_notify_error(context, code, xmsg, xcode) do { if ((context) && (context)->notifier) {\ php_stream_notification_notify((context), (code), PHP_STREAM_NOTIFY_SEVERITY_ERR, \ - (xmsg), (xcode), 0, 0, NULL TSRMLS_CC); } } while(0) - + (xmsg), (xcode), 0, 0, NULL); } } while(0) + /* * Local variables: diff --git a/main/streams/php_stream_filter_api.h b/main/streams/php_stream_filter_api.h index 9e08b43cad..a37517e1ea 100644 --- a/main/streams/php_stream_filter_api.h +++ b/main/streams/php_stream_filter_api.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -26,7 +26,7 @@ * it is intentially a light-weight implementation. * * Each stream can have a chain of filters for reading and another for writing. - * + * * When data is written to the stream, it is placed into a bucket and placed at * the start of the input brigade. * @@ -50,7 +50,7 @@ struct _php_stream_bucket { /* if non-zero, buf should be pefreed when the bucket is destroyed */ int own_buf; int is_persistent; - + /* destroy this struct when refcount falls to zero */ int refcount; }; @@ -67,14 +67,14 @@ typedef enum { /* Buckets API. */ BEGIN_EXTERN_C() -PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent TSRMLS_DC); -PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length TSRMLS_DC); -PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket TSRMLS_DC); +PHPAPI php_stream_bucket *php_stream_bucket_new(php_stream *stream, char *buf, size_t buflen, int own_buf, int buf_persistent); +PHPAPI int php_stream_bucket_split(php_stream_bucket *in, php_stream_bucket **left, php_stream_bucket **right, size_t length); +PHPAPI void php_stream_bucket_delref(php_stream_bucket *bucket); #define php_stream_bucket_addref(bucket) (bucket)->refcount++ -PHPAPI void php_stream_bucket_prepend(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC); -PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket TSRMLS_DC); -PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket TSRMLS_DC); -PHPAPI php_stream_bucket *php_stream_bucket_make_writeable(php_stream_bucket *bucket TSRMLS_DC); +PHPAPI void php_stream_bucket_prepend(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket); +PHPAPI void php_stream_bucket_append(php_stream_bucket_brigade *brigade, php_stream_bucket *bucket); +PHPAPI void php_stream_bucket_unlink(php_stream_bucket *bucket); +PHPAPI php_stream_bucket *php_stream_bucket_make_writeable(php_stream_bucket *bucket); END_EXTERN_C() #define PSFS_FLAG_NORMAL 0 /* regular read/write */ @@ -90,12 +90,12 @@ typedef struct _php_stream_filter_ops { php_stream_bucket_brigade *buckets_out, size_t *bytes_consumed, int flags - TSRMLS_DC); - - void (*dtor)(php_stream_filter *thisfilter TSRMLS_DC); - + ); + + void (*dtor)(php_stream_filter *thisfilter); + const char *label; - + } php_stream_filter_ops; typedef struct _php_stream_filter_chain { @@ -107,7 +107,7 @@ typedef struct _php_stream_filter_chain { struct _php_stream_filter { php_stream_filter_ops *fops; - void *abstract; /* for use by filter implementation */ + zval abstract; /* for use by filter implementation */ php_stream_filter *next; php_stream_filter *prev; int is_persistent; @@ -119,37 +119,37 @@ struct _php_stream_filter { php_stream_bucket_brigade buffer; /* filters are auto_registered when they're applied */ - int rsrc_id; + zend_resource *res; }; /* stack filter onto a stream */ BEGIN_EXTERN_C() -PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); -PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); -PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); -PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter TSRMLS_DC); -PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish TSRMLS_DC); -PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor TSRMLS_DC); -PHPAPI void php_stream_filter_free(php_stream_filter *filter TSRMLS_DC); -PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC TSRMLS_DC); +PHPAPI void _php_stream_filter_prepend(php_stream_filter_chain *chain, php_stream_filter *filter); +PHPAPI int php_stream_filter_prepend_ex(php_stream_filter_chain *chain, php_stream_filter *filter); +PHPAPI void _php_stream_filter_append(php_stream_filter_chain *chain, php_stream_filter *filter); +PHPAPI int php_stream_filter_append_ex(php_stream_filter_chain *chain, php_stream_filter *filter); +PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish); +PHPAPI php_stream_filter *php_stream_filter_remove(php_stream_filter *filter, int call_dtor); +PHPAPI void php_stream_filter_free(php_stream_filter *filter); +PHPAPI php_stream_filter *_php_stream_filter_alloc(php_stream_filter_ops *fops, void *abstract, int persistent STREAMS_DC); END_EXTERN_C() -#define php_stream_filter_alloc(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC TSRMLS_CC) -#define php_stream_filter_alloc_rel(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC TSRMLS_CC) -#define php_stream_filter_prepend(chain, filter) _php_stream_filter_prepend((chain), (filter) TSRMLS_CC) -#define php_stream_filter_append(chain, filter) _php_stream_filter_append((chain), (filter) TSRMLS_CC) -#define php_stream_filter_flush(filter, finish) _php_stream_filter_flush((filter), (finish) TSRMLS_CC) +#define php_stream_filter_alloc(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_CC) +#define php_stream_filter_alloc_rel(fops, thisptr, persistent) _php_stream_filter_alloc((fops), (thisptr), (persistent) STREAMS_REL_CC) +#define php_stream_filter_prepend(chain, filter) _php_stream_filter_prepend((chain), (filter)) +#define php_stream_filter_append(chain, filter) _php_stream_filter_append((chain), (filter)) +#define php_stream_filter_flush(filter, finish) _php_stream_filter_flush((filter), (finish)) #define php_stream_is_filtered(stream) ((stream)->readfilters.head || (stream)->writefilters.head) typedef struct _php_stream_filter_factory { - php_stream_filter *(*create_filter)(const char *filtername, zval *filterparams, int persistent TSRMLS_DC); + php_stream_filter *(*create_filter)(const char *filtername, zval *filterparams, int persistent); } php_stream_filter_factory; BEGIN_EXTERN_C() -PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC); -PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern TSRMLS_DC); -PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory TSRMLS_DC); -PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent TSRMLS_DC); +PHPAPI int php_stream_filter_register_factory(const char *filterpattern, php_stream_filter_factory *factory); +PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern); +PHPAPI int php_stream_filter_register_factory_volatile(const char *filterpattern, php_stream_filter_factory *factory); +PHPAPI php_stream_filter *php_stream_filter_create(const char *filtername, zval *filterparams, int persistent); END_EXTERN_C() /* diff --git a/main/streams/php_stream_glob_wrapper.h b/main/streams/php_stream_glob_wrapper.h index 691b3c4438..15a4d978c6 100644 --- a/main/streams/php_stream_glob_wrapper.h +++ b/main/streams/php_stream_glob_wrapper.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -23,14 +23,14 @@ PHPAPI extern php_stream_ops php_glob_stream_ops; BEGIN_EXTERN_C() -PHPAPI char* _php_glob_stream_get_path(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC); -#define php_glob_stream_get_path(stream, copy, plen) _php_glob_stream_get_path((stream), (copy), (plen) STREAMS_CC TSRMLS_CC) +PHPAPI char* _php_glob_stream_get_path(php_stream *stream, int copy, size_t *plen STREAMS_DC); +#define php_glob_stream_get_path(stream, copy, plen) _php_glob_stream_get_path((stream), (copy), (plen) STREAMS_CC) -PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC); -#define php_glob_stream_get_pattern(stream, copy, plen) _php_glob_stream_get_pattern((stream), (copy), (plen) STREAMS_CC TSRMLS_CC) +PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, int copy, size_t *plen STREAMS_DC); +#define php_glob_stream_get_pattern(stream, copy, plen) _php_glob_stream_get_pattern((stream), (copy), (plen) STREAMS_CC) -PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC TSRMLS_DC); -#define php_glob_stream_get_count(stream, pflags) _php_glob_stream_get_count((stream), (pflags) STREAMS_CC TSRMLS_CC) +PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC); +#define php_glob_stream_get_count(stream, pflags) _php_glob_stream_get_count((stream), (pflags) STREAMS_CC) END_EXTERN_C() diff --git a/main/streams/php_stream_mmap.h b/main/streams/php_stream_mmap.h index e3ae0cb9f6..e912a5593e 100644 --- a/main/streams/php_stream_mmap.h +++ b/main/streams/php_stream_mmap.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -37,7 +37,7 @@ typedef enum { /* Unmap the last range that was mapped for the stream */ PHP_STREAM_MMAP_UNMAP } php_stream_mmap_operation_t; - + typedef enum { PHP_STREAM_MAP_MODE_READONLY, PHP_STREAM_MAP_MODE_READWRITE, @@ -50,9 +50,9 @@ typedef struct { * If length is 0, the whole file is mapped */ size_t offset; size_t length; - + php_stream_mmap_access_t mode; - + /* returned mapped address */ char *mapped; @@ -60,22 +60,22 @@ typedef struct { #define PHP_STREAM_MMAP_ALL 0 -#define php_stream_mmap_supported(stream) (_php_stream_set_option((stream), PHP_STREAM_OPTION_MMAP_API, PHP_STREAM_MMAP_SUPPORTED, NULL TSRMLS_CC) == 0 ? 1 : 0) +#define php_stream_mmap_supported(stream) (_php_stream_set_option((stream), PHP_STREAM_OPTION_MMAP_API, PHP_STREAM_MMAP_SUPPORTED, NULL) == 0 ? 1 : 0) /* Returns 1 if the stream in its current state can be memory mapped, * 0 otherwise */ #define php_stream_mmap_possible(stream) (!php_stream_is_filtered((stream)) && php_stream_mmap_supported((stream))) BEGIN_EXTERN_C() -PHPAPI char *_php_stream_mmap_range(php_stream *stream, size_t offset, size_t length, php_stream_mmap_operation_t mode, size_t *mapped_len TSRMLS_DC); -#define php_stream_mmap_range(stream, offset, length, mode, mapped_len) _php_stream_mmap_range((stream), (offset), (length), (mode), (mapped_len) TSRMLS_CC) +PHPAPI char *_php_stream_mmap_range(php_stream *stream, size_t offset, size_t length, php_stream_mmap_access_t mode, size_t *mapped_len); +#define php_stream_mmap_range(stream, offset, length, mode, mapped_len) _php_stream_mmap_range((stream), (offset), (length), (mode), (mapped_len)) /* un-maps the last mapped range */ -PHPAPI int _php_stream_mmap_unmap(php_stream *stream TSRMLS_DC); -#define php_stream_mmap_unmap(stream) _php_stream_mmap_unmap((stream) TSRMLS_CC) +PHPAPI int _php_stream_mmap_unmap(php_stream *stream); +#define php_stream_mmap_unmap(stream) _php_stream_mmap_unmap((stream)) -PHPAPI int _php_stream_mmap_unmap_ex(php_stream *stream, off_t readden TSRMLS_DC); -#define php_stream_mmap_unmap_ex(stream, readden) _php_stream_mmap_unmap_ex((stream), (readden) TSRMLS_CC) +PHPAPI int _php_stream_mmap_unmap_ex(php_stream *stream, zend_off_t readden); +#define php_stream_mmap_unmap_ex(stream, readden) _php_stream_mmap_unmap_ex((stream), (readden)) END_EXTERN_C() /* diff --git a/main/streams/php_stream_plain_wrapper.h b/main/streams/php_stream_plain_wrapper.h index 040a1dca5d..61fc09542b 100644 --- a/main/streams/php_stream_plain_wrapper.h +++ b/main/streams/php_stream_plain_wrapper.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -27,32 +27,32 @@ PHPAPI extern php_stream_wrapper php_plain_files_wrapper; BEGIN_EXTERN_C() /* like fopen, but returns a stream */ -PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, char **opened_path, int options STREAMS_DC TSRMLS_DC); -#define php_stream_fopen(filename, mode, opened) _php_stream_fopen((filename), (mode), (opened), 0 STREAMS_CC TSRMLS_CC) +PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, zend_string **opened_path, int options STREAMS_DC); +#define php_stream_fopen(filename, mode, opened) _php_stream_fopen((filename), (mode), (opened), 0 STREAMS_CC) -PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC); -#define php_stream_fopen_with_path(filename, mode, path, opened) _php_stream_fopen_with_path((filename), (mode), (path), (opened), 0 STREAMS_CC TSRMLS_CC) +PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path, int options STREAMS_DC); +#define php_stream_fopen_with_path(filename, mode, path, opened) _php_stream_fopen_with_path((filename), (mode), (path), (opened), 0 STREAMS_CC) -PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC TSRMLS_DC); -#define php_stream_fopen_from_file(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_CC TSRMLS_CC) +PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC); +#define php_stream_fopen_from_file(file, mode) _php_stream_fopen_from_file((file), (mode) STREAMS_CC) -PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC); -#define php_stream_fopen_from_fd(fd, mode, persistent_id) _php_stream_fopen_from_fd((fd), (mode), (persistent_id) STREAMS_CC TSRMLS_CC) +PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC); +#define php_stream_fopen_from_fd(fd, mode, persistent_id) _php_stream_fopen_from_fd((fd), (mode), (persistent_id) STREAMS_CC) -PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STREAMS_DC TSRMLS_DC); -#define php_stream_fopen_from_pipe(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_CC TSRMLS_CC) +PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STREAMS_DC); +#define php_stream_fopen_from_pipe(file, mode) _php_stream_fopen_from_pipe((file), (mode) STREAMS_CC) -PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC); -#define php_stream_fopen_tmpfile() _php_stream_fopen_tmpfile(0 STREAMS_CC TSRMLS_CC) +PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC); +#define php_stream_fopen_tmpfile() _php_stream_fopen_tmpfile(0 STREAMS_CC) -PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path STREAMS_DC TSRMLS_DC); -#define php_stream_fopen_temporary_file(dir, pfx, opened_path) _php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_CC TSRMLS_CC) +PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, zend_string **opened_path STREAMS_DC); +#define php_stream_fopen_temporary_file(dir, pfx, opened_path) _php_stream_fopen_temporary_file((dir), (pfx), (opened_path) STREAMS_CC) /* This is a utility API for extensions that are opening a stream, converting it * to a FILE* and then closing it again. Be warned that fileno() on the result * will most likely fail on systems with fopencookie. */ -PHPAPI FILE * _php_stream_open_wrapper_as_file(char * path, char * mode, int options, char **opened_path STREAMS_DC TSRMLS_DC); -#define php_stream_open_wrapper_as_file(path, mode, options, opened_path) _php_stream_open_wrapper_as_file((path), (mode), (options), (opened_path) STREAMS_CC TSRMLS_CC) +PHPAPI FILE * _php_stream_open_wrapper_as_file(char * path, char * mode, int options, zend_string **opened_path STREAMS_DC); +#define php_stream_open_wrapper_as_file(path, mode, options, opened_path) _php_stream_open_wrapper_as_file((path), (mode), (options), (opened_path) STREAMS_CC) END_EXTERN_C() diff --git a/main/streams/php_stream_transport.h b/main/streams/php_stream_transport.h index e5d09419de..f21bbb5520 100644 --- a/main/streams/php_stream_transport.h +++ b/main/streams/php_stream_transport.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -30,12 +30,12 @@ typedef php_stream *(php_stream_transport_factory_func)(const char *proto, size_ const char *resourcename, size_t resourcenamelen, const char *persistent_id, int options, int flags, struct timeval *timeout, - php_stream_context *context STREAMS_DC TSRMLS_DC); + php_stream_context *context STREAMS_DC); typedef php_stream_transport_factory_func *php_stream_transport_factory; BEGIN_EXTERN_C() -PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory TSRMLS_DC); -PHPAPI int php_stream_xport_unregister(const char *protocol TSRMLS_DC); +PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory); +PHPAPI int php_stream_xport_unregister(const char *protocol); #define STREAM_XPORT_CLIENT 0 #define STREAM_XPORT_SERVER 1 @@ -50,48 +50,48 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in int flags, const char *persistent_id, struct timeval *timeout, php_stream_context *context, - char **error_string, + zend_string **error_string, int *error_code - STREAMS_DC TSRMLS_DC); + STREAMS_DC); #define php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode) \ - _php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode STREAMS_CC TSRMLS_CC) + _php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode STREAMS_CC) /* Bind the stream to a local address */ PHPAPI int php_stream_xport_bind(php_stream *stream, const char *name, size_t namelen, - char **error_text - TSRMLS_DC); + zend_string **error_text + ); /* Connect to a remote address */ PHPAPI int php_stream_xport_connect(php_stream *stream, const char *name, size_t namelen, int asynchronous, struct timeval *timeout, - char **error_text, + zend_string **error_text, int *error_code - TSRMLS_DC); + ); /* Prepare to listen */ PHPAPI int php_stream_xport_listen(php_stream *stream, int backlog, - char **error_text - TSRMLS_DC); + zend_string **error_text + ); /* Get the next client and their address as a string, or the underlying address * structure. You must efree either of these if you request them */ PHPAPI int php_stream_xport_accept(php_stream *stream, php_stream **client, - char **textaddr, int *textaddrlen, + zend_string **textaddr, void **addr, socklen_t *addrlen, struct timeval *timeout, - char **error_text - TSRMLS_DC); + zend_string **error_text + ); /* Get the name of either the socket or it's peer */ PHPAPI int php_stream_xport_get_name(php_stream *stream, int want_peer, - char **textaddr, int *textaddrlen, + zend_string **textaddr, void **addr, socklen_t *addrlen - TSRMLS_DC); + ); enum php_stream_xport_send_recv_flags { STREAM_OOB = 1, @@ -101,13 +101,13 @@ enum php_stream_xport_send_recv_flags { /* Similar to recv() system call; read data from the stream, optionally * peeking, optionally retrieving OOB data */ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t buflen, - long flags, void **addr, socklen_t *addrlen, - char **textaddr, int *textaddrlen TSRMLS_DC); + int flags, void **addr, socklen_t *addrlen, + zend_string **textaddr); /* Similar to send() system call; send data to the stream, optionally * sending it as OOB data */ PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t buflen, - long flags, void *addr, socklen_t addrlen TSRMLS_DC); + int flags, void *addr, socklen_t addrlen); typedef enum { STREAM_SHUT_RD, @@ -117,7 +117,7 @@ typedef enum { /* Similar to shutdown() system call; shut down part of a full-duplex * connection */ -PHPAPI int php_stream_xport_shutdown(php_stream *stream, stream_shutdown_t how TSRMLS_DC); +PHPAPI int php_stream_xport_shutdown(php_stream *stream, stream_shutdown_t how); END_EXTERN_C() @@ -142,23 +142,21 @@ typedef struct _php_stream_xport_param { struct { char *name; size_t namelen; - int backlog; struct timeval *timeout; struct sockaddr *addr; - socklen_t addrlen; char *buf; size_t buflen; - long flags; + socklen_t addrlen; + int backlog; + int flags; } inputs; struct { php_stream *client; - int returncode; struct sockaddr *addr; socklen_t addrlen; - char *textaddr; - long textaddrlen; - - char *error_text; + zend_string *textaddr; + zend_string *error_text; + int returncode; int error_code; } outputs; } php_stream_xport_param; @@ -194,23 +192,23 @@ typedef enum { /* These functions provide crypto support on the underlying transport */ BEGIN_EXTERN_C() -PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream TSRMLS_DC); -PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate TSRMLS_DC); +PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream); +PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate); END_EXTERN_C() typedef struct _php_stream_xport_crypto_param { - enum { - STREAM_XPORT_CRYPTO_OP_SETUP, - STREAM_XPORT_CRYPTO_OP_ENABLE - } op; struct { + php_stream *session; int activate; php_stream_xport_crypt_method_t method; - php_stream *session; } inputs; struct { int returncode; } outputs; + enum { + STREAM_XPORT_CRYPTO_OP_SETUP, + STREAM_XPORT_CRYPTO_OP_ENABLE + } op; } php_stream_xport_crypto_param; BEGIN_EXTERN_C() diff --git a/main/streams/php_stream_userspace.h b/main/streams/php_stream_userspace.h index 337b00512e..bb984067ac 100644 --- a/main/streams/php_stream_userspace.h +++ b/main/streams/php_stream_userspace.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ diff --git a/main/streams/php_streams_int.h b/main/streams/php_streams_int.h index cdecfccae1..0188202c91 100644 --- a/main/streams/php_streams_int.h +++ b/main/streams/php_streams_int.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -49,16 +49,12 @@ #define CHUNK_SIZE 8192 #ifdef PHP_WIN32 -# ifdef EWOULDBLOCK +# ifdef EWOULDBLOCK # undef EWOULDBLOCK # endif # define EWOULDBLOCK WSAEWOULDBLOCK #endif -#ifndef S_ISREG -#define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG) -#endif - /* This functions transforms the first char to 'w' if it's not 'r', 'a' or 'w' * and strips any subsequent chars except '+' and 'b'. * Use this to sanitize stream->mode if you call e.g. fdopen, fopencookie or @@ -66,6 +62,6 @@ * ones. result should be a char[5]. */ void php_stream_mode_sanitize_fdopen_fopencookie(php_stream *stream, char *result); -void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC); -void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption TSRMLS_DC); +void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper); +void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption); diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index 7ffb6663d8..066f7789a7 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -44,14 +44,20 @@ # include "win32/time.h" #endif -#define php_stream_fopen_from_fd_int(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_CC TSRMLS_CC) -#define php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_REL_CC TSRMLS_CC) -#define php_stream_fopen_from_file_int(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_CC TSRMLS_CC) -#define php_stream_fopen_from_file_int_rel(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_REL_CC TSRMLS_CC) +#define php_stream_fopen_from_fd_int(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_CC) +#define php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id) _php_stream_fopen_from_fd_int((fd), (mode), (persistent_id) STREAMS_REL_CC) +#define php_stream_fopen_from_file_int(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_CC) +#define php_stream_fopen_from_file_int_rel(file, mode) _php_stream_fopen_from_file_int((file), (mode) STREAMS_REL_CC) #if !defined(WINDOWS) && !defined(NETWARE) -extern int php_get_uid_by_name(const char *name, uid_t *uid TSRMLS_DC); -extern int php_get_gid_by_name(const char *name, gid_t *gid TSRMLS_DC); +extern int php_get_uid_by_name(const char *name, uid_t *uid); +extern int php_get_gid_by_name(const char *name, gid_t *gid); +#endif + +#if defined(PHP_WIN32) +# define PLAIN_WRAP_BUF_SIZE(st) (((st) > UINT_MAX) ? UINT_MAX : (unsigned int)(st)) +#else +# define PLAIN_WRAP_BUF_SIZE(st) (st) #endif /* parse standard "fopen" modes into open() flags */ @@ -115,10 +121,11 @@ typedef struct { unsigned is_process_pipe:1; /* use pclose instead of fclose */ unsigned is_pipe:1; /* don't try and seek */ unsigned cached_fstat:1; /* sb is valid */ - unsigned _reserved:29; - + unsigned is_pipe_blocking:1; /* allow blocking read() on pipes, currently Windows only */ + unsigned _reserved:28; + int lock_flag; /* stores the lock state */ - char *temp_file_name; /* if non-null, this is the path to a temporary file that + zend_string *temp_name; /* if non-null, this is the path to a temporary file that * is to be deleted when the stream is closed */ #if HAVE_FLUSHIO char last_op; @@ -133,7 +140,7 @@ typedef struct { HANDLE file_mapping; #endif - struct stat sb; + zend_stat_t sb; } php_stdio_stream_data; #define PHP_STDIOP_GET_FD(anfd, data) anfd = (data)->file ? fileno((data)->file) : (data)->fd @@ -142,9 +149,9 @@ static int do_fstat(php_stdio_stream_data *d, int force) if (!d->cached_fstat || force) { int fd; int r; - + PHP_STDIOP_GET_FD(fd, d); - r = fstat(fd, &d->sb); + r = zend_fstat(fd, &d->sb); d->cached_fstat = r == 0; return r; @@ -152,44 +159,50 @@ static int do_fstat(php_stdio_stream_data *d, int force) return 0; } -static php_stream *_php_stream_fopen_from_fd_int(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC) +static php_stream *_php_stream_fopen_from_fd_int(int fd, const char *mode, const char *persistent_id STREAMS_DC) { php_stdio_stream_data *self; - + self = pemalloc_rel_orig(sizeof(*self), persistent_id); memset(self, 0, sizeof(*self)); self->file = NULL; self->is_pipe = 0; self->lock_flag = LOCK_UN; self->is_process_pipe = 0; - self->temp_file_name = NULL; + self->temp_name = NULL; self->fd = fd; - +#ifdef PHP_WIN32 + self->is_pipe_blocking = 0; +#endif + return php_stream_alloc_rel(&php_stream_stdio_ops, self, persistent_id, mode); } -static php_stream *_php_stream_fopen_from_file_int(FILE *file, const char *mode STREAMS_DC TSRMLS_DC) +static php_stream *_php_stream_fopen_from_file_int(FILE *file, const char *mode STREAMS_DC) { php_stdio_stream_data *self; - + self = emalloc_rel_orig(sizeof(*self)); memset(self, 0, sizeof(*self)); self->file = file; self->is_pipe = 0; self->lock_flag = LOCK_UN; self->is_process_pipe = 0; - self->temp_file_name = NULL; + self->temp_name = NULL; self->fd = fileno(file); +#ifdef PHP_WIN32 + self->is_pipe_blocking = 0; +#endif return php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode); } -PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, char **opened_path_ptr STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char *pfx, zend_string **opened_path_ptr STREAMS_DC) { - char *opened_path = NULL; + zend_string *opened_path = NULL; int fd; - fd = php_open_temporary_fd(dir, pfx, &opened_path TSRMLS_CC); + fd = php_open_temporary_fd(dir, pfx, &opened_path); if (fd != -1) { php_stream *stream; @@ -201,28 +214,28 @@ PHPAPI php_stream *_php_stream_fopen_temporary_file(const char *dir, const char if (stream) { php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract; stream->wrapper = &php_plain_files_wrapper; - stream->orig_path = estrdup(opened_path); + stream->orig_path = estrndup(ZSTR_VAL(opened_path), ZSTR_LEN(opened_path)); - self->temp_file_name = opened_path; + self->temp_name = opened_path; self->lock_flag = LOCK_UN; - + return stream; } close(fd); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to allocate stream"); + php_error_docref(NULL, E_WARNING, "unable to allocate stream"); return NULL; } return NULL; } -PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC) { return php_stream_fopen_temporary_file(NULL, "php", NULL); } -PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const char *persistent_id STREAMS_DC) { php_stream *stream = php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id); @@ -243,13 +256,13 @@ PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const cha } } #endif - + if (self->is_pipe) { stream->flags |= PHP_STREAM_FLAG_NO_SEEK; } else { - stream->position = lseek(self->fd, 0, SEEK_CUR); + stream->position = zend_lseek(self->fd, 0, SEEK_CUR); #ifdef ESPIPE - if (stream->position == (off_t)-1 && errno == ESPIPE) { + if (stream->position == (zend_off_t)-1 && errno == ESPIPE) { stream->position = 0; stream->flags |= PHP_STREAM_FLAG_NO_SEEK; self->is_pipe = 1; @@ -261,7 +274,7 @@ PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const cha return stream; } -PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STREAMS_DC) { php_stream *stream = php_stream_fopen_from_file_int_rel(file, mode); @@ -282,18 +295,18 @@ PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STRE } } #endif - + if (self->is_pipe) { stream->flags |= PHP_STREAM_FLAG_NO_SEEK; } else { - stream->position = ftell(file); + stream->position = zend_ftell(file); } } return stream; } -PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STREAMS_DC) { php_stdio_stream_data *self; php_stream *stream; @@ -305,28 +318,39 @@ PHPAPI php_stream *_php_stream_fopen_from_pipe(FILE *file, const char *mode STRE self->lock_flag = LOCK_UN; self->is_process_pipe = 1; self->fd = fileno(file); - self->temp_file_name = NULL; + self->temp_name = NULL; +#ifdef PHP_WIN32 + self->is_pipe_blocking = 0; +#endif stream = php_stream_alloc_rel(&php_stream_stdio_ops, self, 0, mode); stream->flags |= PHP_STREAM_FLAG_NO_SEEK; return stream; } -static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; assert(data != NULL); if (data->fd >= 0) { +#ifdef PHP_WIN32 + int bytes_written; + if (ZEND_SIZE_T_UINT_OVFL(count)) { + count = UINT_MAX; + } + bytes_written = _write(data->fd, buf, (unsigned int)count); +#else int bytes_written = write(data->fd, buf, count); +#endif if (bytes_written < 0) return 0; return (size_t) bytes_written; } else { #if HAVE_FLUSHIO if (!data->is_pipe && data->last_op == 'r') { - fseek(data->file, 0, SEEK_CUR); + zend_fseek(data->file, 0, SEEK_CUR); } data->last_op = 'w'; #endif @@ -335,7 +359,7 @@ static size_t php_stdiop_write(php_stream *stream, const char *buf, size_t count } } -static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; size_t ret; @@ -346,7 +370,7 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count TSRMLS #ifdef PHP_WIN32 php_stdio_stream_data *self = (php_stdio_stream_data*)stream->abstract; - if (self->is_pipe || self->is_process_pipe) { + if ((self->is_pipe || self->is_process_pipe) && !self->is_pipe_blocking) { HANDLE ph = (HANDLE)_get_osfhandle(data->fd); int retry = 0; DWORD avail_read = 0; @@ -371,21 +395,21 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count TSRMLS } } #endif - ret = read(data->fd, buf, count); + ret = read(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count)); if (ret == (size_t)-1 && errno == EINTR) { /* Read was interrupted, retry once, If read still fails, giveup with feof==0 so script can retry if desired */ - ret = read(data->fd, buf, count); + ret = read(data->fd, buf, PLAIN_WRAP_BUF_SIZE(count)); } - + stream->eof = (ret == 0 || (ret == (size_t)-1 && errno != EWOULDBLOCK && errno != EINTR && errno != EBADF)); - + } else { #if HAVE_FLUSHIO if (!data->is_pipe && data->last_op == 'w') - fseek(data->file, 0, SEEK_CUR); + zend_fseek(data->file, 0, SEEK_CUR); data->last_op = 'r'; #endif @@ -396,7 +420,7 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count TSRMLS return ret; } -static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC) +static int php_stdiop_close(php_stream *stream, int close_handle) { int ret; php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; @@ -418,7 +442,7 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC) data->file_mapping = NULL; } #endif - + if (close_handle) { if (data->file) { if (data->is_process_pipe) { @@ -440,11 +464,11 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC) } else { return 0; /* everything should be closed already -> success */ } - if (data->temp_file_name) { - unlink(data->temp_file_name); + if (data->temp_name) { + unlink(ZSTR_VAL(data->temp_name)); /* temporary streams are never persistent */ - efree(data->temp_file_name); - data->temp_file_name = NULL; + zend_string_release(data->temp_name); + data->temp_name = NULL; } } else { ret = 0; @@ -457,7 +481,7 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC) return ret; } -static int php_stdiop_flush(php_stream *stream TSRMLS_DC) +static int php_stdiop_flush(php_stream *stream) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; @@ -474,7 +498,7 @@ static int php_stdiop_flush(php_stream *stream TSRMLS_DC) return 0; } -static int php_stdiop_seek(php_stream *stream, off_t offset, int whence, off_t *newoffset TSRMLS_DC) +static int php_stdiop_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffset) { php_stdio_stream_data *data = (php_stdio_stream_data*)stream->abstract; int ret; @@ -482,34 +506,34 @@ static int php_stdiop_seek(php_stream *stream, off_t offset, int whence, off_t * assert(data != NULL); if (data->is_pipe) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot seek on a pipe"); + php_error_docref(NULL, E_WARNING, "cannot seek on a pipe"); return -1; } if (data->fd >= 0) { - off_t result; - - result = lseek(data->fd, offset, whence); - if (result == (off_t)-1) + zend_off_t result; + + result = zend_lseek(data->fd, offset, whence); + if (result == (zend_off_t)-1) return -1; *newoffset = result; return 0; - + } else { - ret = fseek(data->file, offset, whence); - *newoffset = ftell(data->file); + ret = zend_fseek(data->file, offset, whence); + *newoffset = zend_ftell(data->file); return ret; } } -static int php_stdiop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) +static int php_stdiop_cast(php_stream *stream, int castas, void **ret) { php_socket_t fd; php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract; assert(data != NULL); - + /* as soon as someone touches the stdio layer, buffering may ensue, * so we need to stop using the fd directly in that case */ @@ -527,7 +551,7 @@ static int php_stdiop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) return FAILURE; } } - + *(FILE**)ret = data->file; data->fd = SOCK_ERR; } @@ -561,19 +585,20 @@ static int php_stdiop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) } } -static int php_stdiop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +static int php_stdiop_stat(php_stream *stream, php_stream_statbuf *ssb) { int ret; php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract; assert(data != NULL); + if((ret = do_fstat(data, 1)) == 0) { + memcpy(&ssb->sb, &data->sb, sizeof(ssb->sb)); + } - ret = do_fstat(data, 1); - memcpy(&ssb->sb, &data->sb, sizeof(ssb->sb)); return ret; } -static int php_stdiop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +static int php_stdiop_set_option(php_stream *stream, int option, int value, void *ptrparam) { php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract; size_t size; @@ -583,9 +608,9 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void int flags; int oldval; #endif - + PHP_STDIOP_GET_FD(fd, data); - + switch(option) { case PHP_STREAM_OPTION_BLOCKING: if (fd == -1) @@ -597,20 +622,20 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void flags &= ~O_NONBLOCK; else flags |= O_NONBLOCK; - + if (-1 == fcntl(fd, F_SETFL, flags)) return -1; return oldval; #else return -1; /* not yet implemented */ #endif - + case PHP_STREAM_OPTION_WRITE_BUFFER: if (data->file == NULL) { return -1; } - + if (ptrparam) size = *(size_t *)ptrparam; else @@ -619,10 +644,10 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void switch(value) { case PHP_STREAM_BUFFER_NONE: return setvbuf(data->file, NULL, _IONBF, 0); - + case PHP_STREAM_BUFFER_LINE: return setvbuf(data->file, NULL, _IOLBF, size); - + case PHP_STREAM_BUFFER_FULL: return setvbuf(data->file, NULL, _IOFBF, size); @@ -630,7 +655,7 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void return -1; } break; - + case PHP_STREAM_OPTION_LOCKING: if (fd == -1) { return -1; @@ -653,13 +678,15 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void { php_stream_mmap_range *range = (php_stream_mmap_range*)ptrparam; int prot, flags; - + switch (value) { case PHP_STREAM_MMAP_SUPPORTED: return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; case PHP_STREAM_MMAP_MAP_RANGE: - do_fstat(data, 1); + if(do_fstat(data, 1) != 0) { + return PHP_STREAM_OPTION_RETURN_ERR; + } if (range->length == 0 && range->offset > 0 && range->offset < data->sb.st_size) { range->length = data->sb.st_size - range->offset; } @@ -770,8 +797,8 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void GetSystemInfo(&info); gran = info.dwAllocationGranularity; - loffs = (range->offset / gran) * gran; - delta = range->offset - loffs; + loffs = ((DWORD)range->offset / gran) * gran; + delta = (DWORD)range->offset - loffs; } data->last_mapped_addr = MapViewOfFile(data->file_mapping, acc, 0, loffs, range->length + delta); @@ -818,7 +845,13 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void return ftruncate(fd, new_size) == 0 ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR; } } - + +#ifdef PHP_WIN32 + case PHP_STREAM_OPTION_PIPE_BLOCKING: + data->is_pipe_blocking = value; + return PHP_STREAM_OPTION_RETURN_OK; +#endif + default: return PHP_STREAM_OPTION_RETURN_NOTIMPL; } @@ -836,7 +869,7 @@ PHPAPI php_stream_ops php_stream_stdio_ops = { /* }}} */ /* {{{ plain files opendir/readdir implementation */ -static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size_t count) { DIR *dir = (DIR*)stream->abstract; /* avoid libc5 readdir problems */ @@ -855,12 +888,12 @@ static size_t php_plain_files_dirstream_read(php_stream *stream, char *buf, size return 0; } -static int php_plain_files_dirstream_close(php_stream *stream, int close_handle TSRMLS_DC) +static int php_plain_files_dirstream_close(php_stream *stream, int close_handle) { return closedir((DIR *)stream->abstract); } -static int php_plain_files_dirstream_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) +static int php_plain_files_dirstream_rewind(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs) { rewinddir((DIR *)stream->abstract); return 0; @@ -877,26 +910,26 @@ static php_stream_ops php_plain_files_dirstream_ops = { }; static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, const char *path, const char *mode, - int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) + int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) { DIR *dir = NULL; php_stream *stream = NULL; #ifdef HAVE_GLOB if (options & STREAM_USE_GLOB_DIR_OPEN) { - return php_glob_stream_wrapper.wops->dir_opener(&php_glob_stream_wrapper, path, mode, options, opened_path, context STREAMS_REL_CC TSRMLS_CC); + return php_glob_stream_wrapper.wops->dir_opener(&php_glob_stream_wrapper, path, mode, options, opened_path, context STREAMS_REL_CC); } #endif - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) { + if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path)) { return NULL; } - + dir = VCWD_OPENDIR(path); #ifdef PHP_WIN32 if (!dir) { - php_win32_docref2_from_error(GetLastError(), path, path TSRMLS_CC); + php_win32_docref2_from_error(GetLastError(), path, path); } if (dir && dir->finished) { @@ -909,15 +942,15 @@ static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, const if (stream == NULL) closedir(dir); } - + return stream; } /* }}} */ /* {{{ php_stream_fopen */ -PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, char **opened_path, int options STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, zend_string **opened_path, int options STREAMS_DC) { - char *realpath = NULL; + char realpath[MAXPATHLEN]; int open_flags; int fd; php_stream *ret; @@ -926,38 +959,35 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha if (FAILURE == php_stream_parse_fopen_modes(mode, &open_flags)) { if (options & REPORT_ERRORS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "`%s' is not a valid mode for fopen", mode); + php_error_docref(NULL, E_WARNING, "`%s' is not a valid mode for fopen", mode); } return NULL; } if (options & STREAM_ASSUME_REALPATH) { - realpath = estrdup(filename); + strlcpy(realpath, filename, sizeof(realpath)); } else { - if ((realpath = expand_filepath(filename, NULL TSRMLS_CC)) == NULL) { + if (expand_filepath(filename, realpath) == NULL) { return NULL; } } if (persistent) { spprintf(&persistent_id, 0, "streams_stdio_%d_%s", open_flags, realpath); - switch (php_stream_from_persistent_id(persistent_id, &ret TSRMLS_CC)) { + switch (php_stream_from_persistent_id(persistent_id, &ret)) { case PHP_STREAM_PERSISTENT_SUCCESS: if (opened_path) { - *opened_path = realpath; - realpath = NULL; + //TODO: avoid reallocation??? + *opened_path = zend_string_init(realpath, strlen(realpath), 0); } /* fall through */ case PHP_STREAM_PERSISTENT_FAILURE: - if (realpath) { - efree(realpath); - } efree(persistent_id);; return ret; } } - + fd = open(realpath, open_flags, 0666); if (fd != -1) { @@ -970,11 +1000,7 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha if (ret) { if (opened_path) { - *opened_path = realpath; - realpath = NULL; - } - if (realpath) { - efree(realpath); + *opened_path = zend_string_init(realpath, strlen(realpath), 0); } if (persistent_id) { efree(persistent_id); @@ -992,20 +1018,24 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha r = do_fstat(self, 0); if ((r == 0 && !S_ISREG(self->sb.st_mode))) { if (opened_path) { - efree(*opened_path); + zend_string_release(*opened_path); *opened_path = NULL; } php_stream_close(ret); return NULL; } } + + if (options & STREAM_USE_BLOCKING_PIPE) { + php_stdio_stream_data *self = (php_stdio_stream_data*)ret->abstract; + self->is_pipe_blocking = 1; + } #endif return ret; } close(fd); } - efree(realpath); if (persistent_id) { efree(persistent_id); } @@ -1015,30 +1045,28 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha static php_stream *php_plain_files_stream_opener(php_stream_wrapper *wrapper, const char *path, const char *mode, - int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) + int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) { - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) { + if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path)) { return NULL; } return php_stream_fopen_rel(path, mode, opened_path, options); } -static int php_plain_files_url_stater(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) +static int php_plain_files_url_stater(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context) { if (strncasecmp(url, "file://", sizeof("file://") - 1) == 0) { url += sizeof("file://") - 1; } - if (php_check_open_basedir_ex(url, (flags & PHP_STREAM_URL_STAT_QUIET) ? 0 : 1 TSRMLS_CC)) { + if (php_check_open_basedir_ex(url, (flags & PHP_STREAM_URL_STAT_QUIET) ? 0 : 1)) { return -1; } #ifdef PHP_WIN32 - if (EG(windows_version_info).dwMajorVersion >= 5) { - if (flags & PHP_STREAM_URL_STAT_LINK) { - return VCWD_LSTAT(url, &ssb->sb); - } + if (flags & PHP_STREAM_URL_STAT_LINK) { + return VCWD_LSTAT(url, &ssb->sb); } #else # ifdef HAVE_SYMLINK @@ -1050,7 +1078,7 @@ static int php_plain_files_url_stater(php_stream_wrapper *wrapper, const char *u return VCWD_STAT(url, &ssb->sb); } -static int php_plain_files_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) +static int php_plain_files_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) { int ret; @@ -1058,25 +1086,25 @@ static int php_plain_files_unlink(php_stream_wrapper *wrapper, const char *url, url += sizeof("file://") - 1; } - if (php_check_open_basedir(url TSRMLS_CC)) { + if (php_check_open_basedir(url)) { return 0; } ret = VCWD_UNLINK(url); if (ret == -1) { if (options & REPORT_ERRORS) { - php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "%s", strerror(errno)); + php_error_docref1(NULL, url, E_WARNING, "%s", strerror(errno)); } return 0; } /* Clear stat cache (and realpath cache) */ - php_clear_stat_cache(1, NULL, 0 TSRMLS_CC); + php_clear_stat_cache(1, NULL, 0); return 1; } -static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC) +static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context) { int ret; @@ -1085,12 +1113,12 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f } #ifdef PHP_WIN32 - if (!php_win32_check_trailing_space(url_from, strlen(url_from))) { - php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to TSRMLS_CC); + if (!php_win32_check_trailing_space(url_from, (int)strlen(url_from))) { + php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to); return 0; } - if (!php_win32_check_trailing_space(url_to, strlen(url_to))) { - php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to TSRMLS_CC); + if (!php_win32_check_trailing_space(url_to, (int)strlen(url_to))) { + php_win32_docref2_from_error(ERROR_INVALID_NAME, url_from, url_to); return 0; } #endif @@ -1103,7 +1131,7 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f url_to += sizeof("file://") - 1; } - if (php_check_open_basedir(url_from TSRMLS_CC) || php_check_open_basedir(url_to TSRMLS_CC)) { + if (php_check_open_basedir(url_from) || php_check_open_basedir(url_to)) { return 0; } @@ -1113,26 +1141,26 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f #ifndef PHP_WIN32 # ifdef EXDEV if (errno == EXDEV) { - struct stat sb; - if (php_copy_file(url_from, url_to TSRMLS_CC) == SUCCESS) { + zend_stat_t sb; + if (php_copy_file(url_from, url_to) == SUCCESS) { if (VCWD_STAT(url_from, &sb) == 0) { # if !defined(TSRM_WIN32) && !defined(NETWARE) if (VCWD_CHMOD(url_to, sb.st_mode)) { if (errno == EPERM) { - php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); VCWD_UNLINK(url_from); return 1; } - php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); return 0; } if (VCWD_CHOWN(url_to, sb.st_uid, sb.st_gid)) { if (errno == EPERM) { - php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); VCWD_UNLINK(url_from); return 1; } - php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); return 0; } # endif @@ -1140,27 +1168,27 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, const char *url_f return 1; } } - php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); return 0; } # endif #endif #ifdef PHP_WIN32 - php_win32_docref2_from_error(GetLastError(), url_from, url_to TSRMLS_CC); + php_win32_docref2_from_error(GetLastError(), url_from, url_to); #else - php_error_docref2(NULL TSRMLS_CC, url_from, url_to, E_WARNING, "%s", strerror(errno)); + php_error_docref2(NULL, url_from, url_to, E_WARNING, "%s", strerror(errno)); #endif return 0; } /* Clear stat cache (and realpath cache) */ - php_clear_stat_cache(1, NULL, 0 TSRMLS_CC); + php_clear_stat_cache(1, NULL, 0); return 1; } -static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, int mode, int options, php_stream_context *context TSRMLS_DC) +static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, int mode, int options, php_stream_context *context) { int ret, recursive = options & PHP_STREAM_MKDIR_RECURSIVE; char *p; @@ -1170,17 +1198,17 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i } if (!recursive) { - ret = php_mkdir(dir, mode TSRMLS_CC); + ret = php_mkdir(dir, mode); } else { /* we look for directory separator from the end of string, thus hopefuly reducing our work load */ char *e; - struct stat sb; - int dir_len = strlen(dir); + zend_stat_t sb; + int dir_len = (int)strlen(dir); int offset = 0; char buf[MAXPATHLEN]; - if (!expand_filepath_with_mode(dir, buf, NULL, 0, CWD_EXPAND TSRMLS_CC)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid path"); + if (!expand_filepath_with_mode(dir, buf, NULL, 0, CWD_EXPAND )) { + php_error_docref(NULL, E_WARNING, "Invalid path"); return 0; } @@ -1191,7 +1219,7 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i } if (p && dir_len == 1) { - /* buf == "DEFAULT_SLASH" */ + /* buf == "DEFAULT_SLASH" */ } else { /* find a top level directory we need to create */ @@ -1217,8 +1245,8 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i } if (p == buf) { - ret = php_mkdir(dir, mode TSRMLS_CC); - } else if (!(ret = php_mkdir(buf, mode TSRMLS_CC))) { + ret = php_mkdir(dir, mode); + } else if (!(ret = php_mkdir(buf, mode))) { if (!p) { p = buf; } @@ -1229,7 +1257,7 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i if ((*(p+1) != '\0') && (ret = VCWD_MKDIR(buf, (mode_t)mode)) < 0) { if (options & REPORT_ERRORS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); + php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); } break; } @@ -1246,35 +1274,35 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, const char *dir, i } } -static int php_plain_files_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) +static int php_plain_files_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) { if (strncasecmp(url, "file://", sizeof("file://") - 1) == 0) { url += sizeof("file://") - 1; } - if (php_check_open_basedir(url TSRMLS_CC)) { + if (php_check_open_basedir(url)) { return 0; } #if PHP_WIN32 if (!php_win32_check_trailing_space(url, (int)strlen(url))) { - php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "%s", strerror(ENOENT)); + php_error_docref1(NULL, url, E_WARNING, "%s", strerror(ENOENT)); return 0; } #endif if (VCWD_RMDIR(url) < 0) { - php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "%s", strerror(errno)); + php_error_docref1(NULL, url, E_WARNING, "%s", strerror(errno)); return 0; } /* Clear stat cache (and realpath cache) */ - php_clear_stat_cache(1, NULL, 0 TSRMLS_CC); + php_clear_stat_cache(1, NULL, 0); return 1; } -static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url, int option, void *value, php_stream_context *context TSRMLS_DC) +static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url, int option, void *value, php_stream_context *context) { struct utimbuf *newtime; #if !defined(WINDOWS) && !defined(NETWARE) @@ -1284,12 +1312,12 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url mode_t mode; int ret = 0; #if PHP_WIN32 - int url_len = strlen(url); + int url_len = (int)strlen(url); #endif #if PHP_WIN32 if (!php_win32_check_trailing_space(url, url_len)) { - php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "%s", strerror(ENOENT)); + php_error_docref1(NULL, url, E_WARNING, "%s", strerror(ENOENT)); return 0; } #endif @@ -1298,7 +1326,7 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url url += sizeof("file://") - 1; } - if (php_check_open_basedir(url TSRMLS_CC)) { + if (php_check_open_basedir(url)) { return 0; } @@ -1308,7 +1336,7 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url if (VCWD_ACCESS(url, F_OK) != 0) { FILE *file = VCWD_FOPEN(url, "w"); if (file == NULL) { - php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "Unable to create file %s because %s", url, strerror(errno)); + php_error_docref1(NULL, url, E_WARNING, "Unable to create file %s because %s", url, strerror(errno)); return 0; } fclose(file); @@ -1320,8 +1348,8 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url case PHP_STREAM_META_OWNER_NAME: case PHP_STREAM_META_OWNER: if(option == PHP_STREAM_META_OWNER_NAME) { - if(php_get_uid_by_name((char *)value, &uid TSRMLS_CC) != SUCCESS) { - php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "Unable to find uid for %s", (char *)value); + if(php_get_uid_by_name((char *)value, &uid) != SUCCESS) { + php_error_docref1(NULL, url, E_WARNING, "Unable to find uid for %s", (char *)value); return 0; } } else { @@ -1332,8 +1360,8 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url case PHP_STREAM_META_GROUP: case PHP_STREAM_META_GROUP_NAME: if(option == PHP_STREAM_META_GROUP_NAME) { - if(php_get_gid_by_name((char *)value, &gid TSRMLS_CC) != SUCCESS) { - php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "Unable to find gid for %s", (char *)value); + if(php_get_gid_by_name((char *)value, &gid) != SUCCESS) { + php_error_docref1(NULL, url, E_WARNING, "Unable to find gid for %s", (char *)value); return 0; } } else { @@ -1343,18 +1371,18 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, const char *url break; #endif case PHP_STREAM_META_ACCESS: - mode = (mode_t)*(long *)value; + mode = (mode_t)*(zend_long *)value; ret = VCWD_CHMOD(url, mode); break; default: - php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "Unknown option %d for stream_metadata", option); + php_error_docref1(NULL, url, E_WARNING, "Unknown option %d for stream_metadata", option); return 0; } if (ret == -1) { - php_error_docref1(NULL TSRMLS_CC, url, E_WARNING, "Operation failed: %s", strerror(errno)); + php_error_docref1(NULL, url, E_WARNING, "Operation failed: %s", strerror(errno)); return 0; } - php_clear_stat_cache(0, NULL, 0 TSRMLS_CC); + php_clear_stat_cache(0, NULL, 0); return 1; } @@ -1373,24 +1401,22 @@ static php_stream_wrapper_ops php_plain_files_wrapper_ops = { php_plain_files_metadata }; -php_stream_wrapper php_plain_files_wrapper = { +PHPAPI php_stream_wrapper php_plain_files_wrapper = { &php_plain_files_wrapper_ops, NULL, 0 }; /* {{{ php_stream_fopen_with_path */ -PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char *mode, const char *path, char **opened_path, int options STREAMS_DC TSRMLS_DC) +PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path, int options STREAMS_DC) { /* code ripped off from fopen_wrappers.c */ char *pathbuf, *end; const char *ptr; - const char *exec_fname; char trypath[MAXPATHLEN]; php_stream *stream; - int path_length; int filename_length; - int exec_fname_length; + zend_string *exec_filename; if (opened_path) { *opened_path = NULL; @@ -1400,7 +1426,10 @@ PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char return NULL; } - filename_length = strlen(filename); + filename_length = (int)strlen(filename); +#ifndef PHP_WIN32 + (void) filename_length; +#endif /* Relative path open */ if (*filename == '.' && (IS_SLASH(filename[1]) || filename[1] == '.')) { @@ -1414,7 +1443,7 @@ PHPAPI php_stream *_php_stream_fopen_with_path(const char *filename, const char } - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(filename TSRMLS_CC)) { + if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(filename)) { return NULL; } @@ -1426,31 +1455,31 @@ not_relative_path: /* Absolute path open */ if (IS_ABSOLUTE_PATH(filename, filename_length)) { - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(filename TSRMLS_CC)) { + if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(filename)) { return NULL; } return php_stream_fopen_rel(filename, mode, opened_path, options); } - + #ifdef PHP_WIN32 if (IS_SLASH(filename[0])) { size_t cwd_len; char *cwd; - cwd = virtual_getcwd_ex(&cwd_len TSRMLS_CC); + cwd = virtual_getcwd_ex(&cwd_len); /* getcwd() will return always return [DRIVE_LETTER]:/) on windows. */ *(cwd+3) = '\0'; - + if (snprintf(trypath, MAXPATHLEN, "%s%s", cwd, filename) >= MAXPATHLEN) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", cwd, filename, MAXPATHLEN); + php_error_docref(NULL, E_NOTICE, "%s/%s path was truncated to %d", cwd, filename, MAXPATHLEN); } - + efree(cwd); - - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(trypath TSRMLS_CC)) { + + if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(trypath)) { return NULL; } - + return php_stream_fopen_rel(trypath, mode, opened_path, options); } #endif @@ -1463,17 +1492,18 @@ not_relative_path: /* append the calling scripts' current working directory * as a fall back case */ - if (zend_is_executing(TSRMLS_C)) { - exec_fname = zend_get_executed_filename(TSRMLS_C); - exec_fname_length = strlen(exec_fname); - path_length = strlen(path); - - while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length])); - if ((exec_fname && exec_fname[0] == '[') - || exec_fname_length<=0) { - /* [no active file] or no path */ + if (zend_is_executing() && + (exec_filename = zend_get_executed_filename_ex()) != NULL) { + const char *exec_fname = ZSTR_VAL(exec_filename); + size_t exec_fname_length = ZSTR_LEN(exec_filename); + + while ((--exec_fname_length < SIZE_MAX) && !IS_SLASH(exec_fname[exec_fname_length])); + if (exec_fname_length<=0) { + /* no path */ pathbuf = estrdup(path); } else { + size_t path_length = strlen(path); + pathbuf = (char *) emalloc(exec_fname_length + path_length +1 +1); memcpy(pathbuf, path, path_length); pathbuf[path_length] = DEFAULT_DIR_SEPARATOR; @@ -1496,13 +1526,13 @@ not_relative_path: goto stream_skip; } if (snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename) >= MAXPATHLEN) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN); + php_error_docref(NULL, E_NOTICE, "%s/%s path was truncated to %d", ptr, filename, MAXPATHLEN); } - if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir_ex(trypath, 0 TSRMLS_CC)) { + if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir_ex(trypath, 0)) { goto stream_skip; } - + stream = php_stream_fopen_rel(trypath, mode, opened_path, options); if (stream) { efree(pathbuf); diff --git a/main/streams/streams.c b/main/streams/streams.c index 90fc505185..7f919ca834 100644 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -55,7 +55,7 @@ PHPAPI int php_file_le_stream_filter(void) return le_stream_filter; } -PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(TSRMLS_D) +PHPAPI HashTable *_php_stream_get_url_stream_wrappers_hash(void) { return (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); } @@ -65,19 +65,12 @@ PHPAPI HashTable *php_stream_get_url_stream_wrappers_hash_global(void) return &url_stream_wrappers_hash; } -static int _php_stream_release_context(zend_rsrc_list_entry *le, void *pContext TSRMLS_DC) -{ - if (le->ptr == pContext) { - return --le->refcount == 0; - } - return 0; -} - -static int forget_persistent_resource_id_numbers(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static int forget_persistent_resource_id_numbers(zval *el) { php_stream *stream; + zend_resource *rsrc = Z_RES_P(el); - if (Z_TYPE_P(rsrc) != le_pstream) { + if (rsrc->type != le_pstream) { return 0; } @@ -87,13 +80,10 @@ static int forget_persistent_resource_id_numbers(zend_rsrc_list_entry *rsrc TSRM fprintf(stderr, "forget_persistent: %s:%p\n", stream->ops->label, stream); #endif - stream->rsrc_id = FAILURE; + stream->res = NULL; - if (stream->context) { - zend_hash_apply_with_argument(&EG(regular_list), - (apply_func_arg_t) _php_stream_release_context, - stream->context TSRMLS_CC); - stream->context = NULL; + if (stream->ctx) { + zend_list_delete(stream->ctx); } return 0; @@ -101,7 +91,7 @@ fprintf(stderr, "forget_persistent: %s:%p\n", stream->ops->label, stream); PHP_RSHUTDOWN_FUNCTION(streams) { - zend_hash_apply(&EG(persistent_list), (apply_func_t)forget_persistent_resource_id_numbers TSRMLS_CC); + zend_hash_apply(&EG(persistent_list), forget_persistent_resource_id_numbers); return SUCCESS; } @@ -114,39 +104,28 @@ PHPAPI php_stream *php_stream_encloses(php_stream *enclosing, php_stream *enclos return orig; } -PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream TSRMLS_DC) +PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream **stream) { - zend_rsrc_list_entry *le; + zend_resource *le; - if (zend_hash_find(&EG(persistent_list), (char*)persistent_id, strlen(persistent_id)+1, (void*) &le) == SUCCESS) { - if (Z_TYPE_P(le) == le_pstream) { + if ((le = zend_hash_str_find_ptr(&EG(persistent_list), persistent_id, strlen(persistent_id))) != NULL) { + if (le->type == le_pstream) { if (stream) { - HashPosition pos; - zend_rsrc_list_entry *regentry; - ulong index = -1; /* intentional */ + zend_resource *regentry = NULL; /* see if this persistent resource already has been loaded to the * regular list; allowing the same resource in several entries in the * regular list causes trouble (see bug #54623) */ - zend_hash_internal_pointer_reset_ex(&EG(regular_list), &pos); - while (zend_hash_get_current_data_ex(&EG(regular_list), - (void **)®entry, &pos) == SUCCESS) { + *stream = (php_stream*)le->ptr; + ZEND_HASH_FOREACH_PTR(&EG(regular_list), regentry) { if (regentry->ptr == le->ptr) { - zend_hash_get_current_key_ex(&EG(regular_list), NULL, NULL, - &index, 0, &pos); - break; + GC_REFCOUNT(regentry)++; + (*stream)->res = regentry; + return PHP_STREAM_PERSISTENT_SUCCESS; } - zend_hash_move_forward_ex(&EG(regular_list), &pos); - } - - *stream = (php_stream*)le->ptr; - if (index == -1) { /* not found in regular list */ - le->refcount++; - (*stream)->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, *stream, le_pstream); - } else { - regentry->refcount++; - (*stream)->rsrc_id = index; - } + } ZEND_HASH_FOREACH_END(); + GC_REFCOUNT(le)++; + (*stream)->res = zend_register_resource(*stream, le_pstream); } return PHP_STREAM_PERSISTENT_SUCCESS; } @@ -157,32 +136,29 @@ PHPAPI int php_stream_from_persistent_id(const char *persistent_id, php_stream * /* }}} */ -static zend_llist *php_get_wrapper_errors_list(php_stream_wrapper *wrapper TSRMLS_DC) +static zend_llist *php_get_wrapper_errors_list(php_stream_wrapper *wrapper) { - zend_llist *list = NULL; if (!FG(wrapper_errors)) { return NULL; } else { - zend_hash_find(FG(wrapper_errors), (const char*)&wrapper, - sizeof wrapper, (void**)&list); - return list; + return (zend_llist*) zend_hash_str_find_ptr(FG(wrapper_errors), (const char*)&wrapper, sizeof(wrapper)); } } /* {{{ wrapper error reporting */ -void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption TSRMLS_DC) +void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char *path, const char *caption) { char *tmp = estrdup(path); char *msg; int free_msg = 0; if (wrapper) { - zend_llist *err_list = php_get_wrapper_errors_list(wrapper TSRMLS_CC); + zend_llist *err_list = php_get_wrapper_errors_list(wrapper); if (err_list) { size_t l = 0; int brlen; int i; - int count = zend_llist_count(err_list); + int count = (int)zend_llist_count(err_list); const char *br; const char **err_buf_p; zend_llist_position pos; @@ -227,17 +203,17 @@ void php_stream_display_wrapper_errors(php_stream_wrapper *wrapper, const char * } php_strip_url_passwd(tmp); - php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "%s: %s", caption, msg); + php_error_docref1(NULL, tmp, E_WARNING, "%s: %s", caption, msg); efree(tmp); if (free_msg) { efree(msg); } } -void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper TSRMLS_DC) +void php_stream_tidy_wrapper_error_log(php_stream_wrapper *wrapper) { if (wrapper && FG(wrapper_errors)) { - zend_hash_del(FG(wrapper_errors), (const char*)&wrapper, sizeof wrapper); + zend_hash_str_del(FG(wrapper_errors), (const char*)&wrapper, sizeof(wrapper)); } } @@ -246,7 +222,13 @@ static void wrapper_error_dtor(void *error) efree(*(char**)error); } -PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options TSRMLS_DC, const char *fmt, ...) +static void wrapper_list_dtor(zval *item) { + zend_llist *list = (zend_llist*)Z_PTR_P(item); + zend_llist_destroy(list); + efree(list); +} + +PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int options, const char *fmt, ...) { va_list args; char *buffer = NULL; @@ -256,24 +238,22 @@ PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int option va_end(args); if (options & REPORT_ERRORS || wrapper == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", buffer); + php_error_docref(NULL, E_WARNING, "%s", buffer); efree(buffer); } else { zend_llist *list = NULL; if (!FG(wrapper_errors)) { ALLOC_HASHTABLE(FG(wrapper_errors)); - zend_hash_init(FG(wrapper_errors), 8, NULL, - (dtor_func_t)zend_llist_destroy, 0); + zend_hash_init(FG(wrapper_errors), 8, NULL, wrapper_list_dtor, 0); } else { - zend_hash_find(FG(wrapper_errors), (const char*)&wrapper, - sizeof wrapper, (void**)&list); + list = zend_hash_str_find_ptr(FG(wrapper_errors), (const char*)&wrapper, sizeof(wrapper)); } if (!list) { zend_llist new_list; - zend_llist_init(&new_list, sizeof buffer, wrapper_error_dtor, 0); - zend_hash_update(FG(wrapper_errors), (const char*)&wrapper, - sizeof wrapper, &new_list, sizeof new_list, (void**)&list); + zend_llist_init(&new_list, sizeof(buffer), wrapper_error_dtor, 0); + list = zend_hash_str_update_mem(FG(wrapper_errors), (const char*)&wrapper, + sizeof(wrapper), &new_list, sizeof(new_list)); } /* append to linked list */ @@ -285,7 +265,7 @@ PHPAPI void php_stream_wrapper_log_error(php_stream_wrapper *wrapper, int option /* }}} */ /* allocate a new stream for a particular ops */ -PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, const char *persistent_id, const char *mode STREAMS_DC TSRMLS_DC) /* {{{ */ +PHPAPI php_stream *_php_stream_alloc(php_stream_ops *ops, void *abstract, const char *persistent_id, const char *mode STREAMS_DC) /* {{{ */ { php_stream *ret; @@ -315,30 +295,26 @@ fprintf(stderr, "stream_alloc: %s:%p persistent=%s\n", ops->label, ret, persiste } if (persistent_id) { - zend_rsrc_list_entry le; - - Z_TYPE(le) = le_pstream; - le.ptr = ret; - le.refcount = 0; + zval tmp; - if (FAILURE == zend_hash_update(&EG(persistent_list), (char *)persistent_id, - strlen(persistent_id) + 1, - (void *)&le, sizeof(le), NULL)) { + ZVAL_NEW_PERSISTENT_RES(&tmp, -1, ret, le_pstream); + if (NULL == zend_hash_str_update(&EG(persistent_list), persistent_id, + strlen(persistent_id), &tmp)) { pefree(ret, 1); return NULL; } } - ret->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, ret, persistent_id ? le_pstream : le_stream); + ret->res = zend_register_resource(ret, persistent_id ? le_pstream : le_stream); strlcpy(ret->mode, mode, sizeof(ret->mode)); ret->wrapper = NULL; ret->wrapperthis = NULL; - ret->wrapperdata = NULL; + ZVAL_UNDEF(&ret->wrapperdata); ret->stdiocast = NULL; ret->orig_path = NULL; - ret->context = NULL; + ret->ctx = NULL; ret->readbuf = NULL; ret->enclosing_stream = NULL; @@ -346,10 +322,10 @@ fprintf(stderr, "stream_alloc: %s:%p persistent=%s\n", ops->label, ret, persiste } /* }}} */ -PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options TSRMLS_DC) /* {{{ */ +PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options) /* {{{ */ { - return _php_stream_free(stream_enclosed, - close_options | PHP_STREAM_FREE_IGNORE_ENCLOSING TSRMLS_CC); + return php_stream_free(stream_enclosed, + close_options | PHP_STREAM_FREE_IGNORE_ENCLOSING); } /* }}} */ @@ -374,13 +350,14 @@ static const char *_php_stream_pretty_free_options(int close_options, char *out) } #endif -static int _php_stream_free_persistent(zend_rsrc_list_entry *le, void *pStream TSRMLS_DC) +static int _php_stream_free_persistent(zval *zv, void *pStream) { + zend_resource *le = Z_RES_P(zv); return le->ptr == pStream; } -PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /* {{{ */ +PHPAPI int _php_stream_free(php_stream *stream, int close_options) /* {{{ */ { int ret = 1; int preserve_handle = close_options & PHP_STREAM_FREE_PRESERVE_HANDLE ? 1 : 0; @@ -391,7 +368,7 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /* * already been freed (if it was created after the stream resource), so * don't reference it */ if (EG(active)) { - context = stream->context; + context = PHP_STREAM_CONTEXT(stream); } if (stream->flags & PHP_STREAM_FLAG_NO_CLOSE) { @@ -404,7 +381,7 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /* fprintf(stderr, "stream_free: %s:%p[%s] in_free=%d opts=%s\n", stream->ops->label, stream, stream->orig_path, stream->in_free, _php_stream_pretty_free_options(close_options, out)); } - + #endif if (stream->in_free) { @@ -429,8 +406,8 @@ PHPAPI int _php_stream_free(php_stream *stream, int close_options TSRMLS_DC) /* /* we force PHP_STREAM_CALL_DTOR because that's from where the * enclosing stream can free this stream. We remove rsrc_dtor because * we want the enclosing stream to be deleted from the resource list */ - return _php_stream_free(enclosing_stream, - (close_options | PHP_STREAM_FREE_CALL_DTOR) & ~PHP_STREAM_FREE_RSRC_DTOR TSRMLS_CC); + return php_stream_free(enclosing_stream, + (close_options | PHP_STREAM_FREE_CALL_DTOR) & ~PHP_STREAM_FREE_RSRC_DTOR); } /* if we are releasing the stream only (and preserving the underlying handle), @@ -457,17 +434,20 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov (close_options & PHP_STREAM_FREE_RSRC_DTOR) == 0); #endif - /* make sure everything is saved */ - _php_stream_flush(stream, 1 TSRMLS_CC); + if (stream->flags & PHP_STREAM_FLAG_WAS_WRITTEN) { + /* make sure everything is saved */ + _php_stream_flush(stream, 1); + } /* If not called from the resource dtor, remove the stream from the resource list. */ - if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) == 0) { - /* zend_list_delete actually only decreases the refcount; if we're - * releasing the stream, we want to actually delete the resource from - * the resource list, otherwise the resource will point to invalid memory. - * In any case, let's always completely delete it from the resource list, - * not only when PHP_STREAM_FREE_RELEASE_STREAM is set */ - while (zend_list_delete(stream->rsrc_id) == SUCCESS) {} + if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) == 0 && stream->res) { + /* Close resource, but keep it in resource list */ + zend_list_close(stream->res); + if ((close_options & PHP_STREAM_FREE_KEEP_RSRC) == 0) { + /* Completely delete zend_resource, if not referenced */ + zend_list_delete(stream->res); + stream->res = NULL; + } } if (close_options & PHP_STREAM_FREE_CALL_DTOR) { @@ -483,7 +463,7 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov return fclose(stream->stdiocast); } - ret = stream->ops->close(stream, preserve_handle ? 0 : 1 TSRMLS_CC); + ret = stream->ops->close(stream, preserve_handle ? 0 : 1); stream->abstract = NULL; /* tidy up any FILE* that might have been fdopened */ @@ -496,20 +476,20 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov if (close_options & PHP_STREAM_FREE_RELEASE_STREAM) { while (stream->readfilters.head) { - php_stream_filter_remove(stream->readfilters.head, 1 TSRMLS_CC); + php_stream_filter_remove(stream->readfilters.head, 1); } while (stream->writefilters.head) { - php_stream_filter_remove(stream->writefilters.head, 1 TSRMLS_CC); + php_stream_filter_remove(stream->writefilters.head, 1); } if (stream->wrapper && stream->wrapper->wops && stream->wrapper->wops->stream_closer) { - stream->wrapper->wops->stream_closer(stream->wrapper, stream TSRMLS_CC); + stream->wrapper->wops->stream_closer(stream->wrapper, stream); stream->wrapper = NULL; } - if (stream->wrapperdata) { + if (Z_TYPE(stream->wrapperdata) != IS_UNDEF) { zval_ptr_dtor(&stream->wrapperdata); - stream->wrapperdata = NULL; + ZVAL_UNDEF(&stream->wrapperdata); } if (stream->readbuf) { @@ -519,27 +499,29 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov if (stream->is_persistent && (close_options & PHP_STREAM_FREE_PERSISTENT)) { /* we don't work with *stream but need its value for comparison */ - zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) _php_stream_free_persistent, stream TSRMLS_CC); + zend_hash_apply_with_argument(&EG(persistent_list), _php_stream_free_persistent, stream); } #if ZEND_DEBUG if ((close_options & PHP_STREAM_FREE_RSRC_DTOR) && (stream->__exposed == 0) && (EG(error_reporting) & E_WARNING)) { /* it leaked: Lets deliberately NOT pefree it so that the memory manager shows it * as leaked; it will log a warning, but lets help it out and display what kind * of stream it was. */ - char *leakinfo; - spprintf(&leakinfo, 0, __FILE__ "(%d) : Stream of type '%s' %p (path:%s) was not closed\n", __LINE__, stream->ops->label, stream, stream->orig_path); + if (!CG(unclean_shutdown)) { + char *leakinfo; + spprintf(&leakinfo, 0, __FILE__ "(%d) : Stream of type '%s' %p (path:%s) was not closed\n", __LINE__, stream->ops->label, stream, stream->orig_path); - if (stream->orig_path) { - pefree(stream->orig_path, stream->is_persistent); - stream->orig_path = NULL; - } + if (stream->orig_path) { + pefree(stream->orig_path, stream->is_persistent); + stream->orig_path = NULL; + } # if defined(PHP_WIN32) - OutputDebugString(leakinfo); + OutputDebugString(leakinfo); # else - fprintf(stderr, "%s", leakinfo); + fprintf(stderr, "%s", leakinfo); # endif - efree(leakinfo); + efree(leakinfo); + } } else { if (stream->orig_path) { pefree(stream->orig_path, stream->is_persistent); @@ -559,7 +541,7 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov } if (context) { - zend_list_delete(context->rsrc_id); + zend_list_delete(context->res); } return ret; @@ -568,7 +550,7 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov /* {{{ generic stream operations */ -PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_DC) +PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size) { /* allocate/fill the buffer */ @@ -593,12 +575,12 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ php_stream_filter *filter; /* read a chunk into a bucket */ - justread = stream->ops->read(stream, chunk_buf, stream->chunk_size TSRMLS_CC); + justread = stream->ops->read(stream, chunk_buf, stream->chunk_size); if (justread && justread != (size_t)-1) { - bucket = php_stream_bucket_new(stream, chunk_buf, justread, 0, 0 TSRMLS_CC); + bucket = php_stream_bucket_new(stream, chunk_buf, justread, 0, 0); /* after this call, bucket is owned by the brigade */ - php_stream_bucket_append(brig_inp, bucket TSRMLS_CC); + php_stream_bucket_append(brig_inp, bucket); flags = PSFS_FLAG_NORMAL; } else { @@ -607,7 +589,7 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ /* wind the handle... */ for (filter = stream->readfilters.head; filter; filter = filter->next) { - status = filter->fops->filter(stream, filter, brig_inp, brig_outp, NULL, flags TSRMLS_CC); + status = filter->fops->filter(stream, filter, brig_inp, brig_outp, NULL, flags); if (status != PSFS_PASS_ON) { break; @@ -639,8 +621,8 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ memcpy(stream->readbuf + stream->writepos, bucket->buf, bucket->buflen); stream->writepos += bucket->buflen; - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); } break; @@ -671,7 +653,7 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ } else { /* is there enough data in the buffer ? */ - if (stream->writepos - stream->readpos < (off_t)size) { + if (stream->writepos - stream->readpos < (zend_off_t)size) { size_t justread = 0; /* reduce buffer memory consumption if possible, to avoid a realloc */ @@ -689,9 +671,9 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ stream->is_persistent); } - justread = stream->ops->read(stream, stream->readbuf + stream->writepos, + justread = stream->ops->read(stream, (char*)stream->readbuf + stream->writepos, stream->readbuflen - stream->writepos - TSRMLS_CC); + ); if (justread != (size_t)-1) { stream->writepos += justread; @@ -700,7 +682,7 @@ PHPAPI void _php_stream_fill_read_buffer(php_stream *stream, size_t size TSRMLS_ } } -PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS_DC) +PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size) { size_t toread = 0, didread = 0; @@ -730,7 +712,7 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS } if (!stream->readfilters.head && (stream->flags & PHP_STREAM_FLAG_NO_BUFFER || stream->chunk_size == 1)) { - toread = stream->ops->read(stream, buf, size TSRMLS_CC); + toread = stream->ops->read(stream, buf, size); if (toread == (size_t) -1) { /* e.g. underlying read(2) returned -1 */ break; @@ -770,7 +752,7 @@ PHPAPI size_t _php_stream_read(php_stream *stream, char *buf, size_t size TSRMLS return didread; } -PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC) +PHPAPI int _php_stream_eof(php_stream *stream) { /* if there is data in the buffer, it's not EOF */ if (stream->writepos - stream->readpos > 0) { @@ -787,17 +769,17 @@ PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC) return stream->eof; } -PHPAPI int _php_stream_putc(php_stream *stream, int c TSRMLS_DC) +PHPAPI int _php_stream_putc(php_stream *stream, int c) { unsigned char buf = c; - if (php_stream_write(stream, &buf, 1) > 0) { + if (php_stream_write(stream, (char*)&buf, 1) > 0) { return 1; } return EOF; } -PHPAPI int _php_stream_getc(php_stream *stream TSRMLS_DC) +PHPAPI int _php_stream_getc(php_stream *stream) { char buf; @@ -807,9 +789,9 @@ PHPAPI int _php_stream_getc(php_stream *stream TSRMLS_DC) return EOF; } -PHPAPI int _php_stream_puts(php_stream *stream, const char *buf TSRMLS_DC) +PHPAPI int _php_stream_puts(php_stream *stream, const char *buf) { - int len; + size_t len; char newline[2] = "\n"; /* is this OK for Win? */ len = strlen(buf); @@ -819,13 +801,13 @@ PHPAPI int _php_stream_puts(php_stream *stream, const char *buf TSRMLS_DC) return 0; } -PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb) { memset(ssb, 0, sizeof(*ssb)); /* if the stream was wrapped, allow the wrapper to stat it */ if (stream->wrapper && stream->wrapper->wops->stream_stat != NULL) { - return stream->wrapper->wops->stream_stat(stream->wrapper, stream, ssb TSRMLS_CC); + return stream->wrapper->wops->stream_stat(stream->wrapper, stream, ssb); } /* if the stream doesn't directly support stat-ing, return with failure. @@ -836,21 +818,21 @@ PHPAPI int _php_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_D return -1; } - return (stream->ops->stat)(stream, ssb TSRMLS_CC); + return (stream->ops->stat)(stream, ssb); } -PHPAPI const char *php_stream_locate_eol(php_stream *stream, const char *buf, size_t buf_len TSRMLS_DC) +PHPAPI const char *php_stream_locate_eol(php_stream *stream, zend_string *buf) { size_t avail; const char *cr, *lf, *eol = NULL; const char *readptr; if (!buf) { - readptr = stream->readbuf + stream->readpos; + readptr = (char*)stream->readbuf + stream->readpos; avail = stream->writepos - stream->readpos; } else { - readptr = buf; - avail = buf_len; + readptr = ZSTR_VAL(buf); + avail = ZSTR_LEN(buf); } /* Look for EOL */ @@ -882,7 +864,7 @@ PHPAPI const char *php_stream_locate_eol(php_stream *stream, const char *buf, si * appropriate length to hold the line, regardless of the line length, memory * permitting */ PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, - size_t *returned_len TSRMLS_DC) + size_t *returned_len) { size_t avail = 0; size_t current_buf_size = 0; @@ -918,8 +900,8 @@ PHPAPI char *_php_stream_get_line(php_stream *stream, char *buf, size_t maxlen, const char *eol; int done = 0; - readptr = stream->readbuf + stream->readpos; - eol = php_stream_locate_eol(stream, NULL, 0 TSRMLS_CC); + readptr = (char*)stream->readbuf + stream->readpos; + eol = php_stream_locate_eol(stream, NULL); if (eol) { cpysz = eol - readptr + 1; @@ -1002,7 +984,7 @@ static const char *_php_stream_search_delim(php_stream *stream, size_t maxlen, size_t skiplen, const char *delim, /* non-empty! */ - size_t delim_len TSRMLS_DC) + size_t delim_len) { size_t seek_len; @@ -1022,13 +1004,13 @@ static const char *_php_stream_search_delim(php_stream *stream, } } -PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *returned_len, const char *delim, size_t delim_len TSRMLS_DC) +PHPAPI zend_string *php_stream_get_record(php_stream *stream, size_t maxlen, const char *delim, size_t delim_len) { - char *ret_buf; /* returned buffer */ + zend_string *ret_buf; /* returned buffer */ const char *found_delim = NULL; size_t buffered_len, tent_ret_len; /* tentative returned length */ - int has_delim = delim_len > 0; + int has_delim = delim_len > 0; if (maxlen == 0) { return NULL; @@ -1036,7 +1018,7 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re if (has_delim) { found_delim = _php_stream_search_delim( - stream, maxlen, 0, delim, delim_len TSRMLS_CC); + stream, maxlen, 0, delim, delim_len); } buffered_len = STREAM_BUFFERED_AMOUNT(stream); @@ -1062,14 +1044,14 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re * searched for the delimiter. * The left part of the delimiter may still remain in the buffer, * so subtract up to <delim_len - 1> from buffered_len, which is - * the ammount of data we skip on this search as an optimization + * the amount of data we skip on this search as an optimization */ found_delim = _php_stream_search_delim( stream, maxlen, buffered_len >= (delim_len - 1) ? buffered_len - (delim_len - 1) : 0, - delim, delim_len TSRMLS_CC); + delim, delim_len); if (found_delim) { break; } @@ -1097,21 +1079,21 @@ PHPAPI char *php_stream_get_record(php_stream *stream, size_t maxlen, size_t *re } } - ret_buf = emalloc(tent_ret_len + 1); + ret_buf = zend_string_alloc(tent_ret_len, 0); /* php_stream_read will not call ops->read here because the necessary * data is guaranteedly buffered */ - *returned_len = php_stream_read(stream, ret_buf, tent_ret_len); + ZSTR_LEN(ret_buf) = php_stream_read(stream, ZSTR_VAL(ret_buf), tent_ret_len); if (found_delim) { stream->readpos += delim_len; stream->position += delim_len; } - ret_buf[*returned_len] = '\0'; + ZSTR_VAL(ret_buf)[ZSTR_LEN(ret_buf)] = '\0'; return ret_buf; } /* Writes a buffer directly to a stream, using multiple of the chunk size */ -static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size_t count) { size_t didwrite = 0, towrite, justwrote; @@ -1121,7 +1103,7 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size if (stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0 && stream->readpos != stream->writepos) { stream->readpos = stream->writepos = 0; - stream->ops->seek(stream, stream->position, SEEK_SET, &stream->position TSRMLS_CC); + stream->ops->seek(stream, stream->position, SEEK_SET, &stream->position); } @@ -1130,7 +1112,7 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size if (towrite > stream->chunk_size) towrite = stream->chunk_size; - justwrote = stream->ops->write(stream, buf, towrite TSRMLS_CC); + justwrote = stream->ops->write(stream, buf, towrite); /* convert justwrote to an integer, since normally it is unsigned */ if ((int)justwrote > 0) { @@ -1156,7 +1138,7 @@ static size_t _php_stream_write_buffer(php_stream *stream, const char *buf, size * This may trigger a real write to the stream. * Returns the number of bytes consumed from buf by the first filter in the chain. * */ -static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, size_t count, int flags TSRMLS_DC) +static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, size_t count, int flags) { size_t consumed = 0; php_stream_bucket *bucket; @@ -1166,15 +1148,15 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si php_stream_filter *filter; if (buf) { - bucket = php_stream_bucket_new(stream, (char *)buf, count, 0, 0 TSRMLS_CC); - php_stream_bucket_append(&brig_in, bucket TSRMLS_CC); + bucket = php_stream_bucket_new(stream, (char *)buf, count, 0, 0); + php_stream_bucket_append(&brig_in, bucket); } for (filter = stream->writefilters.head; filter; filter = filter->next) { /* for our return value, we are interested in the number of bytes consumed from * the first filter in the chain */ status = filter->fops->filter(stream, filter, brig_inp, brig_outp, - filter == stream->writefilters.head ? &consumed : NULL, flags TSRMLS_CC); + filter == stream->writefilters.head ? &consumed : NULL, flags); if (status != PSFS_PASS_ON) { break; @@ -1194,14 +1176,14 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si * underlying stream */ while (brig_inp->head) { bucket = brig_inp->head; - _php_stream_write_buffer(stream, bucket->buf, bucket->buflen TSRMLS_CC); + _php_stream_write_buffer(stream, bucket->buf, bucket->buflen); /* Potential error situation - eg: no space on device. Perhaps we should keep this brigade * hanging around and try to write it later. * At the moment, we just drop it on the floor * */ - php_stream_bucket_unlink(bucket TSRMLS_CC); - php_stream_bucket_delref(bucket TSRMLS_CC); + php_stream_bucket_unlink(bucket); + php_stream_bucket_delref(bucket); } break; case PSFS_FEED_ME: @@ -1217,35 +1199,45 @@ static size_t _php_stream_write_filtered(php_stream *stream, const char *buf, si return consumed; } -PHPAPI int _php_stream_flush(php_stream *stream, int closing TSRMLS_DC) +PHPAPI int _php_stream_flush(php_stream *stream, int closing) { int ret = 0; if (stream->writefilters.head) { - _php_stream_write_filtered(stream, NULL, 0, closing ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC TSRMLS_CC); + _php_stream_write_filtered(stream, NULL, 0, closing ? PSFS_FLAG_FLUSH_CLOSE : PSFS_FLAG_FLUSH_INC ); } + stream->flags &= ~PHP_STREAM_FLAG_WAS_WRITTEN; + if (stream->ops->flush) { - ret = stream->ops->flush(stream TSRMLS_CC); + ret = stream->ops->flush(stream); } return ret; } -PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +PHPAPI size_t _php_stream_write(php_stream *stream, const char *buf, size_t count) { + size_t bytes; + if (buf == NULL || count == 0 || stream->ops->write == NULL) { return 0; } if (stream->writefilters.head) { - return _php_stream_write_filtered(stream, buf, count, PSFS_FLAG_NORMAL TSRMLS_CC); + bytes = _php_stream_write_filtered(stream, buf, count, PSFS_FLAG_NORMAL); } else { - return _php_stream_write_buffer(stream, buf, count TSRMLS_CC); + bytes = _php_stream_write_buffer(stream, buf, count); + } + + if (bytes) { + stream->flags |= PHP_STREAM_FLAG_WAS_WRITTEN; } + + return bytes; } -PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, ...) +PHPAPI size_t _php_stream_printf(php_stream *stream, const char *fmt, ...) { size_t count; char *buf; @@ -1265,12 +1257,12 @@ PHPAPI size_t _php_stream_printf(php_stream *stream TSRMLS_DC, const char *fmt, return count; } -PHPAPI off_t _php_stream_tell(php_stream *stream TSRMLS_DC) +PHPAPI zend_off_t _php_stream_tell(php_stream *stream) { return stream->position; } -PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_DC) +PHPAPI int _php_stream_seek(php_stream *stream, zend_off_t offset, int whence) { if (stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) { /* flush to commit data written to the fopencookie FILE* */ @@ -1305,7 +1297,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_ int ret; if (stream->writefilters.head) { - _php_stream_flush(stream, 0 TSRMLS_CC); + _php_stream_flush(stream, 0); } switch(whence) { @@ -1314,7 +1306,7 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_ whence = SEEK_SET; break; } - ret = stream->ops->seek(stream, offset, whence, &stream->position TSRMLS_CC); + ret = stream->ops->seek(stream, offset, whence, &stream->position); if (((stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0) || ret == 0) { if (ret == 0) { @@ -1344,23 +1336,24 @@ PHPAPI int _php_stream_seek(php_stream *stream, off_t offset, int whence TSRMLS_ return 0; } - php_error_docref(NULL TSRMLS_CC, E_WARNING, "stream does not support seeking"); + php_error_docref(NULL, E_WARNING, "stream does not support seeking"); return -1; } -PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, void *ptrparam) { int ret = PHP_STREAM_OPTION_RETURN_NOTIMPL; if (stream->ops->set_option) { - ret = stream->ops->set_option(stream, option, value, ptrparam TSRMLS_CC); + ret = stream->ops->set_option(stream, option, value, ptrparam); } if (ret == PHP_STREAM_OPTION_RETURN_NOTIMPL) { switch(option) { case PHP_STREAM_OPTION_SET_CHUNK_SIZE: - ret = stream->chunk_size; + /* XXX chunk size itself is of size_t, that might be ok or not for a particular case*/ + ret = stream->chunk_size > INT_MAX ? INT_MAX : (int)stream->chunk_size; stream->chunk_size = value; return ret; @@ -1382,16 +1375,16 @@ PHPAPI int _php_stream_set_option(php_stream *stream, int option, int value, voi return ret; } -PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize TSRMLS_DC) +PHPAPI int _php_stream_truncate_set_size(php_stream *stream, size_t newsize) { return php_stream_set_option(stream, PHP_STREAM_OPTION_TRUNCATE_API, PHP_STREAM_TRUNCATE_SET_SIZE, &newsize); } -PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC) +PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC) { size_t bcount = 0; char buf[8192]; - int b; + size_t b; if (php_stream_mmap_possible(stream)) { char *p; @@ -1422,7 +1415,7 @@ PHPAPI size_t _php_stream_passthru(php_stream * stream STREAMS_DC TSRMLS_DC) } -PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen, int persistent STREAMS_DC TSRMLS_DC) +PHPAPI zend_string *_php_stream_copy_to_mem(php_stream *src, size_t maxlen, int persistent STREAMS_DC) { size_t ret = 0; char *ptr; @@ -1430,9 +1423,10 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen int step = CHUNK_SIZE; int min_room = CHUNK_SIZE / 4; php_stream_statbuf ssbuf; + zend_string *result; if (maxlen == 0) { - return 0; + return ZSTR_EMPTY_ALLOC(); } if (maxlen == PHP_STREAM_COPY_ALL) { @@ -1440,7 +1434,8 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen } if (maxlen > 0) { - ptr = *buf = pemalloc_rel_orig(maxlen + 1, persistent); + result = zend_string_alloc(maxlen, persistent); + ptr = ZSTR_VAL(result); while ((len < maxlen) && !php_stream_eof(src)) { ret = php_stream_read(src, ptr, maxlen - len); if (!ret) { @@ -1451,11 +1446,12 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen } if (len) { *ptr = '\0'; + ZSTR_LEN(result) = len; } else { - pefree(*buf, persistent); - *buf = NULL; + zend_string_free(result); + result = NULL; } - return len; + return result; } /* avoid many reallocs by allocating a good sized chunk to begin with, if @@ -1470,30 +1466,32 @@ PHPAPI size_t _php_stream_copy_to_mem(php_stream *src, char **buf, size_t maxlen max_len = step; } - ptr = *buf = pemalloc_rel_orig(max_len, persistent); + result = zend_string_alloc(max_len, persistent); + ptr = ZSTR_VAL(result); - while((ret = php_stream_read(src, ptr, max_len - len))) { + while ((ret = php_stream_read(src, ptr, max_len - len))) { len += ret; if (len + min_room >= max_len) { - *buf = perealloc_rel_orig(*buf, max_len + step, persistent); + result = zend_string_extend(result, max_len + step, persistent); max_len += step; - ptr = *buf + len; + ptr = ZSTR_VAL(result) + len; } else { ptr += ret; } } if (len) { - *buf = perealloc_rel_orig(*buf, len + 1, persistent); - (*buf)[len] = '\0'; + result = zend_string_truncate(result, len, persistent); + ZSTR_VAL(result)[len] = '\0'; } else { - pefree(*buf, persistent); - *buf = NULL; + zend_string_free(result); + result = NULL; } - return len; + + return result; } /* Returns SUCCESS/FAILURE and sets *len to the number of bytes moved */ -PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC) +PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC) { char buf[CHUNK_SIZE]; size_t readchunk; @@ -1600,10 +1598,10 @@ PHPAPI int _php_stream_copy_to_stream_ex(php_stream *src, php_stream *dest, size * Returns 1 when source len is 0. * Deprecated in favor of php_stream_copy_to_stream_ex() */ ZEND_ATTRIBUTE_DEPRECATED -PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC TSRMLS_DC) +PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen STREAMS_DC) { size_t len; - int ret = _php_stream_copy_to_stream_ex(src, dest, maxlen, &len STREAMS_REL_CC TSRMLS_CC); + int ret = _php_stream_copy_to_stream_ex(src, dest, maxlen, &len STREAMS_REL_CC); if (ret == SUCCESS && len == 0 && maxlen != 0) { return 1; } @@ -1613,20 +1611,20 @@ PHPAPI size_t _php_stream_copy_to_stream(php_stream *src, php_stream *dest, size /* {{{ wrapper init and registration */ -static void stream_resource_regular_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void stream_resource_regular_dtor(zend_resource *rsrc) { php_stream *stream = (php_stream*)rsrc->ptr; /* set the return value for pclose */ FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); } -static void stream_resource_persistent_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void stream_resource_persistent_dtor(zend_resource *rsrc) { php_stream *stream = (php_stream*)rsrc->ptr; FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); } -void php_shutdown_stream_hashes(TSRMLS_D) +void php_shutdown_stream_hashes(void) { if (FG(stream_wrappers)) { zend_hash_destroy(FG(stream_wrappers)); @@ -1639,7 +1637,7 @@ void php_shutdown_stream_hashes(TSRMLS_D) efree(FG(stream_filters)); FG(stream_filters) = NULL; } - + if (FG(wrapper_errors)) { zend_hash_destroy(FG(wrapper_errors)); efree(FG(wrapper_errors)); @@ -1647,7 +1645,7 @@ void php_shutdown_stream_hashes(TSRMLS_D) } } -int php_init_stream_wrappers(int module_number TSRMLS_DC) +int php_init_stream_wrappers(int module_number) { le_stream = zend_register_list_destructors_ex(stream_resource_regular_dtor, NULL, "stream", module_number); le_pstream = zend_register_list_destructors_ex(NULL, stream_resource_persistent_dtor, "persistent stream", module_number); @@ -1655,26 +1653,23 @@ int php_init_stream_wrappers(int module_number TSRMLS_DC) /* Filters are cleaned up by the streams they're attached to */ le_stream_filter = zend_register_list_destructors_ex(NULL, NULL, "stream filter", module_number); - return ( - zend_hash_init(&url_stream_wrappers_hash, 0, NULL, NULL, 1) == SUCCESS - && - zend_hash_init(php_get_stream_filters_hash_global(), 0, NULL, NULL, 1) == SUCCESS - && - zend_hash_init(php_stream_xport_get_hash(), 0, NULL, NULL, 1) == SUCCESS - && - php_stream_xport_register("tcp", php_stream_generic_socket_factory TSRMLS_CC) == SUCCESS + zend_hash_init(&url_stream_wrappers_hash, 8, NULL, NULL, 1); + zend_hash_init(php_get_stream_filters_hash_global(), 8, NULL, NULL, 1); + zend_hash_init(php_stream_xport_get_hash(), 8, NULL, NULL, 1); + + return (php_stream_xport_register("tcp", php_stream_generic_socket_factory) == SUCCESS && - php_stream_xport_register("udp", php_stream_generic_socket_factory TSRMLS_CC) == SUCCESS + php_stream_xport_register("udp", php_stream_generic_socket_factory) == SUCCESS #if defined(AF_UNIX) && !(defined(PHP_WIN32) || defined(__riscos__) || defined(NETWARE)) && - php_stream_xport_register("unix", php_stream_generic_socket_factory TSRMLS_CC) == SUCCESS + php_stream_xport_register("unix", php_stream_generic_socket_factory) == SUCCESS && - php_stream_xport_register("udg", php_stream_generic_socket_factory TSRMLS_CC) == SUCCESS + php_stream_xport_register("udg", php_stream_generic_socket_factory) == SUCCESS #endif ) ? SUCCESS : FAILURE; } -int php_shutdown_stream_wrappers(int module_number TSRMLS_DC) +int php_shutdown_stream_wrappers(int module_number) { zend_hash_destroy(&url_stream_wrappers_hash); zend_hash_destroy(php_get_stream_filters_hash_global()); @@ -1702,62 +1697,60 @@ static inline int php_stream_wrapper_scheme_validate(const char *protocol, unsig } /* API for registering GLOBAL wrappers */ -PHPAPI int php_register_url_stream_wrapper(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) +PHPAPI int php_register_url_stream_wrapper(const char *protocol, php_stream_wrapper *wrapper) { - unsigned int protocol_len = strlen(protocol); + unsigned int protocol_len = (unsigned int)strlen(protocol); if (php_stream_wrapper_scheme_validate(protocol, protocol_len) == FAILURE) { return FAILURE; } - return zend_hash_add(&url_stream_wrappers_hash, protocol, protocol_len + 1, &wrapper, sizeof(wrapper), NULL); + return zend_hash_str_add_ptr(&url_stream_wrappers_hash, protocol, protocol_len, wrapper) ? SUCCESS : FAILURE; } -PHPAPI int php_unregister_url_stream_wrapper(const char *protocol TSRMLS_DC) +PHPAPI int php_unregister_url_stream_wrapper(const char *protocol) { - return zend_hash_del(&url_stream_wrappers_hash, protocol, strlen(protocol) + 1); + return zend_hash_str_del(&url_stream_wrappers_hash, protocol, strlen(protocol)); } -static void clone_wrapper_hash(TSRMLS_D) +static void clone_wrapper_hash(void) { - php_stream_wrapper *tmp; - ALLOC_HASHTABLE(FG(stream_wrappers)); zend_hash_init(FG(stream_wrappers), zend_hash_num_elements(&url_stream_wrappers_hash), NULL, NULL, 1); - zend_hash_copy(FG(stream_wrappers), &url_stream_wrappers_hash, NULL, &tmp, sizeof(tmp)); + zend_hash_copy(FG(stream_wrappers), &url_stream_wrappers_hash, NULL); } /* API for registering VOLATILE wrappers */ -PHPAPI int php_register_url_stream_wrapper_volatile(const char *protocol, php_stream_wrapper *wrapper TSRMLS_DC) +PHPAPI int php_register_url_stream_wrapper_volatile(const char *protocol, php_stream_wrapper *wrapper) { - unsigned int protocol_len = strlen(protocol); + unsigned int protocol_len = (unsigned int)strlen(protocol); if (php_stream_wrapper_scheme_validate(protocol, protocol_len) == FAILURE) { return FAILURE; } if (!FG(stream_wrappers)) { - clone_wrapper_hash(TSRMLS_C); + clone_wrapper_hash(); } - return zend_hash_add(FG(stream_wrappers), protocol, protocol_len + 1, &wrapper, sizeof(wrapper), NULL); + return zend_hash_str_add_ptr(FG(stream_wrappers), protocol, protocol_len, wrapper) ? SUCCESS : FAILURE; } -PHPAPI int php_unregister_url_stream_wrapper_volatile(const char *protocol TSRMLS_DC) +PHPAPI int php_unregister_url_stream_wrapper_volatile(const char *protocol) { if (!FG(stream_wrappers)) { - clone_wrapper_hash(TSRMLS_C); + clone_wrapper_hash(); } - return zend_hash_del(FG(stream_wrappers), protocol, strlen(protocol) + 1); + return zend_hash_str_del(FG(stream_wrappers), protocol, strlen(protocol)); } /* }}} */ /* {{{ php_stream_locate_url_wrapper */ -PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options TSRMLS_DC) +PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const char **path_for_open, int options) { HashTable *wrapper_hash = (FG(stream_wrappers) ? FG(stream_wrappers) : &url_stream_wrappers_hash); - php_stream_wrapper **wrapperpp = NULL; + php_stream_wrapper *wrapper = NULL; const char *p, *protocol = NULL; int n = 0; @@ -1779,14 +1772,14 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const /* BC with older php scripts and zlib wrapper */ protocol = "compress.zlib"; n = 13; - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Use of \"zlib:\" wrapper is deprecated; please use \"compress.zlib://\" instead"); + php_error_docref(NULL, E_WARNING, "Use of \"zlib:\" wrapper is deprecated; please use \"compress.zlib://\" instead"); } if (protocol) { char *tmp = estrndup(protocol, n); - if (FAILURE == zend_hash_find(wrapper_hash, (char*)tmp, n + 1, (void**)&wrapperpp)) { + if (NULL == (wrapper = zend_hash_str_find_ptr(wrapper_hash, (char*)tmp, n))) { php_strtolower(tmp, n); - if (FAILURE == zend_hash_find(wrapper_hash, (char*)tmp, n + 1, (void**)&wrapperpp)) { + if (NULL == (wrapper = zend_hash_str_find_ptr(wrapper_hash, (char*)tmp, n))) { char wrapper_name[32]; if (n >= sizeof(wrapper_name)) { @@ -1794,9 +1787,9 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const } PHP_STRLCPY(wrapper_name, protocol, sizeof(wrapper_name), n); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find the wrapper \"%s\" - did you forget to enable it when you configured PHP?", wrapper_name); + php_error_docref(NULL, E_WARNING, "Unable to find the wrapper \"%s\" - did you forget to enable it when you configured PHP?", wrapper_name); - wrapperpp = NULL; + wrapper = NULL; protocol = NULL; } } @@ -1820,7 +1813,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const if (localhost == 0 && path[n+3] != '\0' && path[n+3] != '/') { #endif if (options & REPORT_ERRORS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "remote host file access not supported, %s", path); + php_error_docref(NULL, E_WARNING, "remote host file access not supported, %s", path); } return NULL; } @@ -1831,7 +1824,9 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const if (localhost == 1) { (*path_for_open) += 11; } - while (*(++*path_for_open)=='/'); + while (*(++*path_for_open)=='/') { + /* intentionally empty */ + } #ifdef PHP_WIN32 if (*(*path_for_open + 1) != ':') #endif @@ -1846,18 +1841,18 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const if (FG(stream_wrappers)) { /* The file:// wrapper may have been disabled/overridden */ - if (wrapperpp) { + if (wrapper) { /* It was found so go ahead and provide it */ - return *wrapperpp; + return wrapper; } /* Check again, the original check might have not known the protocol name */ - if (zend_hash_find(wrapper_hash, "file", sizeof("file"), (void**)&wrapperpp) == SUCCESS) { - return *wrapperpp; + if ((wrapper = zend_hash_str_find_ptr(wrapper_hash, "file", sizeof("file")-1)) != NULL) { + return wrapper; } if (options & REPORT_ERRORS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "file:// wrapper is disabled in the server configuration"); + php_error_docref(NULL, E_WARNING, "file:// wrapper is disabled in the server configuration"); } return NULL; } @@ -1865,7 +1860,7 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const return plain_files_wrapper; } - if (wrapperpp && (*wrapperpp)->is_url && + if (wrapper && wrapper->is_url && (options & STREAM_DISABLE_URL_PROTECTION) == 0 && (!PG(allow_url_fopen) || (((options & STREAM_OPEN_FOR_INCLUDE) || @@ -1874,51 +1869,51 @@ PHPAPI php_stream_wrapper *php_stream_locate_url_wrapper(const char *path, const /* protocol[n] probably isn't '\0' */ char *protocol_dup = estrndup(protocol, n); if (!PG(allow_url_fopen)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_fopen=0", protocol_dup); + php_error_docref(NULL, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_fopen=0", protocol_dup); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_include=0", protocol_dup); + php_error_docref(NULL, E_WARNING, "%s:// wrapper is disabled in the server configuration by allow_url_include=0", protocol_dup); } efree(protocol_dup); } return NULL; } - return *wrapperpp; + return wrapper; } /* }}} */ /* {{{ _php_stream_mkdir */ -PHPAPI int _php_stream_mkdir(const char *path, int mode, int options, php_stream_context *context TSRMLS_DC) +PHPAPI int _php_stream_mkdir(const char *path, int mode, int options, php_stream_context *context) { php_stream_wrapper *wrapper = NULL; - wrapper = php_stream_locate_url_wrapper(path, NULL, 0 TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, NULL, 0); if (!wrapper || !wrapper->wops || !wrapper->wops->stream_mkdir) { return 0; } - return wrapper->wops->stream_mkdir(wrapper, path, mode, options, context TSRMLS_CC); + return wrapper->wops->stream_mkdir(wrapper, path, mode, options, context); } /* }}} */ /* {{{ _php_stream_rmdir */ -PHPAPI int _php_stream_rmdir(const char *path, int options, php_stream_context *context TSRMLS_DC) +PHPAPI int _php_stream_rmdir(const char *path, int options, php_stream_context *context) { php_stream_wrapper *wrapper = NULL; - wrapper = php_stream_locate_url_wrapper(path, NULL, 0 TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, NULL, 0); if (!wrapper || !wrapper->wops || !wrapper->wops->stream_rmdir) { return 0; } - return wrapper->wops->stream_rmdir(wrapper, path, options, context TSRMLS_CC); + return wrapper->wops->stream_rmdir(wrapper, path, options, context); } /* }}} */ /* {{{ _php_stream_stat_path */ -PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) +PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf *ssb, php_stream_context *context) { php_stream_wrapper *wrapper = NULL; const char *path_to_open = path; @@ -1939,9 +1934,9 @@ PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf } } - wrapper = php_stream_locate_url_wrapper(path, &path_to_open, 0 TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, 0); if (wrapper && wrapper->wops->url_stat) { - ret = wrapper->wops->url_stat(wrapper, path_to_open, flags, ssb, context TSRMLS_CC); + ret = wrapper->wops->url_stat(wrapper, path_to_open, flags, ssb, context); if (ret == 0) { if (!(flags & PHP_STREAM_URL_STAT_NOCACHE)) { /* Drop into cache */ @@ -1968,7 +1963,7 @@ PHPAPI int _php_stream_stat_path(const char *path, int flags, php_stream_statbuf /* {{{ php_stream_opendir */ PHPAPI php_stream *_php_stream_opendir(const char *path, int options, - php_stream_context *context STREAMS_DC TSRMLS_DC) + php_stream_context *context STREAMS_DC) { php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; @@ -1980,31 +1975,31 @@ PHPAPI php_stream *_php_stream_opendir(const char *path, int options, path_to_open = path; - wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options); if (wrapper && wrapper->wops->dir_opener) { stream = wrapper->wops->dir_opener(wrapper, path_to_open, "r", options ^ REPORT_ERRORS, NULL, - context STREAMS_REL_CC TSRMLS_CC); + context STREAMS_REL_CC); if (stream) { stream->wrapper = wrapper; stream->flags |= PHP_STREAM_FLAG_NO_BUFFER | PHP_STREAM_FLAG_IS_DIR; } } else if (wrapper) { - php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC, "not implemented"); + php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS, "not implemented"); } if (stream == NULL && (options & REPORT_ERRORS)) { - php_stream_display_wrapper_errors(wrapper, path, "failed to open dir" TSRMLS_CC); + php_stream_display_wrapper_errors(wrapper, path, "failed to open dir"); } - php_stream_tidy_wrapper_error_log(wrapper TSRMLS_CC); + php_stream_tidy_wrapper_error_log(wrapper); return stream; } /* }}} */ /* {{{ _php_stream_readdir */ -PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent TSRMLS_DC) +PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_dirent *ent) { if (sizeof(php_stream_dirent) == php_stream_read(dirstream, (char*)ent, sizeof(php_stream_dirent))) { @@ -2017,13 +2012,13 @@ PHPAPI php_stream_dirent *_php_stream_readdir(php_stream *dirstream, php_stream_ /* {{{ php_stream_open_wrapper_ex */ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mode, int options, - char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) + zend_string **opened_path, php_stream_context *context STREAMS_DC) { php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; const char *path_to_open; int persistent = options & STREAM_OPEN_PERSISTENT; - char *resolved_path = NULL; + zend_string *resolved_path = NULL; char *copy_of_path = NULL; if (opened_path) { @@ -2031,14 +2026,14 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } if (!path || !*path) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Filename cannot be empty"); + php_error_docref(NULL, E_WARNING, "Filename cannot be empty"); return NULL; } if (options & USE_PATH) { - resolved_path = zend_resolve_path(path, strlen(path) TSRMLS_CC); + resolved_path = zend_resolve_path(path, (int)strlen(path)); if (resolved_path) { - path = resolved_path; + path = ZSTR_VAL(resolved_path); /* we've found this file, don't re-check include_path or run realpath */ options |= STREAM_ASSUME_REALPATH; options &= ~USE_PATH; @@ -2047,29 +2042,29 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod path_to_open = path; - wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options TSRMLS_CC); + wrapper = php_stream_locate_url_wrapper(path, &path_to_open, options); if (options & STREAM_USE_URL && (!wrapper || !wrapper->is_url)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "This function may only be used against URLs"); + php_error_docref(NULL, E_WARNING, "This function may only be used against URLs"); if (resolved_path) { - efree(resolved_path); + zend_string_release(resolved_path); } return NULL; } if (wrapper) { if (!wrapper->wops->stream_opener) { - php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC, + php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS, "wrapper does not support stream open"); } else { stream = wrapper->wops->stream_opener(wrapper, path_to_open, mode, options ^ REPORT_ERRORS, - opened_path, context STREAMS_REL_CC TSRMLS_CC); + opened_path, context STREAMS_REL_CC); } /* if the caller asked for a persistent stream but the wrapper did not * return one, force an error here */ if (stream && (options & STREAM_OPEN_PERSISTENT) && !stream->is_persistent) { - php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS TSRMLS_CC, + php_stream_wrapper_log_error(wrapper, options ^ REPORT_ERRORS, "wrapper does not support persistent streams"); php_stream_close(stream); stream = NULL; @@ -2104,7 +2099,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod ? PHP_STREAM_PREFER_STDIO : PHP_STREAM_NO_PREFERENCE)) { case PHP_STREAM_UNCHANGED: if (resolved_path) { - efree(resolved_path); + zend_string_release(resolved_path); } return stream; case PHP_STREAM_RELEASED: @@ -2113,7 +2108,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } newstream->orig_path = pestrdup(path, persistent); if (resolved_path) { - efree(resolved_path); + zend_string_release(resolved_path); } return newstream; default: @@ -2122,7 +2117,7 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod if (options & REPORT_ERRORS) { char *tmp = estrdup(path); php_strip_url_passwd(tmp); - php_error_docref1(NULL TSRMLS_CC, tmp, E_WARNING, "could not make seekable - %s", + php_error_docref1(NULL, tmp, E_WARNING, "could not make seekable - %s", tmp); efree(tmp); @@ -2132,29 +2127,29 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod } if (stream && stream->ops->seek && (stream->flags & PHP_STREAM_FLAG_NO_SEEK) == 0 && strchr(mode, 'a') && stream->position == 0) { - off_t newpos = 0; + zend_off_t newpos = 0; /* if opened for append, we need to revise our idea of the initial file position */ - if (0 == stream->ops->seek(stream, 0, SEEK_CUR, &newpos TSRMLS_CC)) { + if (0 == stream->ops->seek(stream, 0, SEEK_CUR, &newpos)) { stream->position = newpos; } } if (stream == NULL && (options & REPORT_ERRORS)) { - php_stream_display_wrapper_errors(wrapper, path, "failed to open stream" TSRMLS_CC); + php_stream_display_wrapper_errors(wrapper, path, "failed to open stream"); if (opened_path && *opened_path) { - efree(*opened_path); + zend_string_release(*opened_path); *opened_path = NULL; } } - php_stream_tidy_wrapper_error_log(wrapper TSRMLS_CC); + php_stream_tidy_wrapper_error_log(wrapper); #if ZEND_DEBUG if (stream == NULL && copy_of_path != NULL) { pefree(copy_of_path, persistent); } #endif if (resolved_path) { - efree(resolved_path); + zend_string_release(resolved_path); } return stream; } @@ -2163,33 +2158,33 @@ PHPAPI php_stream *_php_stream_open_wrapper_ex(const char *path, const char *mod /* {{{ context API */ PHPAPI php_stream_context *php_stream_context_set(php_stream *stream, php_stream_context *context) { - php_stream_context *oldcontext = stream->context; - TSRMLS_FETCH(); - - stream->context = context; + php_stream_context *oldcontext = PHP_STREAM_CONTEXT(stream); if (context) { - zend_list_addref(context->rsrc_id); + stream->ctx = context->res; + GC_REFCOUNT(context->res)++; + } else { + stream->ctx = NULL; } if (oldcontext) { - zend_list_delete(oldcontext->rsrc_id); + zend_list_delete(oldcontext->res); } return oldcontext; } PHPAPI void php_stream_notification_notify(php_stream_context *context, int notifycode, int severity, - char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr TSRMLS_DC) + char *xmsg, int xcode, size_t bytes_sofar, size_t bytes_max, void * ptr) { if (context && context->notifier) - context->notifier->func(context, notifycode, severity, xmsg, xcode, bytes_sofar, bytes_max, ptr TSRMLS_CC); + context->notifier->func(context, notifycode, severity, xmsg, xcode, bytes_sofar, bytes_max, ptr); } PHPAPI void php_stream_context_free(php_stream_context *context) { - if (context->options) { + if (Z_TYPE(context->options) != IS_UNDEF) { zval_ptr_dtor(&context->options); - context->options = NULL; + ZVAL_UNDEF(&context->options); } if (context->notifier) { php_stream_notification_free(context->notifier); @@ -2198,16 +2193,15 @@ PHPAPI void php_stream_context_free(php_stream_context *context) efree(context); } -PHPAPI php_stream_context *php_stream_context_alloc(TSRMLS_D) +PHPAPI php_stream_context *php_stream_context_alloc(void) { php_stream_context *context; context = ecalloc(1, sizeof(php_stream_context)); context->notifier = NULL; - MAKE_STD_ZVAL(context->options); - array_init(context->options); + array_init(&context->options); - context->rsrc_id = ZEND_REGISTER_RESOURCE(NULL, context, php_le_stream_context(TSRMLS_C)); + context->res = zend_register_resource(context, php_le_stream_context()); return context; } @@ -2224,65 +2218,61 @@ PHPAPI void php_stream_notification_free(php_stream_notifier *notifier) efree(notifier); } -PHPAPI int php_stream_context_get_option(php_stream_context *context, - const char *wrappername, const char *optionname, zval ***optionvalue) +PHPAPI zval *php_stream_context_get_option(php_stream_context *context, + const char *wrappername, const char *optionname) { - zval **wrapperhash; + zval *wrapperhash; - if (FAILURE == zend_hash_find(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&wrapperhash)) { - return FAILURE; + if (NULL == (wrapperhash = zend_hash_str_find(Z_ARRVAL(context->options), wrappername, strlen(wrappername)))) { + return NULL; } - return zend_hash_find(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)optionvalue); + return zend_hash_str_find(Z_ARRVAL_P(wrapperhash), optionname, strlen(optionname)); } PHPAPI int php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue) { - zval **wrapperhash; - zval *category, *copied_val; + zval *wrapperhash; + zval category, copied_val; - ALLOC_INIT_ZVAL(copied_val); - *copied_val = *optionvalue; - zval_copy_ctor(copied_val); - INIT_PZVAL(copied_val); + ZVAL_DUP(&copied_val, optionvalue); - if (FAILURE == zend_hash_find(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&wrapperhash)) { - MAKE_STD_ZVAL(category); - array_init(category); - if (FAILURE == zend_hash_update(Z_ARRVAL_P(context->options), (char*)wrappername, strlen(wrappername)+1, (void**)&category, sizeof(zval *), NULL)) { + if (NULL == (wrapperhash = zend_hash_str_find(Z_ARRVAL(context->options), wrappername, strlen(wrappername)))) { + array_init(&category); + if (NULL == zend_hash_str_update(Z_ARRVAL(context->options), (char*)wrappername, strlen(wrappername), &category)) { return FAILURE; } wrapperhash = &category; } - return zend_hash_update(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)&copied_val, sizeof(zval *), NULL); + return zend_hash_str_update(Z_ARRVAL_P(wrapperhash), optionname, strlen(optionname), &copied_val) ? SUCCESS : FAILURE; } /* }}} */ /* {{{ php_stream_dirent_alphasort */ -PHPAPI int php_stream_dirent_alphasort(const char **a, const char **b) +PHPAPI int php_stream_dirent_alphasort(const zend_string **a, const zend_string **b) { - return strcoll(*a, *b); + return strcoll(ZSTR_VAL(*a), ZSTR_VAL(*b)); } /* }}} */ /* {{{ php_stream_dirent_alphasortr */ -PHPAPI int php_stream_dirent_alphasortr(const char **a, const char **b) +PHPAPI int php_stream_dirent_alphasortr(const zend_string **a, const zend_string **b) { - return strcoll(*b, *a); + return strcoll(ZSTR_VAL(*b), ZSTR_VAL(*a)); } /* }}} */ /* {{{ php_stream_scandir */ -PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags, php_stream_context *context, - int (*compare) (const char **a, const char **b) TSRMLS_DC) +PHPAPI int _php_stream_scandir(const char *dirname, zend_string **namelist[], int flags, php_stream_context *context, + int (*compare) (const zend_string **a, const zend_string **b)) { php_stream *stream; php_stream_dirent sdp; - char **vector = NULL; + zend_string **vector = NULL; unsigned int vector_size = 0; unsigned int nfiles = 0; @@ -2308,10 +2298,10 @@ PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags } vector_size *= 2; } - vector = (char **) safe_erealloc(vector, vector_size, sizeof(char *), 0); + vector = (zend_string **) safe_erealloc(vector, vector_size, sizeof(char *), 0); } - vector[nfiles] = estrdup(sdp.d_name); + vector[nfiles] = zend_string_init(sdp.d_name, strlen(sdp.d_name), 0); nfiles++; if(vector_size < 10 || nfiles == 0) { @@ -2326,7 +2316,7 @@ PHPAPI int _php_stream_scandir(const char *dirname, char **namelist[], int flags *namelist = vector; if (nfiles > 0 && compare) { - qsort(*namelist, nfiles, sizeof(char *), (int(*)(const void *, const void *))compare); + qsort(*namelist, nfiles, sizeof(zend_string *), (int(*)(const void *, const void *))compare); } return nfiles; } diff --git a/main/streams/transports.c b/main/streams/transports.c index c125f56a6a..eab6c42df7 100644 --- a/main/streams/transports.c +++ b/main/streams/transports.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -29,50 +29,50 @@ PHPAPI HashTable *php_stream_xport_get_hash(void) return &xport_hash; } -PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory TSRMLS_DC) +PHPAPI int php_stream_xport_register(const char *protocol, php_stream_transport_factory factory) { - return zend_hash_update(&xport_hash, protocol, strlen(protocol) + 1, &factory, sizeof(factory), NULL); + return zend_hash_str_update_ptr(&xport_hash, protocol, strlen(protocol), factory) ? SUCCESS : FAILURE; } -PHPAPI int php_stream_xport_unregister(const char *protocol TSRMLS_DC) +PHPAPI int php_stream_xport_unregister(const char *protocol) { - return zend_hash_del(&xport_hash, protocol, strlen(protocol) + 1); + return zend_hash_str_del(&xport_hash, protocol, strlen(protocol)); } #define ERR_REPORT(out_err, fmt, arg) \ - if (out_err) { spprintf(out_err, 0, fmt, arg); } \ - else { php_error_docref(NULL TSRMLS_CC, E_WARNING, fmt, arg); } + if (out_err) { *out_err = strpprintf(0, fmt, arg); } \ + else { php_error_docref(NULL, E_WARNING, fmt, arg); } #define ERR_RETURN(out_err, local_err, fmt) \ if (out_err) { *out_err = local_err; } \ - else { php_error_docref(NULL TSRMLS_CC, E_WARNING, fmt, local_err ? local_err : "Unspecified error"); \ - if (local_err) { efree(local_err); local_err = NULL; } \ + else { php_error_docref(NULL, E_WARNING, fmt, local_err ? ZSTR_VAL(local_err) : "Unspecified error"); \ + if (local_err) { zend_string_release(local_err); local_err = NULL; } \ } - + PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, int options, int flags, const char *persistent_id, struct timeval *timeout, php_stream_context *context, - char **error_string, + zend_string **error_string, int *error_code - STREAMS_DC TSRMLS_DC) + STREAMS_DC) { php_stream *stream = NULL; - php_stream_transport_factory *factory = NULL; + php_stream_transport_factory factory = NULL; const char *p, *protocol = NULL; int n = 0, failed = 0; - char *error_text = NULL; + zend_string *error_text = NULL; struct timeval default_timeout = { 0, 0 }; - + default_timeout.tv_sec = FG(default_socket_timeout); if (timeout == NULL) { timeout = &default_timeout; } - + /* check for a cached persistent socket */ if (persistent_id) { - switch(php_stream_from_persistent_id(persistent_id, &stream TSRMLS_CC)) { + switch(php_stream_from_persistent_id(persistent_id, &stream)) { case PHP_STREAM_PERSISTENT_SUCCESS: /* use a 0 second timeout when checking if the socket * has already died */ @@ -107,13 +107,13 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in if (protocol) { char *tmp = estrndup(protocol, n); - if (FAILURE == zend_hash_find(&xport_hash, (char*)tmp, n + 1, (void**)&factory)) { + if (NULL == (factory = zend_hash_str_find_ptr(&xport_hash, tmp, n))) { char wrapper_name[32]; if (n >= sizeof(wrapper_name)) n = sizeof(wrapper_name) - 1; PHP_STRLCPY(wrapper_name, protocol, sizeof(wrapper_name), n); - + ERR_REPORT(error_string, "Unable to find the socket transport \"%s\" - did you forget to enable it when you configured PHP?", wrapper_name); @@ -125,13 +125,13 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in if (factory == NULL) { /* should never happen */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find a factory !?"); + php_error_docref(NULL, E_WARNING, "Could not find a factory !?"); return NULL; } - stream = (*factory)(protocol, n, + stream = (factory)(protocol, n, (char*)name, namelen, persistent_id, options, flags, timeout, - context STREAMS_REL_CC TSRMLS_CC); + context STREAMS_REL_CC); if (stream) { php_stream_context_set(stream, context); @@ -142,7 +142,7 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in if (flags & (STREAM_XPORT_CONNECT|STREAM_XPORT_CONNECT_ASYNC)) { if (-1 == php_stream_xport_connect(stream, name, namelen, flags & STREAM_XPORT_CONNECT_ASYNC ? 1 : 0, - timeout, &error_text, error_code TSRMLS_CC)) { + timeout, &error_text, error_code)) { ERR_RETURN(error_string, error_text, "connect() failed: %s"); @@ -153,24 +153,24 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in } else { /* server */ if (flags & STREAM_XPORT_BIND) { - if (0 != php_stream_xport_bind(stream, name, namelen, &error_text TSRMLS_CC)) { + if (0 != php_stream_xport_bind(stream, name, namelen, &error_text)) { ERR_RETURN(error_string, error_text, "bind() failed: %s"); failed = 1; } else if (flags & STREAM_XPORT_LISTEN) { - zval **zbacklog = NULL; + zval *zbacklog = NULL; int backlog = 32; - - if (stream->context && php_stream_context_get_option(stream->context, "socket", "backlog", &zbacklog) == SUCCESS) { - zval *ztmp = *zbacklog; - - convert_to_long_ex(&ztmp); + + if (PHP_STREAM_CONTEXT(stream) && (zbacklog = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "backlog")) != NULL) { + zval *ztmp = zbacklog; + + convert_to_long_ex(ztmp); backlog = Z_LVAL_P(ztmp); - if (ztmp != *zbacklog) { - zval_ptr_dtor(&ztmp); + if (ztmp != zbacklog) { + zval_ptr_dtor(ztmp); } } - - if (0 != php_stream_xport_listen(stream, backlog, &error_text TSRMLS_CC)) { + + if (0 != php_stream_xport_listen(stream, backlog, &error_text)) { ERR_RETURN(error_string, error_text, "listen() failed: %s"); failed = 1; } @@ -195,12 +195,12 @@ PHPAPI php_stream *_php_stream_xport_create(const char *name, size_t namelen, in /* Bind the stream to a local address */ PHPAPI int php_stream_xport_bind(php_stream *stream, const char *name, size_t namelen, - char **error_text - TSRMLS_DC) + zend_string **error_text + ) { php_stream_xport_param param; int ret; - + memset(¶m, 0, sizeof(param)); param.op = STREAM_XPORT_OP_BIND; param.inputs.name = (char*)name; @@ -225,13 +225,13 @@ PHPAPI int php_stream_xport_connect(php_stream *stream, const char *name, size_t namelen, int asynchronous, struct timeval *timeout, - char **error_text, + zend_string **error_text, int *error_code - TSRMLS_DC) + ) { php_stream_xport_param param; int ret; - + memset(¶m, 0, sizeof(param)); param.op = asynchronous ? STREAM_XPORT_OP_CONNECT_ASYNC: STREAM_XPORT_OP_CONNECT; param.inputs.name = (char*)name; @@ -239,7 +239,7 @@ PHPAPI int php_stream_xport_connect(php_stream *stream, param.inputs.timeout = timeout; param.want_errortext = error_text ? 1 : 0; - + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_XPORT_API, 0, ¶m); if (ret == PHP_STREAM_OPTION_RETURN_OK) { @@ -257,16 +257,16 @@ PHPAPI int php_stream_xport_connect(php_stream *stream, } /* Prepare to listen */ -PHPAPI int php_stream_xport_listen(php_stream *stream, int backlog, char **error_text TSRMLS_DC) +PHPAPI int php_stream_xport_listen(php_stream *stream, int backlog, zend_string **error_text) { php_stream_xport_param param; int ret; - + memset(¶m, 0, sizeof(param)); param.op = STREAM_XPORT_OP_LISTEN; param.inputs.backlog = backlog; param.want_errortext = error_text ? 1 : 0; - + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_XPORT_API, 0, ¶m); if (ret == PHP_STREAM_OPTION_RETURN_OK) { @@ -282,11 +282,11 @@ PHPAPI int php_stream_xport_listen(php_stream *stream, int backlog, char **error /* Get the next client and their address (as a string) */ PHPAPI int php_stream_xport_accept(php_stream *stream, php_stream **client, - char **textaddr, int *textaddrlen, + zend_string **textaddr, void **addr, socklen_t *addrlen, struct timeval *timeout, - char **error_text - TSRMLS_DC) + zend_string **error_text + ) { php_stream_xport_param param; int ret; @@ -298,7 +298,7 @@ PHPAPI int php_stream_xport_accept(php_stream *stream, php_stream **client, param.want_addr = addr ? 1 : 0; param.want_textaddr = textaddr ? 1 : 0; param.want_errortext = error_text ? 1 : 0; - + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_XPORT_API, 0, ¶m); if (ret == PHP_STREAM_OPTION_RETURN_OK) { @@ -309,7 +309,6 @@ PHPAPI int php_stream_xport_accept(php_stream *stream, php_stream **client, } if (textaddr) { *textaddr = param.outputs.textaddr; - *textaddrlen = param.outputs.textaddrlen; } if (error_text) { *error_text = param.outputs.error_text; @@ -321,9 +320,9 @@ PHPAPI int php_stream_xport_accept(php_stream *stream, php_stream **client, } PHPAPI int php_stream_xport_get_name(php_stream *stream, int want_peer, - char **textaddr, int *textaddrlen, + zend_string **textaddr, void **addr, socklen_t *addrlen - TSRMLS_DC) + ) { php_stream_xport_param param; int ret; @@ -333,7 +332,7 @@ PHPAPI int php_stream_xport_get_name(php_stream *stream, int want_peer, param.op = want_peer ? STREAM_XPORT_OP_GET_PEER_NAME : STREAM_XPORT_OP_GET_NAME; param.want_addr = addr ? 1 : 0; param.want_textaddr = textaddr ? 1 : 0; - + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_XPORT_API, 0, ¶m); if (ret == PHP_STREAM_OPTION_RETURN_OK) { @@ -343,7 +342,6 @@ PHPAPI int php_stream_xport_get_name(php_stream *stream, int want_peer, } if (textaddr) { *textaddr = param.outputs.textaddr; - *textaddrlen = param.outputs.textaddrlen; } return param.outputs.returncode; @@ -351,7 +349,7 @@ PHPAPI int php_stream_xport_get_name(php_stream *stream, int want_peer, return ret; } -PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream TSRMLS_DC) +PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream) { php_stream_xport_crypto_param param; int ret; @@ -360,19 +358,19 @@ PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_cr param.op = STREAM_XPORT_CRYPTO_OP_SETUP; param.inputs.method = crypto_method; param.inputs.session = session_stream; - + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_CRYPTO_API, 0, ¶m); if (ret == PHP_STREAM_OPTION_RETURN_OK) { return param.outputs.returncode; } - php_error_docref("streams.crypto" TSRMLS_CC, E_WARNING, "this stream does not support SSL/crypto"); - + php_error_docref("streams.crypto", E_WARNING, "this stream does not support SSL/crypto"); + return ret; } -PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate TSRMLS_DC) +PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate) { php_stream_xport_crypto_param param; int ret; @@ -380,23 +378,23 @@ PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate TSRML memset(¶m, 0, sizeof(param)); param.op = STREAM_XPORT_CRYPTO_OP_ENABLE; param.inputs.activate = activate; - + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_CRYPTO_API, 0, ¶m); if (ret == PHP_STREAM_OPTION_RETURN_OK) { return param.outputs.returncode; } - php_error_docref("streams.crypto" TSRMLS_CC, E_WARNING, "this stream does not support SSL/crypto"); - + php_error_docref("streams.crypto", E_WARNING, "this stream does not support SSL/crypto"); + return ret; } /* Similar to recv() system call; read data from the stream, optionally * peeking, optionally retrieving OOB data */ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t buflen, - long flags, void **addr, socklen_t *addrlen, char **textaddr, int *textaddrlen - TSRMLS_DC) + int flags, void **addr, socklen_t *addrlen, zend_string **textaddr + ) { php_stream_xport_param param; int ret = 0; @@ -409,10 +407,10 @@ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t bufle } if (stream->readfilters.head) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot peek or fetch OOB data from a filtered stream"); + php_error_docref(NULL, E_WARNING, "cannot peek or fetch OOB data from a filtered stream"); return -1; } - + oob = (flags & STREAM_OOB) == STREAM_OOB; if (!oob && addr == NULL) { @@ -436,7 +434,7 @@ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t bufle #endif /* otherwise, we are going to bypass the buffer */ - + memset(¶m, 0, sizeof(param)); param.op = STREAM_XPORT_OP_RECV; @@ -445,7 +443,7 @@ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t bufle param.inputs.buf = buf; param.inputs.buflen = buflen; param.inputs.flags = flags; - + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_XPORT_API, 0, ¶m); if (ret == PHP_STREAM_OPTION_RETURN_OK) { @@ -455,7 +453,6 @@ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t bufle } if (textaddr) { *textaddr = param.outputs.textaddr; - *textaddrlen = param.outputs.textaddrlen; } return recvd_len + param.outputs.returncode; } @@ -465,7 +462,7 @@ PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t bufle /* Similar to send() system call; send data to the stream, optionally * sending it as OOB data */ PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t buflen, - long flags, void *addr, socklen_t addrlen TSRMLS_DC) + int flags, void *addr, socklen_t addrlen) { php_stream_xport_param param; int ret = 0; @@ -476,14 +473,14 @@ PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t b return php_stream_write(stream, buf, buflen); } #endif - + oob = (flags & STREAM_OOB) == STREAM_OOB; if ((oob || addr) && stream->writefilters.head) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot write OOB data, or data to a targeted address on a filtered stream"); + php_error_docref(NULL, E_WARNING, "cannot write OOB data, or data to a targeted address on a filtered stream"); return -1; } - + memset(¶m, 0, sizeof(param)); param.op = STREAM_XPORT_OP_SEND; @@ -493,7 +490,7 @@ PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t b param.inputs.flags = flags; param.inputs.addr = addr; param.inputs.addrlen = addrlen; - + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_XPORT_API, 0, ¶m); if (ret == PHP_STREAM_OPTION_RETURN_OK) { @@ -504,7 +501,7 @@ PHPAPI int php_stream_xport_sendto(php_stream *stream, const char *buf, size_t b /* Similar to shutdown() system call; shut down part of a full-duplex * connection */ -PHPAPI int php_stream_xport_shutdown(php_stream *stream, stream_shutdown_t how TSRMLS_DC) +PHPAPI int php_stream_xport_shutdown(php_stream *stream, stream_shutdown_t how) { php_stream_xport_param param; int ret = 0; @@ -513,7 +510,7 @@ PHPAPI int php_stream_xport_shutdown(php_stream *stream, stream_shutdown_t how T param.op = STREAM_XPORT_OP_SHUTDOWN; param.how = how; - + ret = php_stream_set_option(stream, PHP_STREAM_OPTION_XPORT_API, 0, ¶m); if (ret == PHP_STREAM_OPTION_RETURN_OK) { diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 38a5dd3107..9bbf5b0c4e 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -45,15 +45,15 @@ struct php_user_stream_wrapper { php_stream_wrapper wrapper; }; -static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); -static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC); -static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); -static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context TSRMLS_DC); -static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context TSRMLS_DC); -static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC); -static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, int option, void *value, php_stream_context *context TSRMLS_DC); +static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *filename, const char *mode, int options, zend_string **opened_path, php_stream_context *context STREAMS_DC); +static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context); +static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context); +static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, int options, php_stream_context *context); +static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int mode, int options, php_stream_context *context); +static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context); +static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, int option, void *value, php_stream_context *context); static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char *filename, const char *mode, - int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC); + int options, zend_string **opened_path, php_stream_context *context STREAMS_DC); static php_stream_wrapper_ops user_stream_wops = { user_wrapper_opener, @@ -70,7 +70,7 @@ static php_stream_wrapper_ops user_stream_wops = { }; -static void stream_wrapper_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void stream_wrapper_dtor(zend_resource *rsrc) { struct php_user_stream_wrapper * uwrap = (struct php_user_stream_wrapper*)rsrc->ptr; @@ -120,7 +120,7 @@ PHP_MINIT_FUNCTION(user_streams) struct _php_userstream_data { struct php_user_stream_wrapper * wrapper; - zval * object; + zval object; }; typedef struct _php_userstream_data php_userstream_data_t; @@ -281,18 +281,14 @@ typedef struct _php_userstream_data php_userstream_data_t; }}} **/ -static zval *user_stream_create_object(struct php_user_stream_wrapper *uwrap, php_stream_context *context TSRMLS_DC) +static void user_stream_create_object(struct php_user_stream_wrapper *uwrap, php_stream_context *context, zval *object) { - zval *object; /* create an instance of our class */ - ALLOC_ZVAL(object); object_init_ex(object, uwrap->ce); - Z_SET_REFCOUNT_P(object, 1); - Z_SET_ISREF_P(object); if (context) { - add_property_resource(object, "context", context->rsrc_id); - zend_list_addref(context->rsrc_id); + add_property_resource(object, "context", context->res); + GC_REFCOUNT(context->res)++; } else { add_property_null(object, "context"); } @@ -300,14 +296,14 @@ static zval *user_stream_create_object(struct php_user_stream_wrapper *uwrap, ph if (uwrap->ce->constructor) { zend_fcall_info fci; zend_fcall_info_cache fcc; - zval *retval_ptr; + zval retval; fci.size = sizeof(fci); fci.function_table = &uwrap->ce->function_table; - fci.function_name = NULL; + ZVAL_UNDEF(&fci.function_name); fci.symbol_table = NULL; - fci.object_ptr = object; - fci.retval_ptr_ptr = &retval_ptr; + fci.object = Z_OBJ_P(object); + fci.retval = &retval; fci.param_count = 0; fci.params = NULL; fci.no_separation = 1; @@ -316,36 +312,32 @@ static zval *user_stream_create_object(struct php_user_stream_wrapper *uwrap, ph fcc.function_handler = uwrap->ce->constructor; fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(object); - fcc.object_ptr = object; + fcc.object = Z_OBJ_P(object); - if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not execute %s::%s()", uwrap->ce->name, uwrap->ce->constructor->common.function_name); + if (zend_call_function(&fci, &fcc) == FAILURE) { + php_error_docref(NULL, E_WARNING, "Could not execute %s::%s()", ZSTR_VAL(uwrap->ce->name), ZSTR_VAL(uwrap->ce->constructor->common.function_name)); zval_dtor(object); - FREE_ZVAL(object); - return NULL; + ZVAL_UNDEF(object); } else { - if (retval_ptr) { - zval_ptr_dtor(&retval_ptr); - } + zval_ptr_dtor(&retval); } } - return object; } static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char *filename, const char *mode, - int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) + int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; php_userstream_data_t *us; - zval *zfilename, *zmode, *zopened, *zoptions, *zretval = NULL, *zfuncname; - zval **args[4]; + zval zretval, zfuncname; + zval args[4]; int call_result; php_stream *stream = NULL; zend_bool old_in_user_include; /* Try to catch bad usage without preventing flexibility */ if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "infinite recursion prevented"); + php_stream_wrapper_log_error(wrapper, options, "infinite recursion prevented"); return NULL; } FG(user_stream_current_filename) = filename; @@ -364,8 +356,8 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * us = emalloc(sizeof(*us)); us->wrapper = uwrap; - us->object = user_stream_create_object(uwrap, context TSRMLS_CC); - if(us->object == NULL) { + user_stream_create_object(uwrap, context, &us->object); + if (Z_TYPE(us->object) == IS_UNDEF) { FG(user_stream_current_filename) = NULL; PG(in_user_include) = old_in_user_include; efree(us); @@ -373,64 +365,48 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * } /* call it's stream_open method - set up params first */ - MAKE_STD_ZVAL(zfilename); - ZVAL_STRING(zfilename, filename, 1); - args[0] = &zfilename; - - MAKE_STD_ZVAL(zmode); - ZVAL_STRING(zmode, mode, 1); - args[1] = &zmode; - - MAKE_STD_ZVAL(zoptions); - ZVAL_LONG(zoptions, options); - args[2] = &zoptions; + ZVAL_STRING(&args[0], filename); + ZVAL_STRING(&args[1], mode); + ZVAL_LONG(&args[2], options); + ZVAL_NEW_REF(&args[3], &EG(uninitialized_zval)); - MAKE_STD_ZVAL(zopened); - Z_SET_REFCOUNT_P(zopened, 1); - Z_SET_ISREF_P(zopened); - ZVAL_NULL(zopened); - args[3] = &zopened; - - MAKE_STD_ZVAL(zfuncname); - ZVAL_STRING(zfuncname, USERSTREAM_OPEN, 1); + ZVAL_STRING(&zfuncname, USERSTREAM_OPEN); call_result = call_user_function_ex(NULL, - &us->object, - zfuncname, + Z_ISUNDEF(us->object)? NULL : &us->object, + &zfuncname, &zretval, 4, args, - 0, NULL TSRMLS_CC); + 0, NULL ); - if (call_result == SUCCESS && zretval != NULL && zval_is_true(zretval)) { + if (call_result == SUCCESS && Z_TYPE(zretval) != IS_UNDEF && zval_is_true(&zretval)) { /* the stream is now open! */ stream = php_stream_alloc_rel(&php_stream_userspace_ops, us, 0, mode); /* if the opened path is set, copy it out */ - if (Z_TYPE_P(zopened) == IS_STRING && opened_path) { - *opened_path = estrndup(Z_STRVAL_P(zopened), Z_STRLEN_P(zopened)); + if (Z_ISREF(args[3]) && Z_TYPE_P(Z_REFVAL(args[3])) == IS_STRING && opened_path) { + *opened_path = zend_string_copy(Z_STR_P(Z_REFVAL(args[3]))); } /* set wrapper data to be a reference to our object */ - stream->wrapperdata = us->object; - zval_add_ref(&stream->wrapperdata); + ZVAL_COPY(&stream->wrapperdata, &us->object); } else { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "\"%s::" USERSTREAM_OPEN "\" call failed", + php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_OPEN "\" call failed", us->wrapper->classname); } /* destroy everything else */ if (stream == NULL) { zval_ptr_dtor(&us->object); + ZVAL_UNDEF(&us->object); efree(us); } - if (zretval) - zval_ptr_dtor(&zretval); - + zval_ptr_dtor(&zretval); zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&zopened); - zval_ptr_dtor(&zoptions); - zval_ptr_dtor(&zmode); - zval_ptr_dtor(&zfilename); + zval_ptr_dtor(&args[3]); + zval_ptr_dtor(&args[2]); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[0]); FG(user_stream_current_filename) = NULL; @@ -439,18 +415,18 @@ static php_stream *user_wrapper_opener(php_stream_wrapper *wrapper, const char * } static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char *filename, const char *mode, - int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) + int options, zend_string **opened_path, php_stream_context *context STREAMS_DC) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; php_userstream_data_t *us; - zval *zfilename, *zoptions, *zretval = NULL, *zfuncname; - zval **args[2]; + zval zretval, zfuncname; + zval args[2]; int call_result; php_stream *stream = NULL; /* Try to catch bad usage without preventing flexibility */ if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "infinite recursion prevented"); + php_stream_wrapper_log_error(wrapper, options, "infinite recursion prevented"); return NULL; } FG(user_stream_current_filename) = filename; @@ -458,55 +434,48 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char us = emalloc(sizeof(*us)); us->wrapper = uwrap; - us->object = user_stream_create_object(uwrap, context TSRMLS_CC); - if(us->object == NULL) { + user_stream_create_object(uwrap, context, &us->object); + if (Z_TYPE(us->object) == IS_UNDEF) { FG(user_stream_current_filename) = NULL; efree(us); return NULL; } /* call it's dir_open method - set up params first */ - MAKE_STD_ZVAL(zfilename); - ZVAL_STRING(zfilename, filename, 1); - args[0] = &zfilename; + ZVAL_STRING(&args[0], filename); + ZVAL_LONG(&args[1], options); - MAKE_STD_ZVAL(zoptions); - ZVAL_LONG(zoptions, options); - args[1] = &zoptions; - - MAKE_STD_ZVAL(zfuncname); - ZVAL_STRING(zfuncname, USERSTREAM_DIR_OPEN, 1); + ZVAL_STRING(&zfuncname, USERSTREAM_DIR_OPEN); call_result = call_user_function_ex(NULL, - &us->object, - zfuncname, + Z_ISUNDEF(us->object)? NULL : &us->object, + &zfuncname, &zretval, 2, args, - 0, NULL TSRMLS_CC); + 0, NULL ); - if (call_result == SUCCESS && zretval != NULL && zval_is_true(zretval)) { + if (call_result == SUCCESS && Z_TYPE(zretval) != IS_UNDEF && zval_is_true(&zretval)) { /* the stream is now open! */ stream = php_stream_alloc_rel(&php_stream_userspace_dir_ops, us, 0, mode); /* set wrapper data to be a reference to our object */ - stream->wrapperdata = us->object; - zval_add_ref(&stream->wrapperdata); + ZVAL_COPY(&stream->wrapperdata, &us->object); } else { - php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed", + php_stream_wrapper_log_error(wrapper, options, "\"%s::" USERSTREAM_DIR_OPEN "\" call failed", us->wrapper->classname); } /* destroy everything else */ if (stream == NULL) { zval_ptr_dtor(&us->object); + ZVAL_UNDEF(&us->object); efree(us); } - if (zretval) - zval_ptr_dtor(&zretval); + zval_ptr_dtor(&zretval); zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&zoptions); - zval_ptr_dtor(&zfilename); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[0]); FG(user_stream_current_filename) = NULL; @@ -518,43 +487,41 @@ static php_stream *user_wrapper_opendir(php_stream_wrapper *wrapper, const char Registers a custom URL protocol handler class */ PHP_FUNCTION(stream_wrapper_register) { - char *protocol, *classname; - int protocol_len, classname_len; + zend_string *protocol, *classname; struct php_user_stream_wrapper * uwrap; - int rsrc_id; - long flags = 0; + zend_resource *rsrc; + zend_long flags = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &protocol, &protocol_len, &classname, &classname_len, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|l", &protocol, &classname, &flags) == FAILURE) { RETURN_FALSE; } uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap)); - uwrap->protoname = estrndup(protocol, protocol_len); - uwrap->classname = estrndup(classname, classname_len); + uwrap->protoname = estrndup(ZSTR_VAL(protocol), ZSTR_LEN(protocol)); + uwrap->classname = estrndup(ZSTR_VAL(classname), ZSTR_LEN(classname)); uwrap->wrapper.wops = &user_stream_wops; uwrap->wrapper.abstract = uwrap; uwrap->wrapper.is_url = ((flags & PHP_STREAM_IS_URL) != 0); - rsrc_id = ZEND_REGISTER_RESOURCE(NULL, uwrap, le_protocols); + rsrc = zend_register_resource(uwrap, le_protocols); - if (zend_lookup_class(uwrap->classname, classname_len, (zend_class_entry***)&uwrap->ce TSRMLS_CC) == SUCCESS) { - uwrap->ce = *(zend_class_entry**)uwrap->ce; - if (php_register_url_stream_wrapper_volatile(protocol, &uwrap->wrapper TSRMLS_CC) == SUCCESS) { + if ((uwrap->ce = zend_lookup_class(classname)) != NULL) { + if (php_register_url_stream_wrapper_volatile(ZSTR_VAL(protocol), &uwrap->wrapper) == SUCCESS) { RETURN_TRUE; } else { /* We failed. But why? */ - if (zend_hash_exists(php_stream_get_url_stream_wrappers_hash(), protocol, protocol_len + 1)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Protocol %s:// is already defined.", protocol); + if (zend_hash_exists(php_stream_get_url_stream_wrappers_hash(), protocol)) { + php_error_docref(NULL, E_WARNING, "Protocol %s:// is already defined.", ZSTR_VAL(protocol)); } else { /* Hash doesn't exist so it must have been an invalid protocol scheme */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid protocol scheme specified. Unable to register wrapper class %s to %s://", classname, protocol); + php_error_docref(NULL, E_WARNING, "Invalid protocol scheme specified. Unable to register wrapper class %s to %s://", ZSTR_VAL(classname), ZSTR_VAL(protocol)); } } } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "class '%s' is undefined", classname); + php_error_docref(NULL, E_WARNING, "class '%s' is undefined", ZSTR_VAL(classname)); } - zend_list_delete(rsrc_id); + zend_list_delete(rsrc); RETURN_FALSE; } /* }}} */ @@ -564,15 +531,15 @@ PHP_FUNCTION(stream_wrapper_register) PHP_FUNCTION(stream_wrapper_unregister) { char *protocol; - int protocol_len; + size_t protocol_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &protocol, &protocol_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &protocol, &protocol_len) == FAILURE) { RETURN_FALSE; } - if (php_unregister_url_stream_wrapper_volatile(protocol TSRMLS_CC) == FAILURE) { + if (php_unregister_url_stream_wrapper_volatile(protocol) == FAILURE) { /* We failed */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to unregister protocol %s://", protocol); + php_error_docref(NULL, E_WARNING, "Unable to unregister protocol %s://", protocol); RETURN_FALSE; } @@ -584,34 +551,30 @@ PHP_FUNCTION(stream_wrapper_unregister) Restore the original protocol handler, overriding if necessary */ PHP_FUNCTION(stream_wrapper_restore) { - char *protocol; - int protocol_len; - php_stream_wrapper **wrapperpp = NULL, *wrapper; + zend_string *protocol; + php_stream_wrapper *wrapper; HashTable *global_wrapper_hash; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &protocol, &protocol_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &protocol) == FAILURE) { RETURN_FALSE; } global_wrapper_hash = php_stream_get_url_stream_wrappers_hash_global(); if (php_stream_get_url_stream_wrappers_hash() == global_wrapper_hash) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s:// was never changed, nothing to restore", protocol); + php_error_docref(NULL, E_NOTICE, "%s:// was never changed, nothing to restore", ZSTR_VAL(protocol)); RETURN_TRUE; } - if ((zend_hash_find(global_wrapper_hash, protocol, protocol_len + 1, (void**)&wrapperpp) == FAILURE) || !wrapperpp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s:// never existed, nothing to restore", protocol); + if ((wrapper = zend_hash_find_ptr(global_wrapper_hash, protocol)) == NULL) { + php_error_docref(NULL, E_WARNING, "%s:// never existed, nothing to restore", ZSTR_VAL(protocol)); RETURN_FALSE; } - /* next line might delete the pointer that wrapperpp points at, so deref it now */ - wrapper = *wrapperpp; - /* A failure here could be okay given that the protocol might have been merely unregistered */ - php_unregister_url_stream_wrapper_volatile(protocol TSRMLS_CC); + php_unregister_url_stream_wrapper_volatile(ZSTR_VAL(protocol)); - if (php_register_url_stream_wrapper_volatile(protocol, wrapper TSRMLS_CC) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to restore original %s:// wrapper", protocol); + if (php_register_url_stream_wrapper_volatile(ZSTR_VAL(protocol), wrapper) == FAILURE) { + php_error_docref(NULL, E_WARNING, "Unable to restore original %s:// wrapper", ZSTR_VAL(protocol)); RETURN_FALSE; } @@ -619,31 +582,29 @@ PHP_FUNCTION(stream_wrapper_restore) } /* }}} */ -static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t count) { zval func_name; - zval *retval = NULL; + zval retval; int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; - zval **args[1]; - zval *zbufptr; + zval args[1]; size_t didwrite = 0; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_WRITE, sizeof(USERSTREAM_WRITE)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_WRITE, sizeof(USERSTREAM_WRITE)-1); - MAKE_STD_ZVAL(zbufptr); - ZVAL_STRINGL(zbufptr, (char*)buf, count, 1);; - args[0] = &zbufptr; + ZVAL_STRINGL(&args[0], (char*)buf, count); call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, 1, args, - 0, NULL TSRMLS_CC); - zval_ptr_dtor(&zbufptr); + 0, NULL); + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&func_name); didwrite = 0; @@ -651,252 +612,235 @@ static size_t php_userstreamop_write(php_stream *stream, const char *buf, size_t return 0; } - if (call_result == SUCCESS && retval != NULL) { - convert_to_long(retval); - didwrite = Z_LVAL_P(retval); + if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { + convert_to_long(&retval); + didwrite = Z_LVAL(retval); } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " is not implemented!", us->wrapper->classname); } /* don't allow strange buffer overruns due to bogus return */ if (didwrite > count) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_WRITE " wrote %ld bytes more data than requested (%ld written, %ld max)", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_WRITE " wrote " ZEND_LONG_FMT " bytes more data than requested (" ZEND_LONG_FMT " written, " ZEND_LONG_FMT " max)", us->wrapper->classname, - (long)(didwrite - count), (long)didwrite, (long)count); + (zend_long)(didwrite - count), (zend_long)didwrite, (zend_long)count); didwrite = count; } - if (retval) - zval_ptr_dtor(&retval); + zval_ptr_dtor(&retval); return didwrite; } -static size_t php_userstreamop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_userstreamop_read(php_stream *stream, char *buf, size_t count) { zval func_name; - zval *retval = NULL; - zval **args[1]; + zval retval; + zval args[1]; int call_result; size_t didread = 0; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; - zval *zcount; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_READ, sizeof(USERSTREAM_READ)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_READ, sizeof(USERSTREAM_READ)-1); - MAKE_STD_ZVAL(zcount); - ZVAL_LONG(zcount, count); - args[0] = &zcount; + ZVAL_LONG(&args[0], count); call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, 1, args, - 0, NULL TSRMLS_CC); + 0, NULL); - zval_ptr_dtor(&zcount); + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&func_name); if (EG(exception)) { - return 0; + return -1; } - if (call_result == SUCCESS && retval != NULL) { - convert_to_string(retval); - didread = Z_STRLEN_P(retval); + if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { + convert_to_string(&retval); + didread = Z_STRLEN(retval); if (didread > count) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_READ " - read %ld bytes more data than requested (%ld read, %ld max) - excess data will be lost", - us->wrapper->classname, (long)(didread - count), (long)didread, (long)count); + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " - read " ZEND_LONG_FMT " bytes more data than requested (" ZEND_LONG_FMT " read, " ZEND_LONG_FMT " max) - excess data will be lost", + us->wrapper->classname, (zend_long)(didread - count), (zend_long)didread, (zend_long)count); didread = count; } if (didread > 0) - memcpy(buf, Z_STRVAL_P(retval), didread); + memcpy(buf, Z_STRVAL(retval), didread); } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_READ " is not implemented!", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_READ " is not implemented!", us->wrapper->classname); } - if (retval) { - zval_ptr_dtor(&retval); - retval = NULL; - } + zval_ptr_dtor(&retval); + ZVAL_UNDEF(&retval); /* since the user stream has no way of setting the eof flag directly, we need to ask it if we hit eof */ - ZVAL_STRINGL(&func_name, USERSTREAM_EOF, sizeof(USERSTREAM_EOF)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_EOF, sizeof(USERSTREAM_EOF)-1); call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, - 0, NULL, 0, NULL TSRMLS_CC); + 0, NULL, 0, NULL); - if (call_result == SUCCESS && retval != NULL && zval_is_true(retval)) { + if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF && zval_is_true(&retval)) { stream->eof = 1; } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_EOF " is not implemented! Assuming EOF", us->wrapper->classname); stream->eof = 1; } - if (retval) { - zval_ptr_dtor(&retval); - retval = NULL; - } + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); return didread; } -static int php_userstreamop_close(php_stream *stream, int close_handle TSRMLS_DC) +static int php_userstreamop_close(php_stream *stream, int close_handle) { zval func_name; - zval *retval = NULL; + zval retval; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_CLOSE, sizeof(USERSTREAM_CLOSE)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_CLOSE, sizeof(USERSTREAM_CLOSE)-1); call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, - 0, NULL, 0, NULL TSRMLS_CC); + 0, NULL, 0, NULL); - if (retval) - zval_ptr_dtor(&retval); + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); zval_ptr_dtor(&us->object); + ZVAL_UNDEF(&us->object); efree(us); return 0; } -static int php_userstreamop_flush(php_stream *stream TSRMLS_DC) +static int php_userstreamop_flush(php_stream *stream) { zval func_name; - zval *retval = NULL; + zval retval; int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_FLUSH, sizeof(USERSTREAM_FLUSH)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_FLUSH, sizeof(USERSTREAM_FLUSH)-1); call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, - 0, NULL, 0, NULL TSRMLS_CC); + 0, NULL, 0, NULL); - if (call_result == SUCCESS && retval != NULL && zval_is_true(retval)) + if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF && zval_is_true(&retval)) call_result = 0; else call_result = -1; - if (retval) - zval_ptr_dtor(&retval); + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); return call_result; } -static int php_userstreamop_seek(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) +static int php_userstreamop_seek(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs) { zval func_name; - zval *retval = NULL; + zval retval; int call_result, ret; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; - zval **args[2]; - zval *zoffs, *zwhence; + zval args[2]; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_SEEK, sizeof(USERSTREAM_SEEK)-1, 0); - - MAKE_STD_ZVAL(zoffs); - ZVAL_LONG(zoffs, offset); - args[0] = &zoffs; + ZVAL_STRINGL(&func_name, USERSTREAM_SEEK, sizeof(USERSTREAM_SEEK)-1); - MAKE_STD_ZVAL(zwhence); - ZVAL_LONG(zwhence, whence); - args[1] = &zwhence; + ZVAL_LONG(&args[0], offset); + ZVAL_LONG(&args[1], whence); call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, 2, args, - 0, NULL TSRMLS_CC); + 0, NULL); - zval_ptr_dtor(&zoffs); - zval_ptr_dtor(&zwhence); + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&func_name); if (call_result == FAILURE) { /* stream_seek is not implemented, so disable seeks for this stream */ stream->flags |= PHP_STREAM_FLAG_NO_SEEK; /* there should be no retval to clean up */ - if (retval) - zval_ptr_dtor(&retval); + zval_ptr_dtor(&retval); return -1; - } else if (call_result == SUCCESS && retval != NULL && zval_is_true(retval)) { + } else if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF && zval_is_true(&retval)) { ret = 0; } else { ret = -1; } - if (retval) { - zval_ptr_dtor(&retval); - retval = NULL; - } + zval_ptr_dtor(&retval); + ZVAL_UNDEF(&retval); if (ret) { return ret; } /* now determine where we are */ - ZVAL_STRINGL(&func_name, USERSTREAM_TELL, sizeof(USERSTREAM_TELL)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_TELL, sizeof(USERSTREAM_TELL)-1); call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, - 0, NULL, 0, NULL TSRMLS_CC); + 0, NULL, 0, NULL); - if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_LONG) { - *newoffs = Z_LVAL_P(retval); + if (call_result == SUCCESS && Z_TYPE(retval) == IS_LONG) { + *newoffs = Z_LVAL(retval); ret = 0; } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", us->wrapper->classname); + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TELL " is not implemented!", us->wrapper->classname); ret = -1; } else { ret = -1; } - if (retval) { - zval_ptr_dtor(&retval); - } + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); return ret; } /* parse the return value from one of the stat functions and store the * relevant fields into the statbuf provided */ -static int statbuf_from_array(zval *array, php_stream_statbuf *ssb TSRMLS_DC) +static int statbuf_from_array(zval *array, php_stream_statbuf *ssb) { - zval **elem; + zval *elem; #define STAT_PROP_ENTRY_EX(name, name2) \ - if (SUCCESS == zend_hash_find(Z_ARRVAL_P(array), #name, sizeof(#name), (void**)&elem)) { \ - SEPARATE_ZVAL(elem); \ - convert_to_long(*elem); \ - ssb->sb.st_##name2 = Z_LVAL_PP(elem); \ + if (NULL != (elem = zend_hash_str_find(Z_ARRVAL_P(array), #name, sizeof(#name)-1))) { \ + ssb->sb.st_##name2 = zval_get_long(elem); \ } #define STAT_PROP_ENTRY(name) STAT_PROP_ENTRY_EX(name,name) @@ -933,114 +877,116 @@ static int statbuf_from_array(zval *array, php_stream_statbuf *ssb TSRMLS_DC) return SUCCESS; } -static int php_userstreamop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +static int php_userstreamop_stat(php_stream *stream, php_stream_statbuf *ssb) { zval func_name; - zval *retval = NULL; + zval retval; int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; int ret = -1; - ZVAL_STRINGL(&func_name, USERSTREAM_STAT, sizeof(USERSTREAM_STAT)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_STAT, sizeof(USERSTREAM_STAT)-1); call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, - 0, NULL, 0, NULL TSRMLS_CC); + 0, NULL, 0, NULL); - if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_ARRAY) { - if (SUCCESS == statbuf_from_array(retval, ssb TSRMLS_CC)) + if (call_result == SUCCESS && Z_TYPE(retval) == IS_ARRAY) { + if (SUCCESS == statbuf_from_array(&retval, ssb)) ret = 0; } else { if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_STAT " is not implemented!", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STAT " is not implemented!", us->wrapper->classname); } } - if (retval) - zval_ptr_dtor(&retval); + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); return ret; } -static int php_userstreamop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) { +static int php_userstreamop_set_option(php_stream *stream, int option, int value, void *ptrparam) { zval func_name; - zval *retval = NULL; + zval retval; int call_result; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; int ret = PHP_STREAM_OPTION_RETURN_NOTIMPL; - zval *zvalue = NULL; - zval **args[3]; + zval args[3]; switch (option) { case PHP_STREAM_OPTION_CHECK_LIVENESS: - ZVAL_STRINGL(&func_name, USERSTREAM_EOF, sizeof(USERSTREAM_EOF)-1, 0); - call_result = call_user_function_ex(NULL, &us->object, &func_name, &retval, 0, NULL, 0, NULL TSRMLS_CC); - if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_BOOL) { - ret = zval_is_true(retval) ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; + ZVAL_STRINGL(&func_name, USERSTREAM_EOF, sizeof(USERSTREAM_EOF)-1); + call_result = call_user_function_ex(NULL, Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, 0, NULL, 0, NULL); + if (call_result == SUCCESS && (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE)) { + ret = zval_is_true(&retval) ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; } else { ret = PHP_STREAM_OPTION_RETURN_ERR; - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_EOF " is not implemented! Assuming EOF", us->wrapper->classname); } + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); break; case PHP_STREAM_OPTION_LOCKING: - MAKE_STD_ZVAL(zvalue); - ZVAL_LONG(zvalue, 0); + ZVAL_LONG(&args[0], 0); if (value & LOCK_NB) { - Z_LVAL_P(zvalue) |= PHP_LOCK_NB; + Z_LVAL_P(&args[0]) |= PHP_LOCK_NB; } switch(value & ~LOCK_NB) { case LOCK_SH: - Z_LVAL_P(zvalue) |= PHP_LOCK_SH; + Z_LVAL_P(&args[0]) |= PHP_LOCK_SH; break; case LOCK_EX: - Z_LVAL_P(zvalue) |= PHP_LOCK_EX; + Z_LVAL_P(&args[0]) |= PHP_LOCK_EX; break; case LOCK_UN: - Z_LVAL_P(zvalue) |= PHP_LOCK_UN; + Z_LVAL_P(&args[0]) |= PHP_LOCK_UN; break; } - args[0] = &zvalue; - /* TODO wouldblock */ - ZVAL_STRINGL(&func_name, USERSTREAM_LOCK, sizeof(USERSTREAM_LOCK)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_LOCK, sizeof(USERSTREAM_LOCK)-1); call_result = call_user_function_ex(NULL, - &us->object, - &func_name, - &retval, - 1, args, 0, NULL TSRMLS_CC); + Z_ISUNDEF(us->object)? NULL : &us->object, + &func_name, + &retval, + 1, args, 0, NULL); - if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) == IS_BOOL) { - ret = !Z_LVAL_P(retval); + if (call_result == SUCCESS && (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE)) { + ret = (Z_TYPE(retval) == IS_FALSE); } else if (call_result == FAILURE) { if (value == 0) { /* lock support test (TODO: more check) */ ret = PHP_STREAM_OPTION_RETURN_OK; } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_LOCK " is not implemented!", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_LOCK " is not implemented!", us->wrapper->classname); ret = PHP_STREAM_OPTION_RETURN_ERR; } } + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); + zval_ptr_dtor(&args[0]); break; case PHP_STREAM_OPTION_TRUNCATE_API: - ZVAL_STRINGL(&func_name, USERSTREAM_TRUNCATE, sizeof(USERSTREAM_TRUNCATE)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_TRUNCATE, sizeof(USERSTREAM_TRUNCATE)-1); switch (value) { case PHP_STREAM_TRUNCATE_SUPPORTED: - if (zend_is_callable_ex(&func_name, us->object, IS_CALLABLE_CHECK_SILENT, - NULL, NULL, NULL, NULL TSRMLS_CC)) + if (zend_is_callable_ex(&func_name, + Z_ISUNDEF(us->object)? NULL : Z_OBJ(us->object), + IS_CALLABLE_CHECK_SILENT, NULL, NULL, NULL)) ret = PHP_STREAM_OPTION_RETURN_OK; else ret = PHP_STREAM_OPTION_RETURN_ERR; @@ -1049,479 +995,413 @@ static int php_userstreamop_set_option(php_stream *stream, int option, int value case PHP_STREAM_TRUNCATE_SET_SIZE: { ptrdiff_t new_size = *(ptrdiff_t*) ptrparam; if (new_size >= 0 && new_size <= (ptrdiff_t)LONG_MAX) { - MAKE_STD_ZVAL(zvalue); - ZVAL_LONG(zvalue, (long)new_size); - args[0] = &zvalue; + ZVAL_LONG(&args[0], (zend_long)new_size); call_result = call_user_function_ex(NULL, - &us->object, - &func_name, - &retval, - 1, args, 0, NULL TSRMLS_CC); - if (call_result == SUCCESS && retval != NULL) { - if (Z_TYPE_P(retval) == IS_BOOL) { - ret = Z_LVAL_P(retval) ? PHP_STREAM_OPTION_RETURN_OK : - PHP_STREAM_OPTION_RETURN_ERR; + Z_ISUNDEF(us->object)? NULL : &us->object, + &func_name, + &retval, + 1, args, 0, NULL); + if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { + if (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE) { + ret = (Z_TYPE(retval) == IS_TRUE) ? PHP_STREAM_OPTION_RETURN_OK : + PHP_STREAM_OPTION_RETURN_ERR; } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TRUNCATE " did not return a boolean!", us->wrapper->classname); } } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_TRUNCATE " is not implemented!", us->wrapper->classname); } + zval_ptr_dtor(&retval); + zval_ptr_dtor(&args[0]); } else { /* bad new size */ ret = PHP_STREAM_OPTION_RETURN_ERR; } break; } } + zval_ptr_dtor(&func_name); break; case PHP_STREAM_OPTION_READ_BUFFER: case PHP_STREAM_OPTION_WRITE_BUFFER: case PHP_STREAM_OPTION_READ_TIMEOUT: case PHP_STREAM_OPTION_BLOCKING: { - zval *zoption = NULL; - zval *zptrparam = NULL; - - ZVAL_STRINGL(&func_name, USERSTREAM_SET_OPTION, sizeof(USERSTREAM_SET_OPTION)-1, 0); - ALLOC_INIT_ZVAL(zoption); - ZVAL_LONG(zoption, option); + ZVAL_STRINGL(&func_name, USERSTREAM_SET_OPTION, sizeof(USERSTREAM_SET_OPTION)-1); - ALLOC_INIT_ZVAL(zvalue); - ALLOC_INIT_ZVAL(zptrparam); - - args[0] = &zoption; - args[1] = &zvalue; - args[2] = &zptrparam; + ZVAL_LONG(&args[0], option); + ZVAL_NULL(&args[1]); + ZVAL_NULL(&args[2]); switch(option) { case PHP_STREAM_OPTION_READ_BUFFER: case PHP_STREAM_OPTION_WRITE_BUFFER: - ZVAL_LONG(zvalue, value); + ZVAL_LONG(&args[1], value); if (ptrparam) { - ZVAL_LONG(zptrparam, *(long *)ptrparam); + ZVAL_LONG(&args[2], *(long *)ptrparam); } else { - ZVAL_LONG(zptrparam, BUFSIZ); + ZVAL_LONG(&args[2], BUFSIZ); } break; case PHP_STREAM_OPTION_READ_TIMEOUT: { struct timeval tv = *(struct timeval*)ptrparam; - ZVAL_LONG(zvalue, tv.tv_sec); - ZVAL_LONG(zptrparam, tv.tv_usec); + ZVAL_LONG(&args[1], tv.tv_sec); + ZVAL_LONG(&args[2], tv.tv_usec); break; } case PHP_STREAM_OPTION_BLOCKING: - ZVAL_LONG(zvalue, value); + ZVAL_LONG(&args[1], value); break; default: break; } call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, - 3, args, 0, NULL TSRMLS_CC); + 3, args, 0, NULL); if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_SET_OPTION " is not implemented!", us->wrapper->classname); ret = PHP_STREAM_OPTION_RETURN_ERR; - } else if (retval && zend_is_true(retval)) { + } else if (Z_TYPE(retval) != IS_UNDEF && zend_is_true(&retval)) { ret = PHP_STREAM_OPTION_RETURN_OK; } else { ret = PHP_STREAM_OPTION_RETURN_ERR; } - if (zoption) { - zval_ptr_dtor(&zoption); - } - if (zptrparam) { - zval_ptr_dtor(&zptrparam); - } + zval_ptr_dtor(&retval); + zval_ptr_dtor(&args[2]); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&func_name); break; } } - /* clean up */ - if (retval) { - zval_ptr_dtor(&retval); - } - - - if (zvalue) { - zval_ptr_dtor(&zvalue); - } - return ret; } -static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context TSRMLS_DC) +static int user_wrapper_unlink(php_stream_wrapper *wrapper, const char *url, int options, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval *zfilename, *zfuncname, *zretval; - zval **args[1]; + zval zfuncname, zretval; + zval args[1]; int call_result; - zval *object; + zval object; int ret = 0; /* create an instance of our class */ - object = user_stream_create_object(uwrap, context TSRMLS_CC); - if(object == NULL) { + user_stream_create_object(uwrap, context, &object); + if (Z_TYPE(object) == IS_UNDEF) { return ret; } /* call the unlink method */ - MAKE_STD_ZVAL(zfilename); - ZVAL_STRING(zfilename, url, 1); - args[0] = &zfilename; + ZVAL_STRING(&args[0], url); - MAKE_STD_ZVAL(zfuncname); - ZVAL_STRING(zfuncname, USERSTREAM_UNLINK, 1); + ZVAL_STRING(&zfuncname, USERSTREAM_UNLINK); call_result = call_user_function_ex(NULL, &object, - zfuncname, + &zfuncname, &zretval, 1, args, - 0, NULL TSRMLS_CC); + 0, NULL ); - if (call_result == SUCCESS && zretval && Z_TYPE_P(zretval) == IS_BOOL) { - ret = Z_LVAL_P(zretval); + if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { + ret = (Z_TYPE(zretval) == IS_TRUE); } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", uwrap->classname); + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_UNLINK " is not implemented!", uwrap->classname); } /* clean up */ zval_ptr_dtor(&object); - if (zretval) - zval_ptr_dtor(&zretval); - + zval_ptr_dtor(&zretval); zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&zfilename); + + zval_ptr_dtor(&args[0]); return ret; } static int user_wrapper_rename(php_stream_wrapper *wrapper, const char *url_from, const char *url_to, - int options, php_stream_context *context TSRMLS_DC) + int options, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval *zold_name, *znew_name, *zfuncname, *zretval; - zval **args[2]; + zval zfuncname, zretval; + zval args[2]; int call_result; - zval *object; + zval object; int ret = 0; /* create an instance of our class */ - object = user_stream_create_object(uwrap, context TSRMLS_CC); - if(object == NULL) { + user_stream_create_object(uwrap, context, &object); + if (Z_TYPE(object) == IS_UNDEF) { return ret; } /* call the rename method */ - MAKE_STD_ZVAL(zold_name); - ZVAL_STRING(zold_name, url_from, 1); - args[0] = &zold_name; - - MAKE_STD_ZVAL(znew_name); - ZVAL_STRING(znew_name, url_to, 1); - args[1] = &znew_name; + ZVAL_STRING(&args[0], url_from); + ZVAL_STRING(&args[1], url_to); - MAKE_STD_ZVAL(zfuncname); - ZVAL_STRING(zfuncname, USERSTREAM_RENAME, 1); + ZVAL_STRING(&zfuncname, USERSTREAM_RENAME); call_result = call_user_function_ex(NULL, &object, - zfuncname, + &zfuncname, &zretval, 2, args, - 0, NULL TSRMLS_CC); + 0, NULL ); - if (call_result == SUCCESS && zretval && Z_TYPE_P(zretval) == IS_BOOL) { - ret = Z_LVAL_P(zretval); + if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { + ret = (Z_TYPE(zretval) == IS_TRUE); } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", uwrap->classname); + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RENAME " is not implemented!", uwrap->classname); } /* clean up */ zval_ptr_dtor(&object); - if (zretval) - zval_ptr_dtor(&zretval); + zval_ptr_dtor(&zretval); zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&zold_name); - zval_ptr_dtor(&znew_name); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[0]); return ret; } static int user_wrapper_mkdir(php_stream_wrapper *wrapper, const char *url, int mode, - int options, php_stream_context *context TSRMLS_DC) + int options, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval *zfilename, *zmode, *zoptions, *zfuncname, *zretval; - zval **args[3]; + zval zfuncname, zretval; + zval args[3]; int call_result; - zval *object; + zval object; int ret = 0; /* create an instance of our class */ - object = user_stream_create_object(uwrap, context TSRMLS_CC); - if(object == NULL) { + user_stream_create_object(uwrap, context, &object); + if (Z_TYPE(object) == IS_UNDEF) { return ret; } /* call the mkdir method */ - MAKE_STD_ZVAL(zfilename); - ZVAL_STRING(zfilename, url, 1); - args[0] = &zfilename; - - MAKE_STD_ZVAL(zmode); - ZVAL_LONG(zmode, mode); - args[1] = &zmode; + ZVAL_STRING(&args[0], url); + ZVAL_LONG(&args[1], mode); + ZVAL_LONG(&args[2], options); - MAKE_STD_ZVAL(zoptions); - ZVAL_LONG(zoptions, options); - args[2] = &zoptions; - - MAKE_STD_ZVAL(zfuncname); - ZVAL_STRING(zfuncname, USERSTREAM_MKDIR, 1); + ZVAL_STRING(&zfuncname, USERSTREAM_MKDIR); call_result = call_user_function_ex(NULL, &object, - zfuncname, + &zfuncname, &zretval, 3, args, - 0, NULL TSRMLS_CC); + 0, NULL ); - if (call_result == SUCCESS && zretval && Z_TYPE_P(zretval) == IS_BOOL) { - ret = Z_LVAL_P(zretval); + if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { + ret = (Z_TYPE(zretval) == IS_TRUE); } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", uwrap->classname); + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_MKDIR " is not implemented!", uwrap->classname); } /* clean up */ zval_ptr_dtor(&object); - if (zretval) { - zval_ptr_dtor(&zretval); - } + zval_ptr_dtor(&zretval); zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&zfilename); - zval_ptr_dtor(&zmode); - zval_ptr_dtor(&zoptions); + zval_ptr_dtor(&args[2]); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[0]); return ret; } static int user_wrapper_rmdir(php_stream_wrapper *wrapper, const char *url, - int options, php_stream_context *context TSRMLS_DC) + int options, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval *zfilename, *zoptions, *zfuncname, *zretval; - zval **args[3]; + zval zfuncname, zretval; + zval args[2]; int call_result; - zval *object; + zval object; int ret = 0; /* create an instance of our class */ - object = user_stream_create_object(uwrap, context TSRMLS_CC); - if(object == NULL) { + user_stream_create_object(uwrap, context, &object); + if (Z_TYPE(object) == IS_UNDEF) { return ret; } /* call the rmdir method */ - MAKE_STD_ZVAL(zfilename); - ZVAL_STRING(zfilename, url, 1); - args[0] = &zfilename; + ZVAL_STRING(&args[0], url); + ZVAL_LONG(&args[1], options); - MAKE_STD_ZVAL(zoptions); - ZVAL_LONG(zoptions, options); - args[1] = &zoptions; - - MAKE_STD_ZVAL(zfuncname); - ZVAL_STRING(zfuncname, USERSTREAM_RMDIR, 1); + ZVAL_STRING(&zfuncname, USERSTREAM_RMDIR); call_result = call_user_function_ex(NULL, &object, - zfuncname, + &zfuncname, &zretval, 2, args, - 0, NULL TSRMLS_CC); + 0, NULL ); - if (call_result == SUCCESS && zretval && Z_TYPE_P(zretval) == IS_BOOL) { - ret = Z_LVAL_P(zretval); + if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { + ret = (Z_TYPE(zretval) == IS_TRUE); } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", uwrap->classname); + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_RMDIR " is not implemented!", uwrap->classname); } /* clean up */ zval_ptr_dtor(&object); - if (zretval) { - zval_ptr_dtor(&zretval); - } + zval_ptr_dtor(&zretval); zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&zfilename); - zval_ptr_dtor(&zoptions); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[0]); return ret; } static int user_wrapper_metadata(php_stream_wrapper *wrapper, const char *url, int option, - void *value, php_stream_context *context TSRMLS_DC) + void *value, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval *zfilename, *zoption, *zvalue, *zfuncname, *zretval; - zval **args[3]; + zval zfuncname, zretval; + zval args[3]; int call_result; - zval *object; + zval object; int ret = 0; - MAKE_STD_ZVAL(zvalue); switch(option) { case PHP_STREAM_META_TOUCH: - array_init(zvalue); + array_init(&args[2]); if(value) { struct utimbuf *newtime = (struct utimbuf *)value; - add_index_long(zvalue, 0, newtime->modtime); - add_index_long(zvalue, 1, newtime->actime); + add_index_long(&args[2], 0, newtime->modtime); + add_index_long(&args[2], 1, newtime->actime); } break; case PHP_STREAM_META_GROUP: case PHP_STREAM_META_OWNER: case PHP_STREAM_META_ACCESS: - ZVAL_LONG(zvalue, *(long *)value); + ZVAL_LONG(&args[2], *(long *)value); break; case PHP_STREAM_META_GROUP_NAME: case PHP_STREAM_META_OWNER_NAME: - ZVAL_STRING(zvalue, value, 1); + ZVAL_STRING(&args[2], value); break; default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option %d for " USERSTREAM_METADATA, option); - zval_ptr_dtor(&zvalue); + php_error_docref(NULL, E_WARNING, "Unknown option %d for " USERSTREAM_METADATA, option); + zval_ptr_dtor(&args[2]); return ret; } /* create an instance of our class */ - object = user_stream_create_object(uwrap, context TSRMLS_CC); - if(object == NULL) { - zval_ptr_dtor(&zvalue); + user_stream_create_object(uwrap, context, &object); + if (Z_TYPE(object) == IS_UNDEF) { + zval_ptr_dtor(&args[2]); return ret; } /* call the mkdir method */ - MAKE_STD_ZVAL(zfilename); - ZVAL_STRING(zfilename, url, 1); - args[0] = &zfilename; + ZVAL_STRING(&args[0], url); + ZVAL_LONG(&args[1], option); - MAKE_STD_ZVAL(zoption); - ZVAL_LONG(zoption, option); - args[1] = &zoption; - - args[2] = &zvalue; - - MAKE_STD_ZVAL(zfuncname); - ZVAL_STRING(zfuncname, USERSTREAM_METADATA, 1); + ZVAL_STRING(&zfuncname, USERSTREAM_METADATA); call_result = call_user_function_ex(NULL, &object, - zfuncname, + &zfuncname, &zretval, 3, args, - 0, NULL TSRMLS_CC); + 0, NULL ); - if (call_result == SUCCESS && zretval && Z_TYPE_P(zretval) == IS_BOOL) { - ret = Z_LVAL_P(zretval); + if (call_result == SUCCESS && (Z_TYPE(zretval) == IS_FALSE || Z_TYPE(zretval) == IS_TRUE)) { + ret = Z_TYPE(zretval) == IS_TRUE; } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", uwrap->classname); + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_METADATA " is not implemented!", uwrap->classname); } /* clean up */ zval_ptr_dtor(&object); - if (zretval) { - zval_ptr_dtor(&zretval); - } + zval_ptr_dtor(&zretval); zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&zfilename); - zval_ptr_dtor(&zoption); - zval_ptr_dtor(&zvalue); + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[2]); return ret; } static int user_wrapper_stat_url(php_stream_wrapper *wrapper, const char *url, int flags, - php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC) + php_stream_statbuf *ssb, php_stream_context *context) { struct php_user_stream_wrapper *uwrap = (struct php_user_stream_wrapper*)wrapper->abstract; - zval *zfilename, *zfuncname, *zretval, *zflags; - zval **args[2]; + zval zfuncname, zretval; + zval args[2]; int call_result; - zval *object; + zval object; int ret = -1; /* create an instance of our class */ - object = user_stream_create_object(uwrap, context TSRMLS_CC); - if(object == NULL) { + user_stream_create_object(uwrap, context, &object); + if (Z_TYPE(object) == IS_UNDEF) { return ret; } /* call it's stat_url method - set up params first */ - MAKE_STD_ZVAL(zfilename); - ZVAL_STRING(zfilename, url, 1); - args[0] = &zfilename; - - MAKE_STD_ZVAL(zflags); - ZVAL_LONG(zflags, flags); - args[1] = &zflags; + ZVAL_STRING(&args[0], url); + ZVAL_LONG(&args[1], flags); - MAKE_STD_ZVAL(zfuncname); - ZVAL_STRING(zfuncname, USERSTREAM_STATURL, 1); + ZVAL_STRING(&zfuncname, USERSTREAM_STATURL); call_result = call_user_function_ex(NULL, &object, - zfuncname, + &zfuncname, &zretval, 2, args, - 0, NULL TSRMLS_CC); + 0, NULL ); - if (call_result == SUCCESS && zretval != NULL && Z_TYPE_P(zretval) == IS_ARRAY) { + if (call_result == SUCCESS && Z_TYPE(zretval) == IS_ARRAY) { /* We got the info we needed */ - if (SUCCESS == statbuf_from_array(zretval, ssb TSRMLS_CC)) + if (SUCCESS == statbuf_from_array(&zretval, ssb)) ret = 0; } else { if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_STATURL " is not implemented!", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_STATURL " is not implemented!", uwrap->classname); } } /* clean up */ zval_ptr_dtor(&object); - if (zretval) - zval_ptr_dtor(&zretval); + zval_ptr_dtor(&zretval); zval_ptr_dtor(&zfuncname); - zval_ptr_dtor(&zfilename); - zval_ptr_dtor(&zflags); + zval_ptr_dtor(&args[1]); + zval_ptr_dtor(&args[0]); return ret; } -static size_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t count) { zval func_name; - zval *retval = NULL; + zval retval; int call_result; size_t didread = 0; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; @@ -1531,125 +1411,122 @@ static size_t php_userstreamop_readdir(php_stream *stream, char *buf, size_t cou if (count != sizeof(php_stream_dirent)) return 0; - ZVAL_STRINGL(&func_name, USERSTREAM_DIR_READ, sizeof(USERSTREAM_DIR_READ)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_DIR_READ, sizeof(USERSTREAM_DIR_READ)-1); call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, 0, NULL, - 0, NULL TSRMLS_CC); + 0, NULL); - if (call_result == SUCCESS && retval != NULL && Z_TYPE_P(retval) != IS_BOOL) { - convert_to_string(retval); - PHP_STRLCPY(ent->d_name, Z_STRVAL_P(retval), sizeof(ent->d_name), Z_STRLEN_P(retval)); + if (call_result == SUCCESS && Z_TYPE(retval) != IS_FALSE && Z_TYPE(retval) != IS_TRUE) { + convert_to_string(&retval); + PHP_STRLCPY(ent->d_name, Z_STRVAL(retval), sizeof(ent->d_name), Z_STRLEN(retval)); didread = sizeof(php_stream_dirent); } else if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_DIR_READ " is not implemented!", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_DIR_READ " is not implemented!", us->wrapper->classname); } - if (retval) - zval_ptr_dtor(&retval); + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); return didread; } -static int php_userstreamop_closedir(php_stream *stream, int close_handle TSRMLS_DC) +static int php_userstreamop_closedir(php_stream *stream, int close_handle) { zval func_name; - zval *retval = NULL; + zval retval; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; assert(us != NULL); - ZVAL_STRINGL(&func_name, USERSTREAM_DIR_CLOSE, sizeof(USERSTREAM_DIR_CLOSE)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_DIR_CLOSE, sizeof(USERSTREAM_DIR_CLOSE)-1); call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, - 0, NULL, 0, NULL TSRMLS_CC); - - if (retval) - zval_ptr_dtor(&retval); + 0, NULL, 0, NULL); + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); zval_ptr_dtor(&us->object); + ZVAL_UNDEF(&us->object); efree(us); return 0; } -static int php_userstreamop_rewinddir(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) +static int php_userstreamop_rewinddir(php_stream *stream, zend_off_t offset, int whence, zend_off_t *newoffs) { zval func_name; - zval *retval = NULL; + zval retval; php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; - ZVAL_STRINGL(&func_name, USERSTREAM_DIR_REWIND, sizeof(USERSTREAM_DIR_REWIND)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_DIR_REWIND, sizeof(USERSTREAM_DIR_REWIND)-1); call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, - 0, NULL, 0, NULL TSRMLS_CC); + 0, NULL, 0, NULL); - if (retval) - zval_ptr_dtor(&retval); + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); return 0; } -static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr TSRMLS_DC) +static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr) { php_userstream_data_t *us = (php_userstream_data_t *)stream->abstract; zval func_name; - zval *retval = NULL; - zval *zcastas = NULL; - zval **args[1]; + zval retval; + zval args[1]; php_stream * intstream = NULL; int call_result; int ret = FAILURE; - ZVAL_STRINGL(&func_name, USERSTREAM_CAST, sizeof(USERSTREAM_CAST)-1, 0); + ZVAL_STRINGL(&func_name, USERSTREAM_CAST, sizeof(USERSTREAM_CAST)-1); - ALLOC_INIT_ZVAL(zcastas); switch(castas) { case PHP_STREAM_AS_FD_FOR_SELECT: - ZVAL_LONG(zcastas, PHP_STREAM_AS_FD_FOR_SELECT); + ZVAL_LONG(&args[0], PHP_STREAM_AS_FD_FOR_SELECT); break; default: - ZVAL_LONG(zcastas, PHP_STREAM_AS_STDIO); + ZVAL_LONG(&args[0], PHP_STREAM_AS_STDIO); break; } - args[0] = &zcastas; call_result = call_user_function_ex(NULL, - &us->object, + Z_ISUNDEF(us->object)? NULL : &us->object, &func_name, &retval, - 1, args, 0, NULL TSRMLS_CC); + 1, args, 0, NULL); do { if (call_result == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_CAST " is not implemented!", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " is not implemented!", us->wrapper->classname); break; } - if (retval == NULL || !zend_is_true(retval)) { + if (Z_ISUNDEF(retval) || !zend_is_true(&retval)) { break; } php_stream_from_zval_no_verify(intstream, &retval); if (!intstream) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_CAST " must return a stream resource", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must return a stream resource", us->wrapper->classname); break; } if (intstream == stream) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s::" USERSTREAM_CAST " must not return itself", + php_error_docref(NULL, E_WARNING, "%s::" USERSTREAM_CAST " must not return itself", us->wrapper->classname); intstream = NULL; break; @@ -1657,12 +1534,9 @@ static int php_userstreamop_cast(php_stream *stream, int castas, void **retptr T ret = php_stream_cast(intstream, castas, retptr, 1); } while (0); - if (retval) { - zval_ptr_dtor(&retval); - } - if (zcastas) { - zval_ptr_dtor(&zcastas); - } + zval_ptr_dtor(&retval); + zval_ptr_dtor(&func_name); + zval_ptr_dtor(&args[0]); return ret; } diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index c4846d8541..e88bb91208 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -39,6 +39,13 @@ # define MSG_PEEK 0 #endif +#ifdef PHP_WIN32 +/* send/recv family on windows expects int */ +# define XP_SOCK_BUF_SIZE(sz) (((sz) > INT_MAX) ? INT_MAX : (int)(sz)) +#else +# define XP_SOCK_BUF_SIZE(sz) (sz) +#endif + php_stream_ops php_stream_generic_socket_ops; PHPAPI php_stream_ops php_stream_socket_ops; php_stream_ops php_stream_udp_socket_ops; @@ -48,16 +55,16 @@ php_stream_ops php_stream_unixdg_socket_ops; #endif -static int php_tcp_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC); +static int php_tcp_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam); /* {{{ Generic socket stream operations */ -static size_t php_sockop_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t php_sockop_write(php_stream *stream, const char *buf, size_t count) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; int didwrite; struct timeval *ptimeout; - if (sock->socket == -1) { + if (!sock || sock->socket == -1) { return 0; } @@ -67,13 +74,13 @@ static size_t php_sockop_write(php_stream *stream, const char *buf, size_t count ptimeout = &sock->timeout; retry: - didwrite = send(sock->socket, buf, count, (sock->is_blocked && ptimeout) ? MSG_DONTWAIT : 0); + didwrite = send(sock->socket, buf, XP_SOCK_BUF_SIZE(count), (sock->is_blocked && ptimeout) ? MSG_DONTWAIT : 0); if (didwrite <= 0) { - long err = php_socket_errno(); + int err = php_socket_errno(); char *estr; - if (sock->is_blocked && err == EWOULDBLOCK) { + if (sock->is_blocked && (err == EWOULDBLOCK || err == EAGAIN)) { int retval; sock->timeout_event = 0; @@ -95,13 +102,13 @@ retry: } while (err == EINTR); } estr = php_socket_strerror(err, NULL, 0); - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "send of %ld bytes failed with errno=%ld %s", - (long)count, err, estr); + php_error_docref(NULL, E_NOTICE, "send of " ZEND_LONG_FMT " bytes failed with errno=%ld %s", + (zend_long)count, err, estr); efree(estr); } if (didwrite > 0) { - php_stream_notify_progress_increment(stream->context, didwrite, 0); + php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), didwrite, 0); } if (didwrite < 0) { @@ -111,15 +118,15 @@ retry: return didwrite; } -static void php_sock_stream_wait_for_data(php_stream *stream, php_netstream_data_t *sock TSRMLS_DC) +static void php_sock_stream_wait_for_data(php_stream *stream, php_netstream_data_t *sock) { int retval; struct timeval *ptimeout; - if (sock->socket == -1) { + if (!sock || sock->socket == -1) { return; } - + sock->timeout_event = 0; if (sock->timeout.tv_sec == -1) @@ -141,27 +148,29 @@ static void php_sock_stream_wait_for_data(php_stream *stream, php_netstream_data } } -static size_t php_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_sockop_read(php_stream *stream, char *buf, size_t count) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; - int nr_bytes = 0; + ssize_t nr_bytes = 0; + int err; - if (sock->socket == -1) { + if (!sock || sock->socket == -1) { return 0; } if (sock->is_blocked) { - php_sock_stream_wait_for_data(stream, sock TSRMLS_CC); + php_sock_stream_wait_for_data(stream, sock); if (sock->timeout_event) return 0; } - nr_bytes = recv(sock->socket, buf, count, (sock->is_blocked && sock->timeout.tv_sec != -1) ? MSG_DONTWAIT : 0); + nr_bytes = recv(sock->socket, buf, XP_SOCK_BUF_SIZE(count), (sock->is_blocked && sock->timeout.tv_sec != -1) ? MSG_DONTWAIT : 0); + err = php_socket_errno(); - stream->eof = (nr_bytes == 0 || (nr_bytes == -1 && php_socket_errno() != EWOULDBLOCK)); + stream->eof = (nr_bytes == 0 || (nr_bytes == -1 && err != EWOULDBLOCK && err != EAGAIN)); if (nr_bytes > 0) { - php_stream_notify_progress_increment(stream->context, nr_bytes, 0); + php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), nr_bytes, 0); } if (nr_bytes < 0) { @@ -172,13 +181,17 @@ static size_t php_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS } -static int php_sockop_close(php_stream *stream, int close_handle TSRMLS_DC) +static int php_sockop_close(php_stream *stream, int close_handle) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; #ifdef PHP_WIN32 int n; #endif + if (!sock) { + return 0; + } + if (close_handle) { #ifdef PHP_WIN32 @@ -207,11 +220,11 @@ static int php_sockop_close(php_stream *stream, int close_handle TSRMLS_DC) } pefree(sock, php_stream_is_persistent(stream)); - + return 0; } -static int php_sockop_flush(php_stream *stream TSRMLS_DC) +static int php_sockop_flush(php_stream *stream) { #if 0 php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; @@ -220,32 +233,38 @@ static int php_sockop_flush(php_stream *stream TSRMLS_DC) return 0; } -static int php_sockop_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC) +static int php_sockop_stat(php_stream *stream, php_stream_statbuf *ssb) { - php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; #if ZEND_WIN32 return 0; #else - return fstat(sock->socket, &ssb->sb); + php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + + return zend_fstat(sock->socket, &ssb->sb); #endif } static inline int sock_sendto(php_netstream_data_t *sock, const char *buf, size_t buflen, int flags, struct sockaddr *addr, socklen_t addrlen - TSRMLS_DC) + ) { int ret; if (addr) { - ret = sendto(sock->socket, buf, buflen, flags, addr, addrlen); + ret = sendto(sock->socket, buf, XP_SOCK_BUF_SIZE(buflen), flags, addr, XP_SOCK_BUF_SIZE(addrlen)); + return (ret == SOCK_CONN_ERR) ? -1 : ret; } +#ifdef PHP_WIN32 + return ((ret = send(sock->socket, buf, buflen > INT_MAX ? INT_MAX : (int)buflen, flags)) == SOCK_CONN_ERR) ? -1 : ret; +#else return ((ret = send(sock->socket, buf, buflen, flags)) == SOCK_CONN_ERR) ? -1 : ret; +#endif } static inline int sock_recvfrom(php_netstream_data_t *sock, char *buf, size_t buflen, int flags, - char **textaddr, long *textaddrlen, + zend_string **textaddr, struct sockaddr **addr, socklen_t *addrlen - TSRMLS_DC) + ) { php_sockaddr_storage sa; socklen_t sl = sizeof(sa); @@ -253,24 +272,28 @@ static inline int sock_recvfrom(php_netstream_data_t *sock, char *buf, size_t bu int want_addr = textaddr || addr; if (want_addr) { - ret = recvfrom(sock->socket, buf, buflen, flags, (struct sockaddr*)&sa, &sl); + ret = recvfrom(sock->socket, buf, XP_SOCK_BUF_SIZE(buflen), flags, (struct sockaddr*)&sa, &sl); ret = (ret == SOCK_CONN_ERR) ? -1 : ret; php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl, - textaddr, textaddrlen, addr, addrlen TSRMLS_CC); + textaddr, addr, addrlen); } else { - ret = recv(sock->socket, buf, buflen, flags); + ret = recv(sock->socket, buf, XP_SOCK_BUF_SIZE(buflen), flags); ret = (ret == SOCK_CONN_ERR) ? -1 : ret; } return ret; } -static int php_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +static int php_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam) { int oldmode, flags; php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; php_stream_xport_param *xparam; - + + if (!sock) { + return PHP_STREAM_OPTION_RETURN_NOTIMPL; + } + switch(option) { case PHP_STREAM_OPTION_CHECK_LIVENESS: { @@ -303,16 +326,16 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void ret = recv(sock->socket, &buf, sizeof(buf), MSG_PEEK); err = php_socket_errno(); if (0 == ret || /* the counterpart did properly shutdown*/ - 0 > ret && err != EWOULDBLOCK && err != EAGAIN) { /* there was an unrecoverable error */ + (0 > ret && err != EWOULDBLOCK && err != EAGAIN)) { /* there was an unrecoverable error */ alive = 0; } } return alive ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR; } - + case PHP_STREAM_OPTION_BLOCKING: oldmode = sock->is_blocked; - if (SUCCESS == php_set_sock_blocking(sock->socket, value TSRMLS_CC)) { + if (SUCCESS == php_set_sock_blocking(sock->socket, value)) { sock->is_blocked = value; return oldmode; } @@ -328,7 +351,7 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void add_assoc_bool((zval *)ptrparam, "blocked", sock->is_blocked); add_assoc_bool((zval *)ptrparam, "eof", stream->eof); return PHP_STREAM_OPTION_RETURN_OK; - + case PHP_STREAM_OPTION_XPORT_API: xparam = (php_stream_xport_param *)ptrparam; @@ -340,19 +363,17 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void case STREAM_XPORT_OP_GET_NAME: xparam->outputs.returncode = php_network_get_sock_name(sock->socket, xparam->want_textaddr ? &xparam->outputs.textaddr : NULL, - xparam->want_textaddr ? &xparam->outputs.textaddrlen : NULL, xparam->want_addr ? &xparam->outputs.addr : NULL, xparam->want_addr ? &xparam->outputs.addrlen : NULL - TSRMLS_CC); + ); return PHP_STREAM_OPTION_RETURN_OK; case STREAM_XPORT_OP_GET_PEER_NAME: xparam->outputs.returncode = php_network_get_peer_name(sock->socket, xparam->want_textaddr ? &xparam->outputs.textaddr : NULL, - xparam->want_textaddr ? &xparam->outputs.textaddrlen : NULL, xparam->want_addr ? &xparam->outputs.addr : NULL, xparam->want_addr ? &xparam->outputs.addrlen : NULL - TSRMLS_CC); + ); return PHP_STREAM_OPTION_RETURN_OK; case STREAM_XPORT_OP_SEND: @@ -364,10 +385,10 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void xparam->inputs.buf, xparam->inputs.buflen, flags, xparam->inputs.addr, - xparam->inputs.addrlen TSRMLS_CC); + xparam->inputs.addrlen); if (xparam->outputs.returncode == -1) { char *err = php_socket_strerror(php_socket_errno(), NULL, 0); - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "%s\n", err); efree(err); } @@ -385,10 +406,9 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void xparam->inputs.buf, xparam->inputs.buflen, flags, xparam->want_textaddr ? &xparam->outputs.textaddr : NULL, - xparam->want_textaddr ? &xparam->outputs.textaddrlen : NULL, xparam->want_addr ? &xparam->outputs.addr : NULL, xparam->want_addr ? &xparam->outputs.addrlen : NULL - TSRMLS_CC); + ); return PHP_STREAM_OPTION_RETURN_OK; @@ -409,7 +429,7 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void return PHP_STREAM_OPTION_RETURN_OK; } #endif - + default: return PHP_STREAM_OPTION_RETURN_NOTIMPL; } @@ -419,10 +439,14 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void } } -static int php_sockop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC) +static int php_sockop_cast(php_stream *stream, int castas, void **ret) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; + if (!sock) { + return FAILURE; + } + switch(castas) { case PHP_STREAM_AS_STDIO: if (ret) { @@ -506,7 +530,7 @@ php_stream_ops php_stream_unixdg_socket_ops = { /* network socket operations */ #ifdef AF_UNIX -static inline int parse_unix_address(php_stream_xport_param *xparam, struct sockaddr_un *unix_addr TSRMLS_DC) +static inline int parse_unix_address(php_stream_xport_param *xparam, struct sockaddr_un *unix_addr) { memset(unix_addr, 0, sizeof(*unix_addr)); unix_addr->sun_family = AF_UNIX; @@ -520,7 +544,7 @@ static inline int parse_unix_address(php_stream_xport_param *xparam, struct sock * BUT, to get into this branch of code, the name is too long, * so we don't care. */ xparam->inputs.namelen = sizeof(unix_addr->sun_path) - 1; - php_error_docref(NULL TSRMLS_CC, E_NOTICE, + php_error_docref(NULL, E_NOTICE, "socket path exceeded the maximum allowed length of %lu bytes " "and was truncated", (unsigned long)sizeof(unix_addr->sun_path)); } @@ -531,7 +555,7 @@ static inline int parse_unix_address(php_stream_xport_param *xparam, struct sock } #endif -static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *portno, int get_err, char **err TSRMLS_DC) +static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *portno, int get_err, zend_string **err) { char *colon; char *host = NULL; @@ -544,7 +568,7 @@ static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *po p = memchr(str + 1, ']', str_len - 2); if (!p || *(p + 1) != ':') { if (get_err) { - spprintf(err, 0, "Failed to parse IPv6 address \"%s\"", str); + *err = strpprintf(0, "Failed to parse IPv6 address \"%s\"", str); } return NULL; } @@ -562,7 +586,7 @@ static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *po host = estrndup(str, colon - str); } else { if (get_err) { - spprintf(err, 0, "Failed to parse address \"%s\"", str); + *err = strpprintf(0, "Failed to parse address \"%s\"", str); } return NULL; } @@ -570,16 +594,18 @@ static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *po return host; } -static inline char *parse_ip_address(php_stream_xport_param *xparam, int *portno TSRMLS_DC) +static inline char *parse_ip_address(php_stream_xport_param *xparam, int *portno) { - return parse_ip_address_ex(xparam->inputs.name, xparam->inputs.namelen, portno, xparam->want_errortext, &xparam->outputs.error_text TSRMLS_CC); + return parse_ip_address_ex(xparam->inputs.name, xparam->inputs.namelen, portno, xparam->want_errortext, &xparam->outputs.error_text); } static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t *sock, - php_stream_xport_param *xparam TSRMLS_DC) + php_stream_xport_param *xparam) { char *host = NULL; int portno, err; + long sockopts = STREAM_SOCKOP_NONE; + zval *tmpzval = NULL; #ifdef AF_UNIX if (stream->ops == &php_stream_unix_socket_ops || stream->ops == &php_stream_unixdg_socket_ops) { @@ -589,32 +615,52 @@ static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t * if (sock->socket == SOCK_ERR) { if (xparam->want_errortext) { - spprintf(&xparam->outputs.error_text, 0, "Failed to create unix%s socket %s", + xparam->outputs.error_text = strpprintf(0, "Failed to create unix%s socket %s", stream->ops == &php_stream_unix_socket_ops ? "" : "datagram", strerror(errno)); } return -1; } - parse_unix_address(xparam, &unix_addr TSRMLS_CC); + parse_unix_address(xparam, &unix_addr); return bind(sock->socket, (const struct sockaddr *)&unix_addr, (socklen_t) XtOffsetOf(struct sockaddr_un, sun_path) + xparam->inputs.namelen); } #endif - host = parse_ip_address(xparam, &portno TSRMLS_CC); + host = parse_ip_address(xparam, &portno); if (host == NULL) { return -1; } +#ifdef SO_REUSEPORT + if (PHP_STREAM_CONTEXT(stream) + && (tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "so_reuseport")) != NULL + && zend_is_true(tmpzval) + ) { + sockopts |= STREAM_SOCKOP_SO_REUSEPORT; + } +#endif + +#ifdef SO_BROADCAST + if (stream->ops == &php_stream_udp_socket_ops /* SO_BROADCAST is only applicable for UDP */ + && PHP_STREAM_CONTEXT(stream) + && (tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "so_broadcast")) != NULL + && zend_is_true(tmpzval) + ) { + sockopts |= STREAM_SOCKOP_SO_BROADCAST; + } +#endif + sock->socket = php_network_bind_socket_to_local_addr(host, portno, stream->ops == &php_stream_udp_socket_ops ? SOCK_DGRAM : SOCK_STREAM, + sockopts, xparam->want_errortext ? &xparam->outputs.error_text : NULL, &err - TSRMLS_CC); - + ); + if (host) { efree(host); } @@ -623,13 +669,14 @@ static inline int php_tcp_sockop_bind(php_stream *stream, php_netstream_data_t * } static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_t *sock, - php_stream_xport_param *xparam TSRMLS_DC) + php_stream_xport_param *xparam) { char *host = NULL, *bindto = NULL; int portno, bindport = 0; int err = 0; int ret; - zval **tmpzval = NULL; + zval *tmpzval = NULL; + long sockopts = STREAM_SOCKOP_NONE; #ifdef AF_UNIX if (stream->ops == &php_stream_unix_socket_ops || stream->ops == &php_stream_unixdg_socket_ops) { @@ -639,12 +686,12 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_ if (sock->socket == SOCK_ERR) { if (xparam->want_errortext) { - spprintf(&xparam->outputs.error_text, 0, "Failed to create unix socket"); + xparam->outputs.error_text = strpprintf(0, "Failed to create unix socket"); } return -1; } - parse_unix_address(xparam, &unix_addr TSRMLS_CC); + parse_unix_address(xparam, &unix_addr); ret = php_network_connect_socket(sock->socket, (const struct sockaddr *)&unix_addr, (socklen_t) XtOffsetOf(struct sockaddr_un, sun_path) + xparam->inputs.namelen, @@ -658,27 +705,37 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_ } #endif - host = parse_ip_address(xparam, &portno TSRMLS_CC); + host = parse_ip_address(xparam, &portno); if (host == NULL) { return -1; } - if (stream->context && php_stream_context_get_option(stream->context, "socket", "bindto", &tmpzval) == SUCCESS) { - if (Z_TYPE_PP(tmpzval) != IS_STRING) { + if (PHP_STREAM_CONTEXT(stream) && (tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "bindto")) != NULL) { + if (Z_TYPE_P(tmpzval) != IS_STRING) { if (xparam->want_errortext) { - spprintf(&xparam->outputs.error_text, 0, "local_addr context option is not a string."); + xparam->outputs.error_text = strpprintf(0, "local_addr context option is not a string."); } efree(host); return -1; } - bindto = parse_ip_address_ex(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), &bindport, xparam->want_errortext, &xparam->outputs.error_text TSRMLS_CC); + bindto = parse_ip_address_ex(Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval), &bindport, xparam->want_errortext, &xparam->outputs.error_text); } +#ifdef SO_BROADCAST + if (stream->ops == &php_stream_udp_socket_ops /* SO_BROADCAST is only applicable for UDP */ + && PHP_STREAM_CONTEXT(stream) + && (tmpzval = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "socket", "so_broadcast")) != NULL + && zend_is_true(tmpzval) + ) { + sockopts |= STREAM_SOCKOP_SO_BROADCAST; + } +#endif + /* Note: the test here for php_stream_udp_socket_ops is important, because we * want the default to be TCP sockets so that the openssl extension can * re-use this code. */ - + sock->socket = php_network_connect_socket_to_host(host, portno, stream->ops == &php_stream_udp_socket_ops ? SOCK_DGRAM : SOCK_STREAM, xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC, @@ -686,9 +743,10 @@ static inline int php_tcp_sockop_connect(php_stream *stream, php_netstream_data_ xparam->want_errortext ? &xparam->outputs.error_text : NULL, &err, bindto, - bindport - TSRMLS_CC); - + bindport, + sockopts + ); + ret = sock->socket == -1 ? -1 : 0; xparam->outputs.error_code = err; @@ -707,12 +765,12 @@ out: /* indicates pending connection */ return 1; } - + return ret; } static inline int php_tcp_sockop_accept(php_stream *stream, php_netstream_data_t *sock, - php_stream_xport_param *xparam STREAMS_DC TSRMLS_DC) + php_stream_xport_param *xparam STREAMS_DC) { int clisock; @@ -720,13 +778,12 @@ static inline int php_tcp_sockop_accept(php_stream *stream, php_netstream_data_t clisock = php_network_accept_incoming(sock->socket, xparam->want_textaddr ? &xparam->outputs.textaddr : NULL, - xparam->want_textaddr ? &xparam->outputs.textaddrlen : NULL, xparam->want_addr ? &xparam->outputs.addr : NULL, xparam->want_addr ? &xparam->outputs.addrlen : NULL, xparam->inputs.timeout, xparam->want_errortext ? &xparam->outputs.error_text : NULL, &xparam->outputs.error_code - TSRMLS_CC); + ); if (clisock >= 0) { php_netstream_data_t *clisockdata; @@ -742,18 +799,18 @@ static inline int php_tcp_sockop_accept(php_stream *stream, php_netstream_data_t xparam->outputs.client = php_stream_alloc_rel(stream->ops, clisockdata, NULL, "r+"); if (xparam->outputs.client) { - xparam->outputs.client->context = stream->context; - if (stream->context) { - zend_list_addref(stream->context->rsrc_id); + xparam->outputs.client->ctx = stream->ctx; + if (stream->ctx) { + GC_REFCOUNT(stream->ctx)++; } } } } - + return xparam->outputs.client == NULL ? -1 : 0; } -static int php_tcp_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam TSRMLS_DC) +static int php_tcp_sockop_set_option(php_stream *stream, int option, int value, void *ptrparam) { php_netstream_data_t *sock = (php_netstream_data_t*)stream->abstract; php_stream_xport_param *xparam; @@ -765,23 +822,23 @@ static int php_tcp_sockop_set_option(php_stream *stream, int option, int value, switch(xparam->op) { case STREAM_XPORT_OP_CONNECT: case STREAM_XPORT_OP_CONNECT_ASYNC: - xparam->outputs.returncode = php_tcp_sockop_connect(stream, sock, xparam TSRMLS_CC); + xparam->outputs.returncode = php_tcp_sockop_connect(stream, sock, xparam); return PHP_STREAM_OPTION_RETURN_OK; case STREAM_XPORT_OP_BIND: - xparam->outputs.returncode = php_tcp_sockop_bind(stream, sock, xparam TSRMLS_CC); + xparam->outputs.returncode = php_tcp_sockop_bind(stream, sock, xparam); return PHP_STREAM_OPTION_RETURN_OK; case STREAM_XPORT_OP_ACCEPT: - xparam->outputs.returncode = php_tcp_sockop_accept(stream, sock, xparam STREAMS_CC TSRMLS_CC); + xparam->outputs.returncode = php_tcp_sockop_accept(stream, sock, xparam STREAMS_CC); return PHP_STREAM_OPTION_RETURN_OK; default: /* fall through */ ; } } - return php_sockop_set_option(stream, option, value, ptrparam TSRMLS_CC); + return php_sockop_set_option(stream, option, value, ptrparam); } @@ -789,7 +846,7 @@ PHPAPI php_stream *php_stream_generic_socket_factory(const char *proto, size_t p const char *resourcename, size_t resourcenamelen, const char *persistent_id, int options, int flags, struct timeval *timeout, - php_stream_context *context STREAMS_DC TSRMLS_DC) + php_stream_context *context STREAMS_DC) { php_stream *stream = NULL; php_netstream_data_t *sock; @@ -812,7 +869,7 @@ PHPAPI php_stream *php_stream_generic_socket_factory(const char *proto, size_t p /* should never happen */ return NULL; } - + sock = pemalloc(sizeof(php_netstream_data_t), persistent_id ? 1 : 0); memset(sock, 0, sizeof(php_netstream_data_t)); @@ -823,7 +880,7 @@ PHPAPI php_stream *php_stream_generic_socket_factory(const char *proto, size_t p /* we don't know the socket until we have determined if we are binding or * connecting */ sock->socket = -1; - + stream = php_stream_alloc_rel(ops, sock, persistent_id, "r+"); if (stream == NULL) { diff --git a/main/strlcat.c b/main/strlcat.c index b9d175a313..e52ee39442 100644 --- a/main/strlcat.c +++ b/main/strlcat.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ diff --git a/main/strlcpy.c b/main/strlcpy.c index 3d437754fd..44e29ad39b 100644 --- a/main/strlcpy.c +++ b/main/strlcpy.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ diff --git a/main/win32_internal_function_disabled.h b/main/win32_internal_function_disabled.h deleted file mode 100644 index 89f96edf9e..0000000000 --- a/main/win32_internal_function_disabled.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2015 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Pierre A. Joye <pierre@php.net> | - +----------------------------------------------------------------------+ - */ - -/* $Id$ */ - -/* 5 means the min version is 5 (XP/2000), 6 (2k8/vista), etc. */ - -/* -Windows Server 2008 6.0 -Windows Vista 6.0 - -Verssions below are not supported anymore, php won't even load: -Windows Server 2003 R2 5.2 -Windows Server 2003 5.2 -Windows XP 5.1 -Windows 2000 5.0 -*/ -static const char *function_name_5[] = {NULL}; -const int function_name_cnt_5 = 0; -static const char *function_name_6[] = {"readlink", "symlink", NULL}; -const int function_name_cnt_6 = 2; diff --git a/main/win95nt.h b/main/win95nt.h index 972add4df9..84c3647afc 100644 --- a/main/win95nt.h +++ b/main/win95nt.h @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 5 | + | PHP Version 7 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ @@ -39,9 +39,8 @@ typedef char * caddr_t; #define _IFLNK 0120000 /* symbolic link */ #define S_IFIFO _IFIFO #define S_IFBLK _IFBLK -#define S_IFLNK _IFLNK -#ifndef S_ISREG -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#ifndef S_IFLNK +# define S_IFLNK _IFLNK #endif #define chdir(path) _chdir(path) #define mkdir(a, b) _mkdir(a) @@ -55,7 +54,7 @@ typedef char * caddr_t; typedef unsigned int uint; typedef unsigned long ulong; #if !NSAPI -typedef long pid_t; +typedef int pid_t; #endif /* missing in vc5 math.h */ |