/* {{{ proto array SplDoublyLinkedList::__serialize() */ SPL_METHOD(SplDoublyLinkedList, __serialize) { spl_dllist_object *intern = Z_SPLDLLIST_P(ZEND_THIS); spl_ptr_llist_element *current = intern->llist->head; zval tmp; if (zend_parse_parameters_none_throw() == FAILURE) { return; } array_init(return_value); /* flags */ ZVAL_LONG(&tmp, intern->flags); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); /* elements */ array_init_size(&tmp, intern->llist->count); while (current) { zend_hash_next_index_insert(Z_ARRVAL(tmp), ¤t->data); current = current->next; } zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); /* members */ ZVAL_ARR(&tmp, zend_std_get_properties(&intern->std)); Z_TRY_ADDREF(tmp); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp); } /* }}} */
static void php_jq_filter(zval **return_value, jq_state *jq, jv json, int flags TSRMLS_DC) { jv result; jq_start(jq, jv_copy(json), 0); if (jv_is_valid(result = jq_next(jq))) { int multiple = 0; while (1) { zval *zv; ALLOC_INIT_ZVAL(zv); if (flags == JQ_OPT_RAW) { if (jv_get_kind(result) == JV_KIND_STRING) { ZVAL_STRING(zv, jv_string_value(result), 1); } else { jv dump = jv_dump_string(result, 0); if (jv_is_valid(dump)) { ZVAL_STRING(zv, jv_string_value(dump), 1); } jv_free(dump); } } else { php_jv_dump(&zv, result TSRMLS_CC); } if (!jv_is_valid(result = jq_next(jq))) { if (multiple) { zend_hash_next_index_insert(Z_ARRVAL_PP(return_value), &zv, sizeof(zv), NULL); } else { ZVAL_ZVAL(*return_value, zv, 1, 1); } break; } if (!multiple) { multiple = 1; array_init(*return_value); } zend_hash_next_index_insert(Z_ARRVAL_PP(return_value), &zv, sizeof(zv), NULL); } } else { jv_free(result); if (PHP_JQ_G(display_errors)) { PHP_JQ_ERR(E_WARNING, "filter parse error"); } ZVAL_BOOL(*return_value, 0); } }
int static edge_register_autoload(zval *loader, const char *fname) { zval *z_function; zval *arg; zval **args[1] = {&arg}; zval *method; zval *ret = NULL; MAKE_STD_ZVAL(z_function); ZVAL_STRING(z_function, "spl_autoload_register", 0); MAKE_STD_ZVAL(method); ZVAL_STRING(method, fname, 1); MAKE_STD_ZVAL(arg); array_init(arg); zend_hash_next_index_insert(Z_ARRVAL_P(arg), &loader, sizeof(zval *), NULL); zend_hash_next_index_insert(Z_ARRVAL_P(arg), &method, sizeof(zval *), NULL); zend_fcall_info fci = { sizeof(fci), EG(function_table), z_function, NULL, &ret, 1, (zval ***)args, NULL, 1 }; if(zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) { if(ret) { zval_ptr_dtor(&ret); } zval_ptr_dtor(&z_function); zval_ptr_dtor(&arg); return 0; } if(ret) { zval_ptr_dtor(&ret); } Z_ADDREF_P(loader); efree(z_function); zval_ptr_dtor(&arg); return 1; }
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 PHP_METHOD(midgard_workspace_storage, list_children) { if (zend_parse_parameters_none() == FAILURE) return; guint n_objects; MidgardWorkspaceStorage *self = MIDGARD_WORKSPACE_STORAGE(__php_gobject_ptr(getThis())); MidgardWorkspaceStorage **children = midgard_workspace_storage_list_children(self, &n_objects); array_init(return_value); if (!children) return; const char *g_class_name = G_OBJECT_TYPE_NAME(children[0]); zend_class_entry *ce = zend_fetch_class((char *) g_class_name, strlen(g_class_name), ZEND_FETCH_CLASS_AUTO TSRMLS_CC); int i; for (i = 0; i < n_objects; i++) { zval *zobject; MAKE_STD_ZVAL(zobject); php_midgard_gobject_new_with_gobject(zobject, ce, G_OBJECT(children[i]), TRUE TSRMLS_CC); zend_hash_next_index_insert(HASH_OF(return_value), &zobject, sizeof(zval *), NULL); } }
/* {{{ pip_sequence_to_hash(PyObject *seq) * Convert a Python sequence to a PHP hash */ zval * pip_sequence_to_hash(PyObject *seq) { zval *hash, *val; PyObject *item; int i = 0; /* Make sure this object implements the sequence protocol */ if (!PySequence_Check(seq)) { return NULL; } /* Initialize our PHP array */ MAKE_STD_ZVAL(hash); if (array_init(hash) != SUCCESS) { return NULL; } /* Iterate over the items in the sequence */ while (item = PySequence_GetItem(seq, i++)) { val = pip_pyobject_to_zval(item); if (zend_hash_next_index_insert(HASH_OF(hash), (void *)&val, sizeof(zval *), NULL) == FAILURE) { php_error(E_ERROR, "Python: Array conversion error"); } Py_DECREF(item); } return hash; }
static void ast_create_virtual_node( zval *zv, zend_ast_kind kind, zend_ast *ast, zend_long version) { zval tmp_zv, tmp_zv2; object_init_ex(zv, ast_node_ce); ZVAL_LONG(&tmp_zv, kind); ast_update_property(zv, AST_STR(kind), &tmp_zv, AST_CACHE_SLOT_KIND); ZVAL_LONG(&tmp_zv, ast->attr); ast_update_property(zv, AST_STR(flags), &tmp_zv, AST_CACHE_SLOT_FLAGS); ZVAL_LONG(&tmp_zv, zend_ast_get_lineno(ast)); ast_update_property(zv, AST_STR(lineno), &tmp_zv, AST_CACHE_SLOT_LINENO); array_init(&tmp_zv); ast_update_property(zv, AST_STR(children), &tmp_zv, AST_CACHE_SLOT_CHILDREN); ZVAL_COPY(&tmp_zv2, zend_ast_get_zval(ast)); if (version >= 30) { zend_hash_add_new(Z_ARRVAL(tmp_zv), ast_kind_child_name(kind, 0), &tmp_zv2); } else { zend_hash_next_index_insert(Z_ARRVAL(tmp_zv), &tmp_zv2); } }
BUESSION_API int buession_hash_next_index_add_double(HashTable *ht, double d TSRMLS_DC){ zval *value; MAKE_STD_ZVAL(value); ZVAL_DOUBLE(value, d); return zend_hash_next_index_insert(ht, (void *) &value, sizeof(zval *), NULL); }
BUESSION_API int buession_hash_next_index_add_long(HashTable *ht, long l TSRMLS_DC){ zval *value; MAKE_STD_ZVAL(value); ZVAL_LONG(value, l); return zend_hash_next_index_insert(ht, (void *) &value, sizeof(zval *), NULL); }
int yaf_loader_register(yaf_loader_t *loader) /* {{{ */ { zval autoload, function, method, ret; array_init(&autoload); ZVAL_STRING(&method, YAF_AUTOLOAD_FUNC_NAME); zend_hash_next_index_insert(Z_ARRVAL(autoload), loader); zend_hash_next_index_insert(Z_ARRVAL(autoload), &method); ZVAL_STRING(&function, YAF_SPL_AUTOLOAD_REGISTER_NAME); do { zend_fcall_info fci = { sizeof(fci), #if PHP_VERSION_ID < 70100 EG(function_table), #endif function, #if PHP_VERSION_ID < 70100 NULL, #endif &ret, &autoload, NULL, 1, 1 }; if (zend_call_function(&fci, NULL) == FAILURE) { zval_ptr_dtor(&function); zval_ptr_dtor(&autoload); php_error_docref(NULL, E_WARNING, "Unable to register autoload function %s", YAF_AUTOLOAD_FUNC_NAME); return 0; } zval_ptr_dtor(&function); zval_ptr_dtor(&autoload); } while (0); return 1; }
/** * Updates an array property */ int zephir_update_property_array(zval *object, const char *property, zend_uint property_length, const zval *index, zval *value) { zval tmp; int separated = 0; if (Z_TYPE_P(object) == IS_OBJECT) { zephir_read_property(&tmp, object, property, property_length, PH_NOISY | PH_READONLY); /** Separation only when refcount > 1 */ if (Z_REFCOUNTED(tmp)) { if (Z_REFCOUNT(tmp) > 1) { if (!Z_ISREF(tmp)) { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } } } else { zval new_zv; ZVAL_DUP(&new_zv, &tmp); ZVAL_COPY_VALUE(&tmp, &new_zv); Z_TRY_DELREF(new_zv); separated = 1; } /** Convert the value to array if not is an array */ if (Z_TYPE(tmp) != IS_ARRAY) { if (separated) { convert_to_array(&tmp); } else { array_init(&tmp); separated = 1; } Z_DELREF(tmp); } Z_TRY_ADDREF_P(value); if (Z_TYPE_P(index) == IS_STRING) { zend_symtable_str_update(Z_ARRVAL(tmp), Z_STRVAL_P(index), Z_STRLEN_P(index), value); } else if (Z_TYPE_P(index) == IS_LONG) { zend_hash_index_update(Z_ARRVAL(tmp), Z_LVAL_P(index), value); } else if (Z_TYPE_P(index) == IS_NULL) { zend_hash_next_index_insert(Z_ARRVAL(tmp), value); } if (separated) { zephir_update_property_zval(object, property, property_length, &tmp); } } return SUCCESS; }
static void php_bencode_decode_list(zval *return_value, char *str, size_t *pos, size_t *str_len) /* {{{ */ { array_init(return_value); (*pos)++; while (*pos < *str_len && str[*pos] != PHP_BENCODE_END_STRUCTURE) { zval list_value; php_bencode_decode(&list_value, str, pos, str_len); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &list_value); } (*pos)++; }
static zval * qb_add_array(zval *array, const char *name) { HashTable *ht = Z_ARRVAL_P(array); zval *zvalue; ALLOC_INIT_ZVAL(zvalue); array_init(zvalue); if(name) { zend_hash_update(ht, name, (uint32_t) strlen(name) + 1, &zvalue, sizeof(zval *), NULL); } else { zend_hash_next_index_insert(ht, &zvalue, sizeof(zval *), NULL); } return zvalue; }
static void add_offset_pair(zval *result, char *string, int string_len, int offset) { zval *match_pair; ALLOC_ZVAL(match_pair); array_init(match_pair); INIT_PZVAL(match_pair); add_next_index_stringl(match_pair, string, string_len, FALSE); add_next_index_long(match_pair, offset); zend_hash_next_index_insert(Z_ARRVAL_P(result), &match_pair, sizeof(zval *), NULL); }
void ra_index_keys(zval *z_pairs, zval *z_redis) { /* Initialize key array */ zval z_keys; zend_string *key; unsigned long num_key; array_init_size(&z_keys, zend_hash_num_elements(Z_ARRVAL_P(z_pairs))); /* Go through input array and add values to the key array */ ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(z_pairs), num_key, key) { zval z_new; if (key) { ZVAL_STR_COPY(&z_new, key); zend_hash_next_index_insert(Z_ARRVAL(z_keys), &z_new); } else { ZVAL_LONG(&z_new, num_key); zend_hash_next_index_insert(Z_ARRVAL(z_keys), &z_new); } } ZEND_HASH_FOREACH_END();
PHP_METHOD(BatchStatement, add) { zval *statement = NULL; zval *arguments = NULL; cassandra_batch_statement_entry *batch_statement_entry = NULL; cassandra_statement *self = NULL; #if PHP_MAJOR_VERSION >= 7 zval entry; #endif if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &statement, &arguments) == FAILURE) { return; } if (!instanceof_function(Z_OBJCE_P(statement), cassandra_simple_statement_ce TSRMLS_CC) && !instanceof_function(Z_OBJCE_P(statement), cassandra_prepared_statement_ce TSRMLS_CC)) { INVALID_ARGUMENT(statement, "an instance of Cassandra\\SimpleStatement or Cassandra\\PreparedStatement"); } self = PHP_CASSANDRA_GET_STATEMENT(getThis()); batch_statement_entry = (cassandra_batch_statement_entry *) ecalloc(1, sizeof(cassandra_batch_statement_entry)); PHP5TO7_ZVAL_COPY(PHP5TO7_ZVAL_MAYBE_P(batch_statement_entry->statement), statement); if (arguments) { PHP5TO7_ZVAL_COPY(PHP5TO7_ZVAL_MAYBE_P(batch_statement_entry->arguments), arguments); } #if PHP_MAJOR_VERSION >= 7 ZVAL_PTR(&entry, batch_statement_entry); zend_hash_next_index_insert(&self->statements, &entry); #else zend_hash_next_index_insert(&self->statements, &batch_statement_entry, sizeof(cassandra_batch_statement_entry *), NULL); #endif }
static void add_zval(zval* list, const char* id, zval* val) { if (list && val) { if (id) { int id_len = strlen(id); if (!(id_len > 1 && id[0] == '0') && is_numeric_string((char *)id, id_len, NULL, NULL, 0) == IS_LONG) { long index = strtol(id, NULL, 0); zend_hash_index_update(Z_ARRVAL_P(list), index, val); } else { zend_hash_str_update(Z_ARRVAL_P(list), (char*)id, strlen(id), val); } } else { zend_hash_next_index_insert(Z_ARRVAL_P(list), val); } } }
static zval * qb_add_string(zval *array, const char *name, const char *s, int32_t len) { HashTable *ht = Z_ARRVAL_P(array); zval *zvalue; ALLOC_INIT_ZVAL(zvalue); if(s) { if(len == -1) { len = (int32_t) strlen(s); } ZVAL_STRINGL(zvalue, s, len, TRUE); } if(name) { zend_hash_update(ht, name, (uint32_t) strlen(name) + 1, &zvalue, sizeof(zval *), NULL); } else { zend_hash_next_index_insert(ht, &zvalue, sizeof(zval *), NULL); } return zvalue; }
static void oauth_provider_check_required_params(HashTable *required_params, HashTable *params, HashTable *missing_params) /* {{{ */ { HashPosition hpos, reqhpos, paramhpos; zval *dest_entry, param; zend_string *key; ulong num_key; zend_hash_internal_pointer_reset_ex(required_params, &hpos); zend_hash_internal_pointer_reset_ex(params, &reqhpos); zend_hash_internal_pointer_reset_ex(missing_params, ¶mhpos); do { if(zend_hash_get_current_key_ex(required_params, &key, &num_key, &hpos) == HASH_KEY_IS_STRING) { if((dest_entry = zend_hash_find(params, key)) == NULL) { ZVAL_STRING(¶m, ZSTR_VAL(key)); zend_hash_next_index_insert(missing_params, ¶m); } } } while(zend_hash_move_forward_ex(required_params, &hpos)==SUCCESS); }
static PHP_METHOD(midgard_query_builder, execute) { RETVAL_FALSE; MidgardConnection *mgd = mgd_handle(TSRMLS_C); CHECK_MGD(mgd); if (zend_parse_parameters_none() == FAILURE) return; _GET_BUILDER_OBJECT; zend_class_entry *ce = php_gobject->user_ce; if (ce == NULL) { php_error(E_WARNING, "Query Builder instance not associated with any class"); return; } guint i, n_objects; GObject **objects = midgard_query_builder_execute(builder, &n_objects); array_init(return_value); if (!objects) return; /* TODO: Should use iterator, instead, and create objects lazily */ /* Initialize zend objects for the same class which was used to initialize Query Builder */ for (i = 0; i < n_objects; i++) { GObject *gobject = objects[i]; zval *zobject; /* TODO: Simplify code below. If possible. */ MAKE_STD_ZVAL(zobject); object_init_ex(zobject, ce); /* Initialize new object for which QB has been created for */ MGD_PHP_SET_GOBJECT(zobject, gobject); // inject our gobject zend_call_method_with_0_params(&zobject, ce, &ce->constructor, "__construct", NULL); /* Call class constructor on given instance */ zend_hash_next_index_insert(HASH_OF(return_value), &zobject, sizeof(zval *), NULL); } if (objects) g_free(objects); }
/* cURL guarantees that headers are written as complete lines, with this function * called once for each header */ static size_t on_header_available(char *data, size_t size, size_t nmemb, void *ctx) { size_t length = size * nmemb; zval *header; php_stream *stream = (php_stream *) ctx; php_curl_stream *curlstream = (php_curl_stream *) stream->abstract; TSRMLS_FETCH(); if (length < 2) { /* invalid header ? */ return length; } if (!(length == 2 && data[0] == '\r' && data[1] == '\n')) { MAKE_STD_ZVAL(header); Z_STRLEN_P(header) = length; Z_STRVAL_P(header) = estrndup(data, length); if (Z_STRVAL_P(header)[length-1] == '\n') { Z_STRVAL_P(header)[length-1] = '\0'; Z_STRLEN_P(header)--; if (Z_STRVAL_P(header)[length-2] == '\r') { Z_STRVAL_P(header)[length-2] = '\0'; Z_STRLEN_P(header)--; } } Z_TYPE_P(header) = IS_STRING; zend_hash_next_index_insert(Z_ARRVAL_P(curlstream->headers), &header, sizeof(zval *), NULL); /* based on the header, we might need to trigger a notification */ if (!strncasecmp(data, "Location: ", 10)) { php_stream_notify_info(stream->context, PHP_STREAM_NOTIFY_REDIRECTED, data + 10, 0); } else if (!strncasecmp(data, "Content-Type: ", 14)) { php_stream_notify_info(stream->context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, data + 14, 0); } else if (!strncasecmp(data, "Context-Length: ", 16)) { php_stream_notify_file_size(stream->context, atoi(data + 16), data, 0); php_stream_notify_progress_init(stream->context, 0, 0); } } return length; }
static void ast_create_virtual_node(zval *zv, zend_ast_kind kind, zend_ast *ast) { zval tmp_zv, tmp_zv2; object_init_ex(zv, ast_node_ce); ZVAL_LONG(&tmp_zv, kind); ast_update_property(zv, AST_G(str_kind), &tmp_zv, AST_CACHE_SLOT_KIND); ZVAL_LONG(&tmp_zv, ast->attr); ast_update_property(zv, AST_G(str_flags), &tmp_zv, AST_CACHE_SLOT_FLAGS); ZVAL_LONG(&tmp_zv, zend_ast_get_lineno(ast)); ast_update_property(zv, AST_G(str_lineno), &tmp_zv, AST_CACHE_SLOT_LINENO); array_init(&tmp_zv); ast_update_property(zv, AST_G(str_children), &tmp_zv, AST_CACHE_SLOT_CHILDREN); ZVAL_COPY(&tmp_zv2, zend_ast_get_zval(ast)); zend_hash_next_index_insert(Z_ARRVAL(tmp_zv), &tmp_zv2); }
void c_array_to_php_array(void *c_array,int num,zval *php_array,int type) { zval *val; HashTable *ht; int i; convert_to_array(php_array); ht = Z_ARRVAL_P(php_array); for(i = 0;i < num;i++) { MAKE_STD_ZVAL(val); switch(type) { case C_INT_TO_PHP_LONG: ZVAL_LONG(val,(int)((int*)c_array)[i]); break; case C_UINT_TO_PHP_LONG: ZVAL_LONG(val,(unsigned int)((unsigned int*)c_array)[i]); break; case C_LONG_TO_PHP_LONG: ZVAL_LONG(val,((long*)c_array)[i]); break; case C_FLOAT_TO_PHP_DOUBLE: ZVAL_DOUBLE(val,(float)((float*)c_array)[i]); break; case C_DOUBLE_TO_PHP_DOUBLE: ZVAL_DOUBLE(val,(double)((double*)c_array)[i]); break; case C_BOOLEAN_TO_PHP_BOOLEAN: ZVAL_BOOL(val,(unsigned char)((unsigned char*)c_array)[i]); break; case C_CHAR_TO_PHP_LONG: ZVAL_LONG(val,(char)((char*)c_array)[i]); break; case C_USHORT_TO_PHP_LONG: ZVAL_LONG(val,(unsigned short)((unsigned short*)c_array)[i]); break; } zend_hash_next_index_insert(ht,&val,sizeof(zval*),NULL); } }
static PHP_METHOD(midgard_query_builder, execute) { RETVAL_FALSE; MidgardConnection *mgd = mgd_handle(TSRMLS_C); CHECK_MGD(mgd); if (zend_parse_parameters_none() == FAILURE) return; _GET_BUILDER_OBJECT; zend_class_entry *ce = php_gobject->user_ce; if (ce == NULL) { php_error(E_WARNING, "Query Builder instance not associated with any class"); return; } guint i, n_objects; GObject **objects = midgard_query_builder_execute(builder, &n_objects); array_init(return_value); if (!objects) return; /* TODO: Should use iterator, instead, and create objects lazily */ for (i = 0; i < n_objects; i++) { GObject *gobject = objects[i]; zval *zobject; MAKE_STD_ZVAL(zobject); php_midgard_gobject_new_with_gobject(zobject, ce, gobject, TRUE TSRMLS_CC); zend_hash_next_index_insert(HASH_OF(return_value), &zobject, sizeof(zval *), NULL); } if (objects) g_free(objects); }
static PHP_METHOD(php_midgard_reflection_class, listSignals) { if (zend_parse_parameters_none() == FAILURE) { return; } _GET_RC_CE; if (ce == NULL) return; array_init(return_value); GType classtype = g_type_from_name(php_class_name_to_g_class_name(ce->name)); if (!classtype) { return; } guint n_ids = 0; guint *ids = g_signal_list_ids(classtype, &n_ids); if (ids == NULL) { return; } size_t i; for (i = 0; i < n_ids; i++) { zval *signalname; MAKE_STD_ZVAL(signalname); ZVAL_STRING(signalname, (char *) g_signal_name(ids[i]), 1); zend_hash_next_index_insert(HASH_OF(return_value), &signalname, sizeof(zval *), NULL); } g_free(ids); }
static void ast_fill_children_ht(HashTable *ht, zend_ast *ast, zend_long version) { uint32_t i, count; zend_bool is_list = zend_ast_is_list(ast); zend_ast **children = ast_get_children(ast, &count); for (i = 0; i < count; ++i) { zend_ast *child = children[i]; zend_string *child_name = !is_list && version >= 30 ? ast_kind_child_name(ast->kind, i) : NULL; zval child_zv; if (version >= 20 && ast->kind == ZEND_AST_STMT_LIST && child != NULL && child->kind == ZEND_AST_STMT_LIST) { ast_fill_children_ht(ht, child, version); continue; } if (ast_is_name(child, ast, i)) { ast_create_virtual_node(&child_zv, AST_NAME, child, version); } else if (ast->kind == ZEND_AST_CLOSURE_USES) { ast_create_virtual_node(&child_zv, AST_CLOSURE_VAR, child, version); } else if (version >= 20 && ast_is_var_name(child, ast, i)) { ast_create_virtual_node(&child_zv, ZEND_AST_VAR, child, version); } else if (ast->kind == ZEND_AST_PROP_ELEM && i == 2) { /* Skip docComment child -- It's handled separately */ continue; } else { ast_to_zval(&child_zv, child, version); } if (child_name) { zend_hash_add_new(ht, child_name, &child_zv); } else { zend_hash_next_index_insert(ht, &child_zv); } } }
php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context, int redirect_max, int header_init STREAMS_DC TSRMLS_DC) { php_stream *stream = NULL; php_url *resource = NULL; int use_ssl; char *scratch = NULL; char *tmp = NULL; char *ua_str = NULL; zval **ua_zval = NULL, **tmpzval = NULL; int scratch_len = 0; int body = 0; char location[HTTP_HEADER_BLOCK_SIZE]; zval **response_header = NULL; int reqok = 0; char *http_header_line = NULL; char tmp_line[128]; size_t chunk_size = 0, file_size = 0; int eol_detect, have_header = 0; if (redirect_max < 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Circular redirect, aborting."); return NULL; } if (strpbrk(mode, "aw+")) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP wrapper does not support writeable connections."); return NULL; } resource = php_url_parse(path); if (resource == NULL) { return NULL; } if (strncasecmp(resource->scheme, "http", sizeof("http")) && strncasecmp(resource->scheme, "https", sizeof("https"))) { php_url_free(resource); return php_stream_open_wrapper_ex(path, mode, ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, context); } use_ssl = resource->scheme && (strlen(resource->scheme) > 4) && resource->scheme[4] == 's'; /* choose default ports */ if (use_ssl && resource->port == 0) resource->port = 443; else if (resource->port == 0) resource->port = 80; stream = php_stream_sock_open_host(resource->host, resource->port, SOCK_STREAM, NULL, 0); if (stream == NULL) { eol_detect = 0; goto out; } /* avoid problems with auto-detecting when reading the headers -> the headers * are always in canonical \r\n format */ eol_detect = stream->flags & (PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC); stream->flags &= ~(PHP_STREAM_FLAG_DETECT_EOL | PHP_STREAM_FLAG_EOL_MAC); php_stream_context_set(stream, context); php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0); #ifdef HAVE_OPENSSL_EXT if (use_ssl) { if (context) { /* set the CN we expect to be on the remote cert. * You still need to have enabled verification (verify_peer) in the context for * this to have an effect */ zval *cn; ALLOC_INIT_ZVAL(cn); ZVAL_STRING(cn, resource->host, 1); php_stream_context_set_option(context, "ssl", "CN_match", cn); } if (php_stream_sock_ssl_activate(stream, 1) == FAILURE) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Unable to activate SSL mode"); php_stream_close(stream); stream = NULL; goto out; } } #endif if (context && php_stream_context_get_option(context, "http", "method", &tmpzval) == SUCCESS) { if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) { scratch_len = strlen(path) + 29 + Z_STRLEN_PP(tmpzval); scratch = (char *)emalloc(scratch_len); strlcpy(scratch, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) + 1); strcat(scratch, " "); } } if (!scratch) { scratch_len = strlen(path) + 32; scratch = (char *)emalloc(scratch_len); strcpy(scratch, "GET "); } /* file */ if (resource->path && *resource->path) strlcat(scratch, resource->path, scratch_len); else strlcat(scratch, "/", scratch_len); /* query string */ if (resource->query) { strlcat(scratch, "?", scratch_len); strlcat(scratch, resource->query, scratch_len); } /* protocol version we are speaking */ strlcat(scratch, " HTTP/1.0\r\n", scratch_len); /* send it */ php_stream_write(stream, scratch, strlen(scratch)); if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS && Z_STRLEN_PP(tmpzval)) { /* Remove newlines and spaces from start and end, php_trim will estrndup() */ tmp = php_trim(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval), NULL, 0, NULL, 3 TSRMLS_CC); if (strlen(tmp) > 0) { /* Output trimmed headers with \r\n at the end */ php_stream_write(stream, tmp, strlen(tmp)); php_stream_write(stream, "\r\n", sizeof("\r\n") - 1); /* Make lowercase for easy comparison against 'standard' headers */ php_strtolower(tmp, strlen(tmp)); if (strstr(tmp, "user-agent:")) { have_header |= HTTP_HEADER_USER_AGENT; } if (strstr(tmp, "host:")) { have_header |= HTTP_HEADER_HOST; } if (strstr(tmp, "from:")) { have_header |= HTTP_HEADER_FROM; } if (strstr(tmp, "authorization:")) { have_header |= HTTP_HEADER_AUTH; } } efree(tmp); } /* auth header if it was specified */ if (((have_header & HTTP_HEADER_AUTH) == 0) && resource->user && resource->pass) { /* decode the strings first */ php_url_decode(resource->user, strlen(resource->user)); php_url_decode(resource->pass, strlen(resource->pass)); /* scratch is large enough, since it was made large enough for the whole URL */ strcpy(scratch, resource->user); strcat(scratch, ":"); strcat(scratch, resource->pass); tmp = (char *)php_base64_encode((unsigned char*)scratch, strlen(scratch), NULL); if (snprintf(scratch, scratch_len, "Authorization: Basic %s\r\n", tmp) > 0) { php_stream_write(stream, scratch, strlen(scratch)); php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, NULL, 0); } efree(tmp); tmp = NULL; } /* if the user has configured who they are, send a From: line */ if (((have_header & HTTP_HEADER_FROM) == 0) && cfg_get_string("from", &tmp) == SUCCESS) { if (snprintf(scratch, scratch_len, "From: %s\r\n", tmp) > 0) { php_stream_write(stream, scratch, strlen(scratch)); } } /* Send Host: header so name-based virtual hosts work */ if ((have_header & HTTP_HEADER_HOST) == 0) { if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) { if (snprintf(scratch, scratch_len, "Host: %s:%i\r\n", resource->host, resource->port) > 0) { php_stream_write(stream, scratch, strlen(scratch)); } } else { if (snprintf(scratch, scratch_len, "Host: %s\r\n", resource->host) > 0) { php_stream_write(stream, scratch, strlen(scratch)); } } } if (context && php_stream_context_get_option(context, "http", "user_agent", &ua_zval) == SUCCESS) { ua_str = Z_STRVAL_PP(ua_zval); } else if (FG(user_agent)) { ua_str = FG(user_agent); } if (ua_str) { #define _UA_HEADER "User-Agent: %s\r\n" char *ua; size_t ua_len; ua_len = sizeof(_UA_HEADER) + strlen(ua_str); /* ensure the header is only sent if user_agent is not blank */ if (ua_len > sizeof(_UA_HEADER)) { ua = (char *)emalloc(ua_len + 1); if ((ua_len = snprintf(ua, ua_len, _UA_HEADER, ua_str)) > 0) { ua[ua_len] = 0; php_stream_write(stream, ua, ua_len); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot construct User-agent header"); } if (ua) { efree(ua); } } } php_stream_write(stream, "\r\n", sizeof("\r\n")-1); /* Request content, such as for POST requests */ if (context && php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS && Z_STRLEN_PP(tmpzval) > 0) { php_stream_write(stream, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval)); php_stream_write(stream, "\r\n\r\n", sizeof("\r\n\r\n")-1); } location[0] = '\0'; /* * We need to read the HTTP response header one-by-one, because * the original author did not know about MSG_PEEK. * The chunk_size will be reset later, once we have read the * header completely. */ if (options & STREAM_WILL_CAST) chunk_size = php_stream_set_chunk_size(stream, 1); if (!header_init && FAILURE == zend_hash_find(EG(active_symbol_table), "http_response_header", sizeof("http_response_header"), (void **) &response_header)) { header_init = 1; } if (header_init) { zval *tmp; MAKE_STD_ZVAL(tmp); array_init(tmp); ZEND_SET_SYMBOL(EG(active_symbol_table), "http_response_header", tmp); zend_hash_find(EG(active_symbol_table), "http_response_header", sizeof("http_response_header"), (void **) &response_header); } if (!php_stream_eof(stream)) { size_t tmp_line_len; /* get response header */ if (_php_stream_get_line(stream, tmp_line, sizeof(tmp_line) - 1, &tmp_line_len TSRMLS_CC) != NULL) { zval *http_response; int response_code; MAKE_STD_ZVAL(http_response); ZVAL_NULL(http_response); if (tmp_line_len > 9) { response_code = atoi(tmp_line + 9); } else { response_code = 0; } switch(response_code) { case 200: case 302: case 301: reqok = 1; break; case 403: php_stream_notify_error(context, PHP_STREAM_NOTIFY_AUTH_RESULT, tmp_line, response_code); break; default: /* safety net in the event tmp_line == NULL */ if (!tmp_line_len) { tmp_line[0] = '\0'; } php_stream_notify_error(context, PHP_STREAM_NOTIFY_FAILURE, tmp_line, response_code); } Z_STRLEN_P(http_response) = tmp_line_len; Z_STRVAL_P(http_response) = estrndup(tmp_line, Z_STRLEN_P(http_response)); if (Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=='\n') { Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=0; Z_STRLEN_P(http_response)--; if (Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=='\r') { Z_STRVAL_P(http_response)[Z_STRLEN_P(http_response)-1]=0; Z_STRLEN_P(http_response)--; } } Z_TYPE_P(http_response) = IS_STRING; zend_hash_next_index_insert(Z_ARRVAL_PP(response_header), &http_response, sizeof(zval *), NULL); } } else { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed, unexpected end of socket!"); goto out; } /* read past HTTP headers */ http_header_line = (char *)emalloc(HTTP_HEADER_BLOCK_SIZE); while (!body && !php_stream_eof(stream)) { if (php_stream_gets(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE-1) != NULL) { char *p; int found_eol = 0; int http_header_line_length; http_header_line[HTTP_HEADER_BLOCK_SIZE-1] = '\0'; p = http_header_line; while(*p) { while(*p == '\n' || *p == '\r') { *p = '\0'; p--; found_eol = 1; } if (found_eol) break; p++; } http_header_line_length = p-http_header_line+1; if (!strncasecmp(http_header_line, "Location: ", 10)) { strlcpy(location, http_header_line + 10, sizeof(location)); } else if (!strncasecmp(http_header_line, "Content-Type: ", 14)) { php_stream_notify_info(context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, http_header_line + 14, 0); } else if (!strncasecmp(http_header_line, "Content-Length: ", 16)) { file_size = atoi(http_header_line + 16); php_stream_notify_file_size(context, file_size, http_header_line, 0); } if (http_header_line[0] == '\0') { body = 1; } else { zval *http_header; MAKE_STD_ZVAL(http_header); ZVAL_STRINGL(http_header, http_header_line, http_header_line_length, 1); zend_hash_next_index_insert(Z_ARRVAL_PP(response_header), &http_header, sizeof(zval *), NULL); } } else { break; } } if (!reqok || location[0] != '\0') { if (location[0] != '\0') php_stream_notify_info(context, PHP_STREAM_NOTIFY_REDIRECTED, location, 0); php_stream_close(stream); stream = NULL; if (location[0] != '\0') { zval *entry, **entryp; char new_path[HTTP_HEADER_BLOCK_SIZE]; char loc_path[HTTP_HEADER_BLOCK_SIZE]; *new_path='\0'; if (strlen(location)<8 || (strncasecmp(location, "http://", sizeof("http://")-1) && strncasecmp(location, "https://", sizeof("https://")-1) && strncasecmp(location, "ftp://", sizeof("ftp://")-1) && strncasecmp(location, "ftps://", sizeof("ftps://")-1))) { if (*location != '/') { if (*(location+1) != '\0' && resource->path) { char *s = strrchr(resource->path, '/'); if (!s) { s = resource->path; if (!s[0]) { efree(s); s = resource->path = estrdup("/"); } else { *s = '/'; } } s[1] = '\0'; if (resource->path && *(resource->path) == '/' && *(resource->path + 1) == '\0') { snprintf(loc_path, sizeof(loc_path) - 1, "%s%s", resource->path, location); } else { snprintf(loc_path, sizeof(loc_path) - 1, "%s/%s", resource->path, location); } } else { snprintf(loc_path, sizeof(loc_path) - 1, "/%s", location); } } else { strlcpy(loc_path, location, sizeof(loc_path)); } if ((use_ssl && resource->port != 443) || (!use_ssl && resource->port != 80)) { snprintf(new_path, sizeof(new_path) - 1, "%s://%s:%d%s", resource->scheme, resource->host, resource->port, loc_path); } else { snprintf(new_path, sizeof(new_path) - 1, "%s://%s%s", resource->scheme, resource->host, loc_path); } } else { strlcpy(new_path, location, sizeof(new_path)); } stream = php_stream_url_wrap_http_ex(NULL, new_path, mode, options, opened_path, context, --redirect_max, 0 STREAMS_CC TSRMLS_CC); if (stream && stream->wrapperdata) { entryp = &entry; MAKE_STD_ZVAL(entry); ZVAL_EMPTY_STRING(entry); zend_hash_next_index_insert(Z_ARRVAL_PP(response_header), entryp, sizeof(zval *), NULL); zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream->wrapperdata)); while (zend_hash_get_current_data(Z_ARRVAL_P(stream->wrapperdata), (void **)&entryp) == SUCCESS) { zval_add_ref(entryp); zend_hash_next_index_insert(Z_ARRVAL_PP(response_header), entryp, sizeof(zval *), NULL); zend_hash_move_forward(Z_ARRVAL_P(stream->wrapperdata)); } zval_dtor(stream->wrapperdata); FREE_ZVAL(stream->wrapperdata); } } else { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP request failed! %s", tmp_line); } } out: if (http_header_line) efree(http_header_line); if (scratch) efree(scratch); php_url_free(resource); if (stream) { if (header_init) { stream->wrapperdata = *response_header; zval_add_ref(response_header); } php_stream_notify_progress_init(context, 0, file_size); /* Restore original chunk size now that we're done with headers (if applicable) */ if (options & STREAM_WILL_CAST) php_stream_set_chunk_size(stream, chunk_size); /* restore the users auto-detect-line-endings setting */ stream->flags |= eol_detect; /* as far as streams are concerned, we are now at the start of * the stream */ stream->position = 0; } return stream; }
/* {{{ php_stat */ static void phar_fancy_stat(zend_stat_t *stat_sb, int type, zval *return_value) { zval stat_dev, stat_ino, stat_mode, stat_nlink, stat_uid, stat_gid, stat_rdev, stat_size, stat_atime, stat_mtime, stat_ctime, stat_blksize, stat_blocks; int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */ char *stat_sb_names[13] = { "dev", "ino", "mode", "nlink", "uid", "gid", "rdev", "size", "atime", "mtime", "ctime", "blksize", "blocks" }; #ifndef NETWARE if (type >= FS_IS_W && type <= FS_IS_X) { if(stat_sb->st_uid==getuid()) { rmask=S_IRUSR; wmask=S_IWUSR; xmask=S_IXUSR; } else if(stat_sb->st_gid==getgid()) { rmask=S_IRGRP; wmask=S_IWGRP; xmask=S_IXGRP; } else { int groups, n, i; gid_t *gids; groups = getgroups(0, NULL); if(groups > 0) { gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0); n=getgroups(groups, gids); for(i=0;i<n;++i){ if(stat_sb->st_gid==gids[i]) { rmask=S_IRGRP; wmask=S_IWGRP; xmask=S_IXGRP; break; } } efree(gids); } } } #endif switch (type) { case FS_PERMS: RETURN_LONG((zend_long)stat_sb->st_mode); case FS_INODE: RETURN_LONG((zend_long)stat_sb->st_ino); case FS_SIZE: RETURN_LONG((zend_long)stat_sb->st_size); case FS_OWNER: RETURN_LONG((zend_long)stat_sb->st_uid); case FS_GROUP: RETURN_LONG((zend_long)stat_sb->st_gid); case FS_ATIME: #ifdef NETWARE RETURN_LONG((zend_long)stat_sb->st_atime.tv_sec); #else RETURN_LONG((zend_long)stat_sb->st_atime); #endif case FS_MTIME: #ifdef NETWARE RETURN_LONG((zend_long)stat_sb->st_mtime.tv_sec); #else RETURN_LONG((zend_long)stat_sb->st_mtime); #endif case FS_CTIME: #ifdef NETWARE RETURN_LONG((zend_long)stat_sb->st_ctime.tv_sec); #else RETURN_LONG((zend_long)stat_sb->st_ctime); #endif case FS_TYPE: if (S_ISLNK(stat_sb->st_mode)) { RETURN_STRING("link"); } switch(stat_sb->st_mode & S_IFMT) { case S_IFDIR: RETURN_STRING("dir"); case S_IFREG: RETURN_STRING("file"); } php_error_docref(NULL, E_NOTICE, "Unknown file type (%u)", stat_sb->st_mode & S_IFMT); RETURN_STRING("unknown"); case FS_IS_W: RETURN_BOOL((stat_sb->st_mode & wmask) != 0); case FS_IS_R: RETURN_BOOL((stat_sb->st_mode&rmask)!=0); case FS_IS_X: RETURN_BOOL((stat_sb->st_mode&xmask)!=0 && !S_ISDIR(stat_sb->st_mode)); case FS_IS_FILE: RETURN_BOOL(S_ISREG(stat_sb->st_mode)); case FS_IS_DIR: RETURN_BOOL(S_ISDIR(stat_sb->st_mode)); case FS_IS_LINK: RETURN_BOOL(S_ISLNK(stat_sb->st_mode)); case FS_EXISTS: RETURN_TRUE; /* the false case was done earlier */ case FS_LSTAT: /* FALLTHROUGH */ case FS_STAT: array_init(return_value); ZVAL_LONG(&stat_dev, stat_sb->st_dev); ZVAL_LONG(&stat_ino, stat_sb->st_ino); ZVAL_LONG(&stat_mode, stat_sb->st_mode); ZVAL_LONG(&stat_nlink, stat_sb->st_nlink); ZVAL_LONG(&stat_uid, stat_sb->st_uid); ZVAL_LONG(&stat_gid, stat_sb->st_gid); #ifdef HAVE_ST_RDEV ZVAL_LONG(&stat_rdev, stat_sb->st_rdev); #else ZVAL_LONG(&stat_rdev, -1); #endif ZVAL_LONG(&stat_size, stat_sb->st_size); #ifdef NETWARE ZVAL_LONG(&stat_atime, (stat_sb->st_atime).tv_sec); ZVAL_LONG(&stat_mtime, (stat_sb->st_mtime).tv_sec); ZVAL_LONG(&stat_ctime, (stat_sb->st_ctime).tv_sec); #else ZVAL_LONG(&stat_atime, stat_sb->st_atime); ZVAL_LONG(&stat_mtime, stat_sb->st_mtime); ZVAL_LONG(&stat_ctime, stat_sb->st_ctime); #endif #ifdef HAVE_ST_BLKSIZE ZVAL_LONG(&stat_blksize, stat_sb->st_blksize); #else ZVAL_LONG(&stat_blksize,-1); #endif #ifdef HAVE_ST_BLOCKS ZVAL_LONG(&stat_blocks, stat_sb->st_blocks); #else ZVAL_LONG(&stat_blocks,-1); #endif /* Store numeric indexes in proper order */ zend_hash_next_index_insert(HASH_OF(return_value), &stat_dev); zend_hash_next_index_insert(HASH_OF(return_value), &stat_ino); zend_hash_next_index_insert(HASH_OF(return_value), &stat_mode); zend_hash_next_index_insert(HASH_OF(return_value), &stat_nlink); zend_hash_next_index_insert(HASH_OF(return_value), &stat_uid); zend_hash_next_index_insert(HASH_OF(return_value), &stat_gid); zend_hash_next_index_insert(HASH_OF(return_value), &stat_rdev); zend_hash_next_index_insert(HASH_OF(return_value), &stat_size); zend_hash_next_index_insert(HASH_OF(return_value), &stat_atime); zend_hash_next_index_insert(HASH_OF(return_value), &stat_mtime); zend_hash_next_index_insert(HASH_OF(return_value), &stat_ctime); zend_hash_next_index_insert(HASH_OF(return_value), &stat_blksize); zend_hash_next_index_insert(HASH_OF(return_value), &stat_blocks); /* Store string indexes referencing the same zval*/ zend_hash_str_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0]), &stat_dev); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1]), &stat_ino); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2]), &stat_mode); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3]), &stat_nlink); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4]), &stat_uid); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5]), &stat_gid); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6]), &stat_rdev); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7]), &stat_size); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8]), &stat_atime); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9]), &stat_mtime); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10]), &stat_ctime); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11]), &stat_blksize); zend_hash_str_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12]), &stat_blocks); return; } php_error_docref(NULL, E_WARNING, "Didn't understand stat call"); RETURN_FALSE; }
static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */ { xsltTransformContextPtr tctxt; zval *args; zval retval; int result, i; int error = 0; zend_fcall_info fci; zval handler; xmlXPathObjectPtr obj; char *str; xsl_object *intern; zend_string *callable = NULL; if (! zend_is_executing()) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: Function called from outside of PHP\n"); error = 1; } else { tctxt = xsltXPathGetTransformContext(ctxt); if (tctxt == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the transformation context\n"); error = 1; } else { intern = (xsl_object*)tctxt->_private; if (intern == NULL) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: failed to get the internal object\n"); error = 1; } else if (intern->registerPhpFunctions == 0) { xsltGenericError(xsltGenericErrorContext, "xsltExtFunctionTest: PHP Object did not register PHP functions\n"); error = 1; } } } if (error == 1) { for (i = nargs - 1; i >= 0; i--) { obj = valuePop(ctxt); xmlXPathFreeObject(obj); } return; } fci.param_count = nargs - 1; if (fci.param_count > 0) { args = safe_emalloc(fci.param_count, sizeof(zval), 0); } /* Reverse order to pop values off ctxt stack */ for (i = nargs - 2; i >= 0; i--) { obj = valuePop(ctxt); switch (obj->type) { case XPATH_STRING: ZVAL_STRING(&args[i], (char *)obj->stringval); break; case XPATH_BOOLEAN: ZVAL_BOOL(&args[i], obj->boolval); break; case XPATH_NUMBER: ZVAL_DOUBLE(&args[i], obj->floatval); break; case XPATH_NODESET: if (type == 1) { str = (char*)xmlXPathCastToString(obj); ZVAL_STRING(&args[i], str); xmlFree(str); } else if (type == 2) { int j; dom_object *domintern = (dom_object *)intern->doc; array_init(&args[i]); if (obj->nodesetval && obj->nodesetval->nodeNr > 0) { for (j = 0; j < obj->nodesetval->nodeNr; j++) { xmlNodePtr node = obj->nodesetval->nodeTab[j]; zval child; /* not sure, if we need this... it's copied from xpath.c */ if (node->type == XML_NAMESPACE_DECL) { xmlNsPtr curns; xmlNodePtr nsparent; nsparent = node->_private; curns = xmlNewNs(NULL, node->name, NULL); if (node->children) { curns->prefix = xmlStrdup((char *)node->children); } if (node->children) { node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name); } else { node = xmlNewDocNode(node->doc, NULL, (const xmlChar *) "xmlns", node->name); } node->type = XML_NAMESPACE_DECL; node->parent = nsparent; node->ns = curns; } else { node = xmlDocCopyNodeList(domintern->document->ptr, node); } php_dom_create_object(node, &child, domintern); add_next_index_zval(&args[i], &child); } } } break; default: str = (char *) xmlXPathCastToString(obj); ZVAL_STRING(&args[i], str); xmlFree(str); } xmlXPathFreeObject(obj); } fci.size = sizeof(fci); fci.function_table = EG(function_table); if (fci.param_count > 0) { fci.params = args; } else { fci.params = NULL; } obj = valuePop(ctxt); if (obj->stringval == NULL) { php_error_docref(NULL, E_WARNING, "Handler name must be a string"); xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&args[i]); } efree(args); } return; } ZVAL_STRING(&handler, (char *) obj->stringval); xmlXPathFreeObject(obj); ZVAL_COPY_VALUE(&fci.function_name, &handler); fci.symbol_table = NULL; fci.object = NULL; fci.retval = &retval; fci.no_separation = 0; /*fci.function_handler_cache = &function_ptr;*/ if (!zend_make_callable(&handler, &callable)) { php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", ZSTR_VAL(callable)); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) { php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'", ZSTR_VAL(callable)); /* Push an empty string, so that we at least have an xslt result... */ valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } else { result = zend_call_function(&fci, NULL); if (result == FAILURE) { if (Z_TYPE(handler) == IS_STRING) { php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", Z_STRVAL(handler)); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } /* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */ } else if (Z_ISUNDEF(retval)) { } else { if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) { xmlNode *nodep; dom_object *obj; if (intern->node_list == NULL) { ALLOC_HASHTABLE(intern->node_list); zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0); } Z_ADDREF(retval); zend_hash_next_index_insert(intern->node_list, &retval); obj = Z_DOMOBJ_P(&retval); nodep = dom_object_get_node(obj); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); } else if (Z_TYPE(retval) == IS_TRUE || Z_TYPE(retval) == IS_FALSE) { valuePush(ctxt, xmlXPathNewBoolean(Z_LVAL(retval))); } else if (Z_TYPE(retval) == IS_OBJECT) { php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string"); valuePush(ctxt, xmlXPathNewString((const xmlChar *) "")); } else { convert_to_string_ex(&retval); valuePush(ctxt, xmlXPathNewString((xmlChar *) Z_STRVAL(retval))); } zval_ptr_dtor(&retval); } } zend_string_release(callable); zval_ptr_dtor(&handler); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&args[i]); } efree(args); } }
static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */ { zval retval; int result, i; int error = 0; zend_fcall_info fci; xmlXPathObjectPtr obj; char *str; zend_string *callable = NULL; dom_xpath_object *intern; if (! zend_is_executing()) { xmlGenericError(xmlGenericErrorContext, "xmlExtFunctionTest: Function called from outside of PHP\n"); error = 1; } else { intern = (dom_xpath_object *) ctxt->context->userData; if (intern == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlExtFunctionTest: failed to get the internal object\n"); error = 1; } else if (intern->registerPhpFunctions == 0) { xmlGenericError(xmlGenericErrorContext, "xmlExtFunctionTest: PHP Object did not register PHP functions\n"); error = 1; } } if (error == 1) { for (i = nargs - 1; i >= 0; i--) { obj = valuePop(ctxt); xmlXPathFreeObject(obj); } return; } fci.param_count = nargs - 1; if (fci.param_count > 0) { fci.params = safe_emalloc(fci.param_count, sizeof(zval), 0); } /* Reverse order to pop values off ctxt stack */ for (i = nargs - 2; i >= 0; i--) { obj = valuePop(ctxt); switch (obj->type) { case XPATH_STRING: ZVAL_STRING(&fci.params[i], (char *)obj->stringval); break; case XPATH_BOOLEAN: ZVAL_BOOL(&fci.params[i], obj->boolval); break; case XPATH_NUMBER: ZVAL_DOUBLE(&fci.params[i], obj->floatval); break; case XPATH_NODESET: if (type == 1) { str = (char *)xmlXPathCastToString(obj); ZVAL_STRING(&fci.params[i], str); xmlFree(str); } else if (type == 2) { int j; array_init(&fci.params[i]); if (obj->nodesetval && obj->nodesetval->nodeNr > 0) { for (j = 0; j < obj->nodesetval->nodeNr; j++) { xmlNodePtr node = obj->nodesetval->nodeTab[j]; zval child; /* not sure, if we need this... it's copied from xpath.c */ if (node->type == XML_NAMESPACE_DECL) { xmlNsPtr curns; xmlNodePtr nsparent; nsparent = node->_private; curns = xmlNewNs(NULL, node->name, NULL); if (node->children) { curns->prefix = xmlStrdup((xmlChar *) node->children); } if (node->children) { node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name); } else { node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name); } node->type = XML_NAMESPACE_DECL; node->parent = nsparent; node->ns = curns; } php_dom_create_object(node, &child, &intern->dom); add_next_index_zval(&fci.params[i], &child); } } } break; default: ZVAL_STRING(&fci.params[i], (char *)xmlXPathCastToString(obj)); } xmlXPathFreeObject(obj); } fci.size = sizeof(fci); fci.function_table = EG(function_table); obj = valuePop(ctxt); if (obj->stringval == NULL) { php_error_docref(NULL, E_WARNING, "Handler name must be a string"); xmlXPathFreeObject(obj); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&fci.params[i]); } efree(fci.params); } return; } ZVAL_STRING(&fci.function_name, (char *) obj->stringval); xmlXPathFreeObject(obj); fci.symbol_table = NULL; fci.object = NULL; fci.retval = &retval; fci.no_separation = 0; if (!zend_make_callable(&fci.function_name, &callable)) { php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", callable->val); } else if (intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) { php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'.", callable->val); /* Push an empty string, so that we at least have an xslt result... */ valuePush(ctxt, xmlXPathNewString((xmlChar *)"")); } else { result = zend_call_function(&fci, NULL); if (result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) { xmlNode *nodep; dom_object *obj; if (intern->node_list == NULL) { ALLOC_HASHTABLE(intern->node_list); zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0); } GC_REFCOUNT(&retval)++; zend_hash_next_index_insert(intern->node_list, &retval); obj = Z_DOMOBJ_P(&retval); nodep = dom_object_get_node(obj); valuePush(ctxt, xmlXPathNewNodeSet(nodep)); } else if (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE) { valuePush(ctxt, xmlXPathNewBoolean(Z_TYPE(retval) == IS_TRUE)); } else if (Z_TYPE(retval) == IS_OBJECT) { php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string"); valuePush(ctxt, xmlXPathNewString((xmlChar *)"")); } else { zend_string *str = zval_get_string(&retval); valuePush(ctxt, xmlXPathNewString((xmlChar *) str->val)); zend_string_release(str); } zval_ptr_dtor(&retval); } } zend_string_release(callable); zval_dtor(&fci.function_name); if (fci.param_count > 0) { for (i = 0; i < nargs - 1; i++) { zval_ptr_dtor(&fci.params[i]); } efree(fci.params); } }