/** * Construct an instance of the Channel class. If the $args array contains a * "credentials" key mapping to a ChannelCredentials object, a secure channel * will be created with those credentials. * @param string $target The hostname to associate with this channel * @param array $args The arguments to pass to the Channel (optional) */ PHP_METHOD(Channel, __construct) { wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); zend_string *target; zval *args_array = NULL; grpc_channel_args args; HashTable *array_hash; zval *creds_obj = NULL; wrapped_grpc_channel_credentials *creds = NULL; /* "Sa" == 1 string, 1 array */ #ifndef FAST_ZPP if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sa", &target, &args_array) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, "Channel expects a string and an array", 1); return; } #else ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STR(target) Z_PARAM_ARRAY(args_array) ZEND_PARSE_PARAMETERS_END(); #endif array_hash = HASH_OF(args_array); if ((creds_obj = zend_hash_str_find(array_hash, "credentials", sizeof("credentials") - 1)) != NULL) { if (Z_TYPE_P(creds_obj) == IS_NULL) { creds = NULL; zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1); } else if (Z_OBJ_P(creds_obj)->ce != grpc_ce_channel_credentials) { zend_throw_exception(spl_ce_InvalidArgumentException, "credentials must be a ChannelCredentials object", 1); return; } else { creds = Z_WRAPPED_GRPC_CHANNEL_CREDS_P(creds_obj); zend_hash_str_del(array_hash, "credentials", sizeof("credentials") - 1); } } php_grpc_read_args_array(args_array, &args); if (creds == NULL) { channel->wrapped = grpc_insecure_channel_create(ZSTR_VAL(target), &args, NULL); } else { channel->wrapped = grpc_secure_channel_create(creds->wrapped, ZSTR_VAL(target), &args, NULL); } efree(args.args); }
PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver) /* {{{ */ { if (!zend_hash_str_exists(&module_registry, "pdo", sizeof("pdo") - 1)) { return; } zend_hash_str_del(&pdo_driver_hash, (char*)driver->driver_name, driver->driver_name_len); }
SAPI_API void sapi_unregister_post_entry(sapi_post_entry *post_entry) { if (SG(sapi_started) && EG(current_execute_data)) { return; } zend_hash_str_del(&SG(known_post_content_types), post_entry->content_type, post_entry->content_type_len); }
/* Upgly hack to fix HTTP_PROXY issue, see bug #72573 */ static void check_http_proxy(HashTable *var_table) { if (zend_hash_str_exists(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")-1)) { char *local_proxy = getenv("HTTP_PROXY"); if (!local_proxy) { zend_hash_str_del(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")-1); } else { zval local_zval; ZVAL_STRING(&local_zval, local_proxy); zend_hash_str_update(var_table, "HTTP_PROXY", sizeof("HTTP_PROXY")-1, &local_zval); } } }
static void on_broken_connection_detected(php_yrmcds_t* conn, yrmcds_error err, yrmcds_status status) { if( err != YRMCDS_OK ) PRINT_YRMCDS_ERROR(err); if( status != YRMCDS_STATUS_OK && status != YRMCDS_STATUS_UNKNOWNCOMMAND ) { char buf[256]; snprintf(buf, sizeof(buf), "yrmcds: unexpected response (%d)", status); php_log_err(buf); } php_log_err("yrmcds: broken persistent connection"); if( conn->reference_count == 0 ) { // Since `conn` is the last user of this persistent connection, // we should clean up resources. zend_hash_str_del(&EG(persistent_list), conn->pkey, conn->pkey_len); } }
static int timecop_class_override_clear() { const struct timecop_override_class_entry *p; zend_class_entry *ce_orig; zend_function *zf_orig, *zf_ovrd, *zf_save; p = &(timecop_override_class_table[0]); while (p->orig_class != NULL) { ce_orig = zend_hash_str_find_ptr(EG(class_table), p->orig_class, strlen(p->orig_class)); if (ce_orig == NULL) { php_error_docref("https://github.com/hnw/php-timecop", E_WARNING, "timecop couldn't find class %s.", p->orig_class); p++; continue; } zf_orig = zend_hash_str_find_ptr(&ce_orig->function_table, p->save_method, strlen(p->save_method)); if (zf_orig == NULL) { php_error_docref("https://github.com/hnw/php-timecop", E_WARNING, "timecop couldn't find method %s::%s.", p->orig_class, p->save_method); p++; continue; } zend_hash_str_update_mem(&ce_orig->function_table, p->orig_method, strlen(p->orig_method), zf_orig, sizeof(zend_internal_function)); function_add_ref(zf_orig); zend_hash_str_del(&ce_orig->function_table, p->save_method, strlen(p->save_method)); if (strcmp(p->orig_method, "__construct") == 0) { ce_orig->constructor = zf_orig; } p++; } return SUCCESS; }
/* clear overrideed function. */ static int timecop_func_override_clear() { const struct timecop_override_func_entry *p; zend_function *zf_orig; p = &(timecop_override_func_table[0]); while (p->orig_func != NULL) { zf_orig = zend_hash_str_find_ptr(EG(function_table), p->save_func, strlen(p->save_func)); if (zf_orig == NULL) { p++; continue; } zend_hash_str_update_mem(EG(function_table), p->orig_func, strlen(p->orig_func), zf_orig, sizeof(zend_internal_function)); function_add_ref(zf_orig); zend_hash_str_del(EG(function_table), p->save_func, strlen(p->save_func)); p++; } return SUCCESS; }
/* {{{ mysqlnd_vio::open_tcp_or_unix */ static php_stream * MYSQLND_METHOD(mysqlnd_vio, open_tcp_or_unix)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) { #if PHP_API_VERSION < 20100412 unsigned int streams_options = ENFORCE_SAFE_MODE; #else unsigned int streams_options = 0; #endif unsigned int streams_flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT; char * hashed_details = NULL; int hashed_details_len = 0; zend_string *errstr = NULL; int errcode = 0; struct timeval tv; dtor_func_t origin_dtor; php_stream * net_stream = NULL; DBG_ENTER("mysqlnd_vio::open_tcp_or_unix"); vio->data->stream = NULL; if (persistent) { hashed_details_len = mnd_sprintf(&hashed_details, 0, "%p", vio); DBG_INF_FMT("hashed_details=%s", hashed_details); } if (vio->data->options.timeout_connect) { tv.tv_sec = vio->data->options.timeout_connect; tv.tv_usec = 0; } DBG_INF_FMT("calling php_stream_xport_create"); net_stream = php_stream_xport_create(scheme.s, scheme.l, streams_options, streams_flags, hashed_details, (vio->data->options.timeout_connect) ? &tv : NULL, NULL /*ctx*/, &errstr, &errcode); if (errstr || !net_stream) { DBG_ERR("Error"); if (hashed_details) { mnd_sprintf_free(hashed_details); } errcode = CR_CONNECTION_ERROR; SET_CLIENT_ERROR(error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, errstr? ZSTR_VAL(errstr):"Unknown error while connecting"); if (errstr) { zend_string_release(errstr); } DBG_RETURN(NULL); } if (hashed_details) { /* If persistent, the streams register it in EG(persistent_list). This is unwanted. ext/mysql or ext/mysqli are responsible to clean, whatever they have to. */ zend_resource *le; if ((le = zend_hash_str_find_ptr(&EG(persistent_list), hashed_details, hashed_details_len))) { origin_dtor = EG(persistent_list).pDestructor; /* in_free will let streams code skip destructing - big HACK, but STREAMS suck big time regarding persistent streams. Just not compatible for extensions that need persistency. */ EG(persistent_list).pDestructor = NULL; zend_hash_str_del(&EG(persistent_list), hashed_details, hashed_details_len); EG(persistent_list).pDestructor = origin_dtor; pefree(le, 1); } #if ZEND_DEBUG /* Shut-up the streams, they don't know what they are doing */ net_stream->__exposed = 1; #endif mnd_sprintf_free(hashed_details); } /* Streams are not meant for C extensions! Thus we need a hack. Every connected stream will be registered as resource (in EG(regular_list). So far, so good. However, it won't be unregistered until the script ends. So, we need to take care of that. */ origin_dtor = EG(regular_list).pDestructor; EG(regular_list).pDestructor = NULL; zend_hash_index_del(&EG(regular_list), net_stream->res->handle); /* ToDO: should it be res->handle, do streams register with addref ?*/ efree(net_stream->res); net_stream->res = NULL; EG(regular_list).pDestructor = origin_dtor; DBG_RETURN(net_stream); }
php_http_message_parser_state_t php_http_message_parser_parse(php_http_message_parser_t *parser, php_http_buffer_t *buffer, unsigned flags, php_http_message_t **message) { char *str = NULL; size_t len = 0; size_t cut = 0; while (buffer->used || !php_http_message_parser_states[php_http_message_parser_state_is(parser)].need_data) { #if DBG_PARSER fprintf(stderr, "#MP: %s (f: %u, t:%d, l:%zu)\n", php_http_message_parser_state_name(php_http_message_parser_state_is(parser)), flags, message && *message ? (*message)->type : -1, buffer->used ); _dpf(0, buffer->data, buffer->used); #endif switch (php_http_message_parser_state_pop(parser)) { case PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE: return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE); case PHP_HTTP_MESSAGE_PARSER_STATE_START: { char *ptr = buffer->data; while (ptr - buffer->data < buffer->used && PHP_HTTP_IS_CTYPE(space, *ptr)) { ++ptr; } php_http_buffer_cut(buffer, 0, ptr - buffer->data); if (buffer->used) { php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER); } break; } case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER: { unsigned header_parser_flags = (flags & PHP_HTTP_MESSAGE_PARSER_CLEANUP) ? PHP_HTTP_HEADER_PARSER_CLEANUP : 0; switch (php_http_header_parser_parse(&parser->header, buffer, header_parser_flags, *message ? &(*message)->hdrs : NULL, (php_http_info_callback_t) php_http_message_info_callback, message)) { case PHP_HTTP_HEADER_PARSER_STATE_FAILURE: return PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE; case PHP_HTTP_HEADER_PARSER_STATE_DONE: php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE); break; default: if (buffer->used || !(flags & PHP_HTTP_MESSAGE_PARSER_CLEANUP)) { return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER); } else { php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE); } } break; } case PHP_HTTP_MESSAGE_PARSER_STATE_HEADER_DONE: { zval h, *h_ptr, *h_loc = NULL, *h_con = NULL, *h_ce; zend_bool chunked = 0; zend_long content_length = -1; zend_string *content_range = NULL; /* Content-Range has higher precedence than Content-Length, * and content-length denotes the original length of the entity, * so let's *NOT* remove CR/CL, because that would fundamentally * change the meaning of the whole message */ if ((h_ptr = php_http_message_header(*message, ZEND_STRL("Transfer-Encoding")))) { zend_string *zs = zval_get_string(h_ptr); chunked = zend_string_equals_literal(zs, "chunked"); zend_string_release(zs); Z_TRY_ADDREF_P(h_ptr); zend_hash_str_update(&(*message)->hdrs, "X-Original-Transfer-Encoding", lenof("X-Original-Transfer-Encoding"), h_ptr); zend_hash_str_del(&(*message)->hdrs, "Transfer-Encoding", lenof("Transfer-Encoding")); /* reset */ ZVAL_LONG(&h, 0); zend_hash_str_update(&(*message)->hdrs, "Content-Length", lenof("Content-Length"), &h); } else if ((h_ptr = php_http_message_header(*message, ZEND_STRL("Content-Length")))) { content_length = zval_get_long(h_ptr); Z_TRY_ADDREF_P(h_ptr); zend_hash_str_update(&(*message)->hdrs, "X-Original-Content-Length", lenof("X-Original-Content-Length"), h_ptr); } if ((content_range = php_http_message_header_string(*message, ZEND_STRL("Content-Range")))) { ZVAL_STR_COPY(&h, content_range); zend_hash_str_update(&(*message)->hdrs, "Content-Range", lenof("Content-Range"), &h); } /* so, if curl sees a 3xx code, a Location header and a Connection:close header * it decides not to read the response body. */ if ((flags & PHP_HTTP_MESSAGE_PARSER_EMPTY_REDIRECTS) && (*message)->type == PHP_HTTP_RESPONSE && (*message)->http.info.response.code/100 == 3 && (h_loc = php_http_message_header(*message, ZEND_STRL("Location"))) && (h_con = php_http_message_header(*message, ZEND_STRL("Connection"))) ) { zend_string *con = zval_get_string(h_con); if (php_http_match(con->val, "close", PHP_HTTP_MATCH_WORD)) { zend_string_release(con); php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE); break; } zend_string_release(con); } if ((h_ce = php_http_message_header(*message, ZEND_STRL("Content-Encoding")))) { zend_string *ce = zval_get_string(h_ce); if (php_http_match(ce->val, "gzip", PHP_HTTP_MATCH_WORD) || php_http_match(ce->val, "x-gzip", PHP_HTTP_MATCH_WORD) || php_http_match(ce->val, "deflate", PHP_HTTP_MATCH_WORD) ) { if (parser->inflate) { php_http_encoding_stream_reset(&parser->inflate); } else { parser->inflate = php_http_encoding_stream_init(NULL, php_http_encoding_stream_get_inflate_ops(), 0); } Z_TRY_ADDREF_P(h_ce); zend_hash_str_update(&(*message)->hdrs, "X-Original-Content-Encoding", lenof("X-Original-Content-Encoding"), h_ce); zend_hash_str_del(&(*message)->hdrs, "Content-Encoding", lenof("Content-Encoding")); } zend_string_release(ce); } if ((flags & PHP_HTTP_MESSAGE_PARSER_DUMB_BODIES)) { php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB); } else { if (chunked) { parser->dechunk = php_http_encoding_stream_init(parser->dechunk, php_http_encoding_stream_get_dechunk_ops(), 0); php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED); break; } if (content_range) { ulong total = 0, start = 0, end = 0; if (!strncasecmp(content_range->val, "bytes", lenof("bytes")) && ( content_range->val[lenof("bytes")] == ':' || content_range->val[lenof("bytes")] == ' ' || content_range->val[lenof("bytes")] == '=' ) ) { char *total_at = NULL, *end_at = NULL; char *start_at = content_range->val + sizeof("bytes"); start = strtoul(start_at, &end_at, 10); if (end_at) { end = strtoul(end_at + 1, &total_at, 10); if (total_at && strncmp(total_at + 1, "*", 1)) { total = strtoul(total_at + 1, NULL, 10); } if (end >= start && (!total || end <= total)) { parser->body_length = end + 1 - start; php_http_message_parser_state_push(parser, 1, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH); zend_string_release(content_range); break; } } } zend_string_release(content_range); } if (content_length >= 0) { parser->body_length = content_length; php_http_message_parser_state_push(parser, 1, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH); break; } if ((*message)->type == PHP_HTTP_REQUEST) { php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE); } else { php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB); } } break; } case PHP_HTTP_MESSAGE_PARSER_STATE_BODY: { if (len) { if (parser->inflate) { char *dec_str = NULL; size_t dec_len; if (SUCCESS != php_http_encoding_stream_update(parser->inflate, str, len, &dec_str, &dec_len)) { return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE); } if (str != buffer->data) { PTR_FREE(str); } str = dec_str; len = dec_len; } php_stream_write(php_http_message_body_stream((*message)->body), str, len); } if (cut) { php_http_buffer_cut(buffer, 0, cut); } if (str != buffer->data) { PTR_FREE(str); } str = NULL; len = 0; cut = 0; break; } case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DUMB: { str = buffer->data; len = buffer->used; cut = len; php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE, PHP_HTTP_MESSAGE_PARSER_STATE_BODY); break; } case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH: { len = MIN(parser->body_length, buffer->used); str = buffer->data; cut = len; parser->body_length -= len; php_http_message_parser_state_push(parser, 2, !parser->body_length?PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE:PHP_HTTP_MESSAGE_PARSER_STATE_BODY_LENGTH, PHP_HTTP_MESSAGE_PARSER_STATE_BODY); break; } case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED: { /* * - pass available data through the dechunk stream * - pass decoded data along * - if stream zeroed: * Y: - cut processed string out of buffer, but leave length of unprocessed dechunk stream data untouched * - body done * N: - parse ahaed */ char *dec_str = NULL; size_t dec_len; if (SUCCESS != php_http_encoding_stream_update(parser->dechunk, buffer->data, buffer->used, &dec_str, &dec_len)) { return PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE; } str = dec_str; len = dec_len; if (php_http_encoding_stream_done(parser->dechunk)) { cut = buffer->used - PHP_HTTP_BUFFER(parser->dechunk->ctx)->used; php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE, PHP_HTTP_MESSAGE_PARSER_STATE_BODY); } else { cut = buffer->used; php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_BODY_CHUNKED, PHP_HTTP_MESSAGE_PARSER_STATE_BODY); } break; } case PHP_HTTP_MESSAGE_PARSER_STATE_BODY_DONE: { php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_DONE); if (parser->dechunk && parser->dechunk->ctx) { char *dec_str = NULL; size_t dec_len; if (SUCCESS != php_http_encoding_stream_finish(parser->dechunk, &dec_str, &dec_len)) { return php_http_message_parser_state_push(parser, 1, PHP_HTTP_MESSAGE_PARSER_STATE_FAILURE); } php_http_encoding_stream_dtor(parser->dechunk); if (dec_str && dec_len) { str = dec_str; len = dec_len; cut = 0; php_http_message_parser_state_push(parser, 2, PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL, PHP_HTTP_MESSAGE_PARSER_STATE_BODY); } } break; } case PHP_HTTP_MESSAGE_PARSER_STATE_UPDATE_CL: { zval zcl; ZVAL_LONG(&zcl, php_http_message_body_size((*message)->body)); zend_hash_str_update(&(*message)->hdrs, "Content-Length", lenof("Content-Length"), &zcl); break; } case PHP_HTTP_MESSAGE_PARSER_STATE_DONE: { char *ptr = buffer->data; while (ptr - buffer->data < buffer->used && PHP_HTTP_IS_CTYPE(space, *ptr)) { ++ptr; } php_http_buffer_cut(buffer, 0, ptr - buffer->data); if (!(flags & PHP_HTTP_MESSAGE_PARSER_GREEDY)) { return PHP_HTTP_MESSAGE_PARSER_STATE_DONE; } break; } } } return php_http_message_parser_state_is(parser); }
PHPAPI int php_stream_xport_unregister(const char *protocol) { return zend_hash_str_del(&xport_hash, protocol, strlen(protocol)); }
PHPAPI int php_stream_filter_unregister_factory(const char *filterpattern) { return zend_hash_str_del(&stream_filters_hash, filterpattern, strlen(filterpattern)); }