static php_mimepart *alloc_new_child_part(php_mimepart *parentpart, size_t startpos, int inherit) { php_mimepart *child = php_mimepart_alloc(); zval child_z; parentpart->parsedata.lastpart = child; child->parent = parentpart; child->source.kind = parentpart->source.kind; if (parentpart->source.kind != mpNONE) { child->source.zval = parentpart->source.zval; zval_copy_ctor(&child->source.zval); } ZVAL_RES(&child_z, child->rsrc); zend_hash_next_index_insert(&parentpart->children, &child_z); child->startpos = child->endpos = child->bodystart = child->bodyend = startpos; if (inherit) { if (parentpart->content_transfer_encoding) child->content_transfer_encoding = estrdup(parentpart->content_transfer_encoding); if (parentpart->charset) child->charset = estrdup(parentpart->charset); } return child; }
static isc_callback _php_ibase_callback(ibase_event *event, /* {{{ */ unsigned short buffer_size, char *result_buf) { zval *res; /* this function is called asynchronously by the Interbase client library. */ TSRMLS_FETCH_FROM_CTX(event->thread_ctx); /** * The callback function is called when the event is first registered and when the event * is cancelled. I consider this is a bug. By clearing event->callback first and setting * it to -1 later, we make sure nothing happens if no event was actually posted. */ switch (event->state) { unsigned short i; unsigned long occurred_event[15]; zval return_value, args[2]; default: /* == DEAD */ break; case ACTIVE: /* copy the updated results into the result buffer */ memcpy(event->result_buffer, result_buf, buffer_size); res = zend_hash_index_find(&EG(regular_list), event->link_res_id); ZVAL_RES(&args[1], Z_RES_P(res)); /* find out which event occurred */ isc_event_counts(occurred_event, buffer_size, event->event_buffer, event->result_buffer); for (i = 0; i < event->event_count; ++i) { if (occurred_event[i]) { ZVAL_STRING(&args[0], event->events[i]); efree(event->events[i]); break; } } /* call the callback provided by the user */ if (SUCCESS != call_user_function(EG(function_table), NULL, &event->callback, &return_value, 2, args)) { _php_ibase_module_error("Error calling callback %s", Z_STRVAL(event->callback)); break; } if (Z_TYPE(return_value) == IS_FALSE) { event->state = DEAD; break; } case NEW: /* re-register the event */ if (isc_que_events(IB_STATUS, &event->link->handle, &event->event_id, buffer_size, event->event_buffer,(isc_callback)_php_ibase_callback, (void *)event)) { _php_ibase_error(); } event->state = ACTIVE; } return 0; }
/* {{{ callback_fn() OCI TAF callback function, calling userspace function */ sb4 callback_fn(void *svchp, void *envhp, void *fo_ctx, ub4 fo_type, ub4 fo_event) { /* Create zval */ zval retval, params[3]; php_oci_connection *connection = (php_oci_connection*)fo_ctx; /* Default return value */ sb4 returnValue = 0; /* Check if userspace callback function was unregistered */ if (Z_ISUNDEF(connection->taf_callback) || Z_ISNULL(connection->taf_callback)) { return 0; } /* Initialize zval */ ZVAL_RES(¶ms[0], connection->id); ZVAL_LONG(¶ms[1], fo_event); ZVAL_LONG(¶ms[2], fo_type); /* Call user function (if possible) */ if (call_user_function(EG(function_table), NULL, &connection->taf_callback, &retval, 3, params) == FAILURE) { php_error_docref(NULL, E_WARNING, "Unable to call Oracle TAF callback function"); } /* Set return value */ if (Z_TYPE(retval) == IS_LONG) { returnValue = (sb4) Z_LVAL(retval); } /* Setting params[0] to null so ressource isn't destroyed on zval_dtor */ ZVAL_NULL(¶ms[0]); /* Cleanup */ zval_ptr_dtor(&retval); zval_ptr_dtor(¶ms[0]); zval_ptr_dtor(¶ms[1]); zval_ptr_dtor(¶ms[2]); return returnValue; }
static php_stream_filter *user_filter_factory_create(const char *filtername, zval *filterparams, uint8_t persistent) { struct php_user_filter_data *fdat = NULL; php_stream_filter *filter; zval obj, zfilter; zval func_name; zval retval; size_t len; /* some sanity checks */ if (persistent) { php_error_docref(NULL, E_WARNING, "cannot use a user-space filter with a persistent stream"); return NULL; } len = strlen(filtername); /* determine the classname/class entry */ if (NULL == (fdat = zend_hash_str_find_ptr(BG(user_filter_map), (char*)filtername, len))) { char *period; /* Userspace Filters using ambiguous wildcards could cause problems. i.e.: myfilter.foo.bar will always call into myfilter.foo.* never seeing myfilter.* TODO: Allow failed userfilter creations to continue scanning through the list */ if ((period = strrchr(filtername, '.'))) { char *wildcard = safe_emalloc(len, 1, 3); /* Search for wildcard matches instead */ memcpy(wildcard, filtername, len + 1); /* copy \0 */ period = wildcard + (period - filtername); while (period) { *period = '\0'; strncat(wildcard, ".*", 2); if (NULL != (fdat = zend_hash_str_find_ptr(BG(user_filter_map), wildcard, strlen(wildcard)))) { period = NULL; } else { *period = '\0'; period = strrchr(wildcard, '.'); } } efree(wildcard); } if (fdat == NULL) { php_error_docref(NULL, E_WARNING, "Err, filter \"%s\" is not in the user-filter map, but somehow the user-filter-factory was invoked for it!?", filtername); return NULL; } } /* bind the classname to the actual class */ if (fdat->ce == NULL) { if (NULL == (fdat->ce = zend_lookup_class(fdat->classname))) { php_error_docref(NULL, E_WARNING, "user-filter \"%s\" requires class \"%s\", but that class is not defined", filtername, ZSTR_VAL(fdat->classname)); return NULL; } } filter = php_stream_filter_alloc(&userfilter_ops, NULL, 0); if (filter == NULL) { return NULL; } /* create the object */ object_init_ex(&obj, fdat->ce); /* filtername */ add_property_string(&obj, "filtername", (char*)filtername); /* and the parameters, if any */ if (filterparams) { add_property_zval(&obj, "params", filterparams); } else { add_property_null(&obj, "params"); } /* invoke the constructor */ ZVAL_STRINGL(&func_name, "oncreate", sizeof("oncreate")-1); call_user_function_ex(NULL, &obj, &func_name, &retval, 0, NULL, 0, NULL); if (Z_TYPE(retval) != IS_UNDEF) { if (Z_TYPE(retval) == IS_FALSE) { /* User reported filter creation error "return false;" */ zval_ptr_dtor(&retval); /* Kill the filter (safely) */ ZVAL_UNDEF(&filter->abstract); php_stream_filter_free(filter); /* Kill the object */ zval_ptr_dtor(&obj); /* Report failure to filter_alloc */ return NULL; } zval_ptr_dtor(&retval); } zval_ptr_dtor(&func_name); /* set the filter property, this will be used during cleanup */ ZVAL_RES(&zfilter, zend_register_resource(filter, le_userfilters)); ZVAL_COPY_VALUE(&filter->abstract, &obj); add_property_zval(&obj, "filter", &zfilter); /* add_property_zval increments the refcount which is unwanted here */ zval_ptr_dtor(&zfilter); return filter; }
php_stream_filter_status_t userfilter_filter( php_stream *stream, php_stream_filter *thisfilter, php_stream_bucket_brigade *buckets_in, php_stream_bucket_brigade *buckets_out, size_t *bytes_consumed, int flags ) { int ret = PSFS_ERR_FATAL; zval *obj = &thisfilter->abstract; zval func_name; zval retval; zval args[4]; zval zpropname; int call_result; /* the userfilter object probably doesn't exist anymore */ if (CG(unclean_shutdown)) { return ret; } if (!zend_hash_str_exists(Z_OBJPROP_P(obj), "stream", sizeof("stream")-1)) { zval tmp; /* Give the userfilter class a hook back to the stream */ php_stream_to_zval(stream, &tmp); zval_copy_ctor(&tmp); add_property_zval(obj, "stream", &tmp); /* add_property_zval increments the refcount which is unwanted here */ zval_ptr_dtor(&tmp); } ZVAL_STRINGL(&func_name, "filter", sizeof("filter")-1); /* Setup calling arguments */ ZVAL_RES(&args[0], zend_register_resource(buckets_in, le_bucket_brigade)); ZVAL_RES(&args[1], zend_register_resource(buckets_out, le_bucket_brigade)); if (bytes_consumed) { ZVAL_LONG(&args[2], *bytes_consumed); } else { ZVAL_NULL(&args[2]); } ZVAL_BOOL(&args[3], flags & PSFS_FLAG_FLUSH_CLOSE); call_result = call_user_function_ex(NULL, obj, &func_name, &retval, 4, args, 0, NULL); zval_ptr_dtor(&func_name); if (call_result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { convert_to_long(&retval); ret = (int)Z_LVAL(retval); } else if (call_result == FAILURE) { php_error_docref(NULL, E_WARNING, "failed to call filter function"); } if (bytes_consumed) { *bytes_consumed = zval_get_long(&args[2]); } if (buckets_in->head) { php_stream_bucket *bucket = buckets_in->head; php_error_docref(NULL, E_WARNING, "Unprocessed filter buckets remaining on input brigade"); while ((bucket = buckets_in->head)) { /* Remove unconsumed buckets from the brigade */ php_stream_bucket_unlink(bucket); php_stream_bucket_delref(bucket); } } if (ret != PSFS_PASS_ON) { php_stream_bucket *bucket = buckets_out->head; while (bucket != NULL) { php_stream_bucket_unlink(bucket); php_stream_bucket_delref(bucket); bucket = buckets_out->head; } } /* filter resources are cleaned up by the stream destructor, * keeping a reference to the stream resource here would prevent it * from being destroyed properly */ ZVAL_STRINGL(&zpropname, "stream", sizeof("stream")-1); Z_OBJ_HANDLER_P(obj, unset_property)(obj, &zpropname, NULL); zval_ptr_dtor(&zpropname); zval_ptr_dtor(&args[3]); zval_ptr_dtor(&args[2]); zval_ptr_dtor(&args[1]); zval_ptr_dtor(&args[0]); return ret; }
static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_headers, struct curl_pushheaders *push_headers, void *userp) /* {{{ */ { php_curl *ch; php_curl *parent; php_curlm *mh = (php_curlm *)userp; size_t rval = CURL_PUSH_DENY; php_curlm_server_push *t = mh->handlers->server_push; zval *pz_parent_ch = NULL; zval pz_ch; zval headers; zval retval; zend_resource *res; char *header; int error; zend_fcall_info fci = empty_fcall_info; pz_parent_ch = _php_curl_multi_find_easy_handle(mh, parent_ch); if (pz_parent_ch == NULL) { return rval; } parent = (php_curl*)zend_fetch_resource(Z_RES_P(pz_parent_ch), le_curl_name, le_curl); ch = alloc_curl_handle(); ch->cp = easy; _php_setup_easy_copy_handlers(ch, parent); Z_ADDREF_P(pz_parent_ch); res = zend_register_resource(ch, le_curl); ZVAL_RES(&pz_ch, res); size_t i; array_init(&headers); for(i=0; i<num_headers; i++) { header = curl_pushheader_bynum(push_headers, i); add_next_index_string(&headers, header); } zend_fcall_info_init(&t->func_name, 0, &fci, &t->fci_cache, NULL, NULL); zend_fcall_info_argn( &fci, 3, pz_parent_ch, &pz_ch, &headers ); fci.retval = &retval; error = zend_call_function(&fci, &t->fci_cache); zend_fcall_info_args_clear(&fci, 1); zval_dtor(&headers); if (error == FAILURE) { php_error_docref(NULL, E_WARNING, "Cannot call the CURLMOPT_PUSHFUNCTION"); } else if (!Z_ISUNDEF(retval)) { if (CURL_PUSH_DENY != zval_get_long(&retval)) { rval = CURL_PUSH_OK; /* we want to create a copy of this zval that we store in the multihandle structure element "easyh" */ zval tmp_val; ZVAL_DUP(&tmp_val, &pz_ch); zend_llist_add_element(&mh->easyh, &tmp_val); } else { /* libcurl will free this easy handle, avoid double free */ ch->cp = NULL; } } return rval; }