/* Returns the bytes read on success * Returns -31 on unknown failure * Returns -80 on timeout * Returns -32 when remote server closes the connection */ int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message) { int num = 1, received = 0; TSRMLS_FETCH(); if (timeout > 0 && options->socketTimeoutMS != timeout) { struct timeval rtimeout = {0}; rtimeout.tv_sec = timeout / 1000; rtimeout.tv_usec = (timeout % 1000) * 1000; php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout); } /* this can return FAILED if there is just no more data from db */ while (received < size && num > 0) { int len = 4096 < (size - received) ? 4096 : size - received; num = php_stream_read(con->socket, (char *) data, len); if (num < 0) { /* Doesn't look like this can happen, php_sockop_read overwrites * the failure from recv() to return 0 */ *error_message = strdup("Read from socket failed"); return -31; } /* It *may* have failed. It also may simply have no data */ if (num == 0) { zval *metadata; MAKE_STD_ZVAL(metadata); array_init(metadata); if (php_stream_populate_meta_data(con->socket, metadata)) { zval **tmp; if (zend_hash_find(Z_ARRVAL_P(metadata), "timed_out", sizeof("timed_out"), (void**)&tmp) == SUCCESS) { convert_to_boolean_ex(tmp); if (Z_BVAL_PP(tmp)) { struct timeval rtimeout = {0}; if (timeout > 0 && options->socketTimeoutMS != timeout) { rtimeout.tv_sec = timeout / 1000; rtimeout.tv_usec = (timeout % 1000) * 1000; } else { rtimeout.tv_sec = options->socketTimeoutMS / 1000; rtimeout.tv_usec = (options->socketTimeoutMS % 1000) * 1000; } *error_message = malloc(256); snprintf(*error_message, 256, "Read timed out after reading %d bytes, waited for %d.%06d seconds", num, rtimeout.tv_sec, rtimeout.tv_usec); zval_ptr_dtor(&metadata); return -80; } } if (zend_hash_find(Z_ARRVAL_P(metadata), "eof", sizeof("eof"), (void**)&tmp) == SUCCESS) { convert_to_boolean_ex(tmp); if (Z_BVAL_PP(tmp)) { *error_message = strdup("Remote server has closed the connection"); zval_ptr_dtor(&metadata); return -32; } } } zval_ptr_dtor(&metadata); } data = (char*)data + num; received += num; } if (options && options->ctx) { php_stream_notify_progress_increment((php_stream_context *)options->ctx, received, size); } if (timeout > 0 && options->socketTimeoutMS != timeout) { struct timeval rtimeout = {0}; rtimeout.tv_sec = options->socketTimeoutMS / 1000; rtimeout.tv_usec = (options->socketTimeoutMS % 1000) * 1000; php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout); } return received; }
/** * Applies a format to a message before sending it to the log * * @param string $message * @param int $type * @param int $timestamp * @param array $context * @return string */ PHP_METHOD(Phalcon_Logger_Formatter_Firephp, format) { zval *message, *type, *type_str = NULL, *timestamp, *context, *interpolated = NULL; zval *payload, *body, *backtrace = NULL, *meta, *encoded; zval *show_backtrace, *enable_labels; int i_show_backtrace, i_enable_labels; smart_str result = { NULL, 0, 0 }; uint i; Bucket *p; phalcon_fetch_params(0, 4, 0, &message, &type, ×tamp, &context); /* * We intentionally do not use Phalcon's MM for better performance. * All variables allocated with ALLOC_INIT_ZVAL() will have * their reference count set to 1 and therefore they can be nicely * put into the result array; when that array will be destroyed, * all inserted variables will be automatically destroyed, too * and we will just save some time by not using Z_ADDREF_P and Z_DELREF_P */ if (Z_TYPE_P(context) == IS_ARRAY) { PHALCON_CALL_METHODW(&interpolated, this_ptr, "interpolate", message, context); } else { interpolated = message; Z_ADDREF_P(interpolated); } { zval *params[] = { type }; if (FAILURE == phalcon_call_method(&type_str, this_ptr, "gettypestring", 1, params TSRMLS_CC)) { zval_ptr_dtor(&interpolated); return; } } show_backtrace = phalcon_fetch_nproperty_this(getThis(), SL("_showBacktrace"), PH_NOISY TSRMLS_CC); enable_labels = phalcon_fetch_nproperty_this(getThis(), SL("_enableLabels"), PH_NOISY TSRMLS_CC); i_show_backtrace = zend_is_true(show_backtrace); i_enable_labels = zend_is_true(enable_labels); /* * Get the backtrace. This differs for different PHP versions. * 5.3.6+ allows us to skip the function arguments which will save some memory * For 5.4+ there is an extra argument. */ if (i_show_backtrace) { ALLOC_INIT_ZVAL(backtrace); #if PHP_VERSION_ID < 50306 zend_fetch_debug_backtrace(backtrace, 1, 0 TSRMLS_CC); #elif PHP_VERSION_ID < 50400 zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS TSRMLS_CC); #else zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS, 0 TSRMLS_CC); #endif if (Z_TYPE_P(backtrace) == IS_ARRAY) { HashPosition pos; HashTable *ht = Z_ARRVAL_P(backtrace); zval **ppzval; int found = 0; ulong idx; char *key; uint key_len; /* * At this point we know that the backtrace is the array. * Again, we intentionally do not use Phalcon's API because we know * that we are working with the array / hash table and thus we can * save some time by omitting Z_TYPE_P(x) == IS_ARRAY checks */ for ( zend_hash_internal_pointer_reset_ex(ht, &pos); zend_hash_has_more_elements_ex(ht, &pos) == SUCCESS; ) { zend_hash_get_current_data_ex(ht, (void**)&ppzval, &pos); zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, &pos); zend_hash_move_forward_ex(ht, &pos); if (Z_TYPE_PP(ppzval) == IS_ARRAY) { /* * Here we need to skip the latest calls into Phalcon's core. * Calls to Zend internal functions will have "file" index not set. * We remove these entries from the array. */ if (!found && !zend_hash_quick_exists(Z_ARRVAL_PP(ppzval), SS("file"), zend_inline_hash_func(SS("file")))) { zend_hash_index_del(ht, idx); } else { /* * Remove args and object indices. They usually give * too much information; this is not suitable to send * in the HTTP headers */ zend_hash_quick_del(Z_ARRVAL_PP(ppzval), "args", sizeof("args"), zend_inline_hash_func(SS("args"))); zend_hash_quick_del(Z_ARRVAL_PP(ppzval), "object", sizeof("object"), zend_inline_hash_func(SS("object"))); found = 1; } } } /* * Now we need to renumber the hash table because we removed several * heading elements. If we don't do this, json_encode() will convert * this array to a JavaScript object which is an unwanted side effect */ p = ht->pListHead; i = 0; while (p != NULL) { p->nKeyLength = 0; p->h = i++; p = p->pListNext; } ht->nNextFreeElement = i; zend_hash_rehash(ht); } } /* * The result will looks like this: * * array( * array('Type' => 'message type', 'Label' => 'message'), * array('backtrace' => array(backtrace goes here) * ) */ MAKE_STD_ZVAL(payload); array_init_size(payload, 2); MAKE_STD_ZVAL(meta); array_init_size(meta, 4); add_assoc_zval_ex(meta, SS("Type"), type_str); if (i_show_backtrace && Z_TYPE_P(backtrace) == IS_ARRAY) { zval **ppzval; if (likely(SUCCESS == zend_hash_index_find(Z_ARRVAL_P(backtrace), 0, (void**)&ppzval)) && likely(Z_TYPE_PP(ppzval) == IS_ARRAY)) { zval **file = NULL, **line = NULL; zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("file"), zend_inline_hash_func(SS("file")), (void**)&file); zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("line"), zend_inline_hash_func(SS("line")), (void**)&line); if (likely(file != NULL)) { Z_ADDREF_PP(file); add_assoc_zval_ex(meta, SS("File"), *file); } if (likely(line != NULL)) { Z_ADDREF_PP(line); add_assoc_zval_ex(meta, SS("Line"), *line); } } } if (i_enable_labels) { add_assoc_zval_ex(meta, SS("Label"), interpolated); } if (!i_enable_labels && !i_show_backtrace) { body = interpolated; } else if (i_enable_labels && !i_show_backtrace) { MAKE_STD_ZVAL(body); ZVAL_EMPTY_STRING(body); } else { MAKE_STD_ZVAL(body); array_init_size(body, 2); if (i_show_backtrace) { add_assoc_zval_ex(body, SS("backtrace"), backtrace); } if (!i_enable_labels) { add_assoc_zval_ex(body, SS("message"), interpolated); } } add_next_index_zval(payload, meta); add_next_index_zval(payload, body); /* Convert everything to JSON */ ALLOC_INIT_ZVAL(encoded); if (FAILURE == phalcon_json_encode(encoded, payload, 0 TSRMLS_CC)) { zval_ptr_dtor(&payload); zval_ptr_dtor(&encoded); return; } /* As promised, kill the payload and all associated elements */ zval_ptr_dtor(&payload); /* * We don't want to use Phalcon's concatenation API because it * requires the memory manager. Therefore we fall back to using smart strings. * smart_str_alloc4() will allocate all required memory amount (plus some more) * in one go and this allows us to avoid performance penalties due to * memory reallocations. */ if (Z_TYPE_P(encoded) == IS_STRING && Z_STRVAL_P(encoded) != NULL) { smart_str_alloc4(&result, (uint)(Z_STRLEN_P(encoded) + 2 + 5), 0, i); /* * The format is: * * <size>|[meta,body]| * * Meta and body are contained in encoded inside the array, as required * by the protocol specification * @see http://www.firephp.org/Wiki/Reference/Protocol */ smart_str_append_long(&result, Z_STRLEN_P(encoded)); smart_str_appendc(&result, '|'); smart_str_appendl(&result, Z_STRVAL_P(encoded), Z_STRLEN_P(encoded)); smart_str_appendc(&result, '|'); smart_str_0(&result); } /* We don't need the JSON message anymore */ zval_ptr_dtor(&encoded); /* Do not free the smart string because we steal its data for zval */ RETURN_STRINGL(result.c, result.len, 0); }
static void php_swoole_aio_onComplete(struct io_event *events, int n) { int i, argc; int64_t ret; struct iocb *iocb; zval *retval; zval *zcontent; zval **args[2]; swoole_async_request *req; MAKE_STD_ZVAL(zcontent); TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); for (i = 0; i < n; i++) { iocb = (struct iocb *) events[i].obj; if(zend_hash_find(&php_sw_aio_callback, (char *)&(iocb->aio_fildes), sizeof(iocb->aio_fildes), (void**)&req) != SUCCESS) { zend_error(E_WARNING, "swoole_async: onAsyncComplete callback not found[1]"); return; } if (req->callback == NULL && req->type == IOCB_CMD_PREAD) { zend_error(E_WARNING, "swoole_async: onAsyncComplete callback not found[2]"); return; } ret = (int64_t) events[i].res; if (ret < 0) { zend_error(E_WARNING, "swoole_async: Aio Error: %s[%d]", strerror((-ret)), (int) ret); return; } if (ret < req->content_length) { zend_error(E_WARNING, "swoole_async: return length < req->length."); } args[0] = &req->filename; if (req->type == IOCB_CMD_PREAD) { ZVAL_STRINGL(zcontent, req->file_content, ret, 0); args[1] = &zcontent; argc = 2; } else { argc = 1; } if (call_user_function_ex(EG(function_table), NULL, req->callback, &retval, argc, args, 0, NULL TSRMLS_CC) == FAILURE) { zend_error(E_WARNING, "swoole_async: onAsyncComplete handler error"); return; } //readfile/writefile 只操作一次,完成后释放缓存区并关闭文件 if (req->once == 1) { free(req->file_content); close(iocb->aio_fildes); } //free(iocb); } zval_ptr_dtor(&zcontent); }
ZEND_METHOD( alinq_class , GroupBy ) { zend_fcall_info fci; zend_fcall_info_cache fci_cache; zend_class_entry *ce; ce = Z_OBJCE_P(getThis()); zval * reVal; zval * resultArray; MAKE_STD_ZVAL(resultArray); array_init(resultArray); zval *retval_ptr = NULL; zval *returnObj; zval *dataSource, **tmpns; char aReturnType; int aReturnTypeLen; // aReturnType = 'bool'; //取得数组 dataSource = zend_read_property(ce, getThis(), "dataSource", sizeof("dataSource")-1, 0 TSRMLS_DC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", &fci, &fci_cache) == FAILURE) { return; } while (zend_hash_get_current_data(Z_ARRVAL_P(dataSource), (void **)&tmpns) == SUCCESS) { char *key; uint keylen; ulong idx; int type; zval **ppzval, tmpcopy; zval **item,*item1; MAKE_STD_ZVAL(item1); array_init(item1); item = &item1; // php_printf("step-\n"); // if(count>0 && i>=count){ //只循环count次 // break; // } type = zend_hash_get_current_key_ex(Z_ARRVAL_P(dataSource), &key, &keylen,&idx, 0, NULL); //重新copy一个zval,防止破坏原数据 tmpcopy = **tmpns; zval_copy_ctor(&tmpcopy); INIT_PZVAL(&tmpcopy); // convert_to_string(&tmpcopy); walu_call_anony_function(&retval_ptr, NULL, fci, "sz", key, keylen,&tmpcopy); if(zend_hash_find(Z_ARRVAL_P(resultArray), Z_STRVAL_P(retval_ptr),sizeof(Z_STRVAL_P(retval_ptr)), (void **)&item) == FAILURE && IS_STRING==Z_TYPE_P(retval_ptr)) { // php_printf("step0\n"); // zend_error(E_ERROR, "element not found"); // MAKE_STD_ZVAL(item); // array_init(item); add_assoc_zval(resultArray, Z_STRVAL_P(retval_ptr), *item); } // PHPWRITE(Z_STRVAL_P(retval_ptr),strlen(Z_STRVAL_P(retval_ptr))); // php_printf("step1\n"); if( IS_ARRAY!=Z_TYPE_PP(item)){ php_printf("not array\n"); continue; } // add_assoc_zval(resultArray, retval_ptr, *tmpns); add_next_index_zval(*item,*tmpns); // /* Toss out old copy */ zval_dtor(&tmpcopy); zend_hash_move_forward(Z_ARRVAL_P(dataSource)); } walu_call_user_function(&returnObj, getThis(), "Instance", "z", resultArray); RETURN_ZVAL(returnObj,1,1); return; }
PHP_METHOD(Edge_Controller, model) { char *model_name = NULL; char *model_dir = NULL; int mnlen=0; int mdlen=0; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &model_name, &mnlen, &model_dir, &mdlen) == FAILURE) { RETURN_FALSE; } char *model_class_name; int class_name_len; class_name_len = spprintf(&model_class_name, 0, "%s%s", model_name, "Model"); zval **z_obj; if(zend_hash_find(Z_ARRVAL_P(EDGE_G(regs)), model_class_name, class_name_len+1, (void **)&z_obj) == SUCCESS) { efree(model_class_name); RETURN_ZVAL(*z_obj, 1, 0); } zval *config; zval *config_data; config = zend_read_static_property(edge_core_ce, ZEND_STRL("config"), 1 TSRMLS_DC); config_data = zend_read_property(edge_config_ce, config, ZEND_STRL("_data"), 1 TSRMLS_DC); zval **models_home_pp; if(zend_hash_find(Z_ARRVAL_P(config_data), "_models_home", strlen("_models_home")+1, (void **)&models_home_pp) == FAILURE) { RETURN_FALSE; } zval *z_model_name; MAKE_STD_ZVAL(z_model_name); ZVAL_STRING(z_model_name, model_class_name, 1); zval *loader; zval *ret; loader = zend_read_static_property(edge_core_ce, ZEND_STRL("loader"), 1 TSRMLS_DC); zend_call_method_with_2_params(&loader, Z_OBJCE_P(loader), NULL, "autoload", &ret, z_model_name, *models_home_pp); zval_ptr_dtor(&z_model_name); if(!Z_BVAL_P(ret)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "model %s%s load fail", Z_STRVAL_PP(models_home_pp), model_class_name); zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "model %s%s load fail", Z_STRVAL_PP(models_home_pp), model_class_name); zval_ptr_dtor(&ret); efree(model_class_name); RETURN_FALSE; } zval_ptr_dtor(&ret); zend_class_entry **model_ce; if(zend_lookup_class(model_class_name, class_name_len, &model_ce TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "model class %s not exist", model_class_name); zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "model class %s%s not exist", model_class_name); efree(model_class_name); RETURN_FALSE; } zval *model_obj; MAKE_STD_ZVAL(model_obj); object_init_ex(model_obj, *model_ce); zval **cfptr; if(zend_hash_find(&((*model_ce)->function_table), "__construct", strlen("__construct")+1, (void **)&cfptr) == SUCCESS) { zval *cretval; zend_call_method(&model_obj, *model_ce, NULL, "__construct", strlen("__construct"), &cretval, 0, NULL, NULL TSRMLS_CC); zval_ptr_dtor(&cretval); } zend_hash_update(Z_ARRVAL_P(EDGE_G(regs)), model_class_name, class_name_len+1, (void **)&model_obj, sizeof(zval *), NULL); efree(model_class_name); RETURN_ZVAL(model_obj, 1, 0); }
/* Returns the bytes read on success * Returns -31 on unknown failure * Returns -80 on timeout * Returns -32 when remote server closes the connection */ int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message) { int num = 1, received = 0; TSRMLS_FETCH(); int socketTimeoutMS = options->socketTimeoutMS ? options->socketTimeoutMS : FG(default_socket_timeout) * 1000; /* Convert negative values to -1 second, which implies no timeout */ socketTimeoutMS = socketTimeoutMS < 0 ? -1000 : socketTimeoutMS; timeout = timeout < 0 ? -1000 : timeout; /* Socket timeout behavior varies based on the following: * - Negative => no timeout (i.e. block indefinitely) * - Zero => not specified (no changes to existing configuration) * - Positive => used specified timeout (revert to previous value later) */ if (timeout && timeout != socketTimeoutMS) { struct timeval rtimeout = {0, 0}; rtimeout.tv_sec = timeout / 1000; rtimeout.tv_usec = (timeout % 1000) * 1000; php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout); mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "Setting the stream timeout to %d.%06d", rtimeout.tv_sec, rtimeout.tv_usec); } else { mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "No timeout changes for %s", con->hash); } php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_READ, 0, size TSRMLS_CC); /* this can return FAILED if there is just no more data from db */ while (received < size && num > 0) { int len = 4096 < (size - received) ? 4096 : size - received; ERROR_HANDLER_DECLARATION(error_handler) ERROR_HANDLER_REPLACE(error_handler, mongo_ce_ConnectionException); num = php_stream_read(con->socket, (char *) data, len); ERROR_HANDLER_RESTORE(error_handler); if (num < 0) { /* Doesn't look like this can happen, php_sockop_read overwrites * the failure from recv() to return 0 */ *error_message = strdup("Read from socket failed"); return -31; } /* It *may* have failed. It also may simply have no data */ if (num == 0) { zval *metadata; MAKE_STD_ZVAL(metadata); array_init(metadata); if (php_stream_populate_meta_data(con->socket, metadata)) { zval **tmp; if (zend_hash_find(Z_ARRVAL_P(metadata), "timed_out", sizeof("timed_out"), (void**)&tmp) == SUCCESS) { convert_to_boolean_ex(tmp); if (Z_BVAL_PP(tmp)) { struct timeval rtimeout = {0, 0}; if (timeout > 0 && options->socketTimeoutMS != timeout) { rtimeout.tv_sec = timeout / 1000; rtimeout.tv_usec = (timeout % 1000) * 1000; } else { /* Convert timeout=-1 to -1second, which PHP interprets as no timeout */ int socketTimeoutMS = options->socketTimeoutMS == -1 ? -1000 : options->socketTimeoutMS; rtimeout.tv_sec = socketTimeoutMS / 1000; rtimeout.tv_usec = (socketTimeoutMS % 1000) * 1000; } *error_message = malloc(256); snprintf(*error_message, 256, "Read timed out after reading %d bytes, waited for %d.%06d seconds", num, rtimeout.tv_sec, rtimeout.tv_usec); zval_ptr_dtor(&metadata); return -80; } } if (zend_hash_find(Z_ARRVAL_P(metadata), "eof", sizeof("eof"), (void**)&tmp) == SUCCESS) { convert_to_boolean_ex(tmp); if (Z_BVAL_PP(tmp)) { *error_message = strdup("Remote server has closed the connection"); zval_ptr_dtor(&metadata); return -32; } } } zval_ptr_dtor(&metadata); } data = (char*)data + num; received += num; } /* PHP may have sent notify-progress of *more then* 'received' in some * cases. * PHP will read 8192 byte chunks at a time, but if we request less data * then that PHP will just buffer the rest, which is fine. It could * confuse users a little, why their progress update was higher then the * max-bytes-expected though... */ php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_COMPLETED, received, size TSRMLS_CC); /* If the timeout was changed, revert to the previous value now */ if (timeout && timeout != socketTimeoutMS) { struct timeval rtimeout = {0, 0}; /* If socketTimeoutMS was never specified, revert to default_socket_timeout */ if (options->socketTimeoutMS == 0) { mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "Stream timeout will be reverted to default_socket_timeout (%d)", FG(default_socket_timeout)); } rtimeout.tv_sec = socketTimeoutMS / 1000; rtimeout.tv_usec = (socketTimeoutMS % 1000) * 1000; php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout); mongo_manager_log(MonGlo(manager), MLOG_CON, MLOG_FINE, "Now setting stream timeout back to %d.%06d", rtimeout.tv_sec, rtimeout.tv_usec); } return received; }
static int apply_to_cursor(zval *cursor, apply_copy_func_t apply_copy_func, void *to, int max TSRMLS_DC) { int total = 0; zval *next; MAKE_STD_ZVAL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); if (EG(exception)) { return FAILURE; } if (Z_TYPE_P(next) != IS_ARRAY) { zval_ptr_dtor(&next); return FAILURE; } while (Z_TYPE_P(next) == IS_ARRAY) { zval **zdata; /* Check if data field exists. If it doesn't, we've probably got an * error message from the db, so return that */ if (zend_hash_find(HASH_P(next), "data", 5, (void**)&zdata) == FAILURE) { if (zend_hash_exists(HASH_P(next), "$err", 5)) { zval_ptr_dtor(&next); return FAILURE; } continue; } /* This copies the next chunk -> *to * Due to a talent I have for not reading directions, older versions of * the driver store files as raw bytes, not MongoBinData. So, we'll * check for and handle both cases. */ if (Z_TYPE_PP(zdata) == IS_STRING) { /* raw bytes */ if (total + Z_STRLEN_PP(zdata) > max) { zend_throw_exception_ex(mongo_ce_GridFSException, 1 TSRMLS_CC, "There is more data associated with this file than the metadata specifies"); return FAILURE; } total += apply_copy_func(to, Z_STRVAL_PP(zdata), Z_STRLEN_PP(zdata)); } else if (Z_TYPE_PP(zdata) == IS_OBJECT && Z_OBJCE_PP(zdata) == mongo_ce_BinData) { /* MongoBinData */ zval *bin = zend_read_property(mongo_ce_BinData, *zdata, "bin", strlen("bin"), NOISY TSRMLS_CC); if (total + Z_STRLEN_P(bin) > max) { zval **n; if (zend_hash_find(HASH_P(next), "n", strlen("n") + 1, (void**)&n) == SUCCESS) { convert_to_long_ex(n); zend_throw_exception_ex(mongo_ce_GridFSException, 1 TSRMLS_CC, "There is more data associated with this file than the metadata specifies (reading chunk %d)", Z_LVAL_PP(n)); } else { zend_throw_exception_ex(mongo_ce_GridFSException, 1 TSRMLS_CC, "There is more data associated with this file than the metadata specifies"); } zval_ptr_dtor(&next); return FAILURE; } total += apply_copy_func(to, Z_STRVAL_P(bin), Z_STRLEN_P(bin)); } else { /* If it's not a string or a MongoBinData, give up */ zval_ptr_dtor(&next); return FAILURE; } /* get ready for the next iteration */ zval_ptr_dtor(&next); MAKE_STD_ZVAL(next); MONGO_METHOD(MongoCursor, getNext, next, cursor); } zval_ptr_dtor(&next); /* return the number of bytes copied */ return total; }
/* Returns the bytes read on success * Returns -31 on unknown failure * Returns -80 on timeout * Returns -32 when remote server closes the connection */ int php_mongo_io_stream_read(mongo_connection *con, mongo_server_options *options, int timeout, void *data, int size, char **error_message) { int num = 1, received = 0; TSRMLS_FETCH(); if (timeout > 0 && options->socketTimeoutMS != timeout) { struct timeval rtimeout = {0, 0}; rtimeout.tv_sec = timeout / 1000; rtimeout.tv_usec = (timeout % 1000) * 1000; php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout); } php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_READ, 0, size TSRMLS_CC); /* this can return FAILED if there is just no more data from db */ while (received < size && num > 0) { int len = 4096 < (size - received) ? 4096 : size - received; ERROR_HANDLER_DECLARATION(error_handler) ERROR_HANDLER_REPLACE(error_handler, mongo_ce_ConnectionException); num = php_stream_read(con->socket, (char *) data, len); ERROR_HANDLER_RESTORE(error_handler); if (num < 0) { /* Doesn't look like this can happen, php_sockop_read overwrites * the failure from recv() to return 0 */ *error_message = strdup("Read from socket failed"); return -31; } /* It *may* have failed. It also may simply have no data */ if (num == 0) { zval *metadata; MAKE_STD_ZVAL(metadata); array_init(metadata); if (php_stream_populate_meta_data(con->socket, metadata)) { zval **tmp; if (zend_hash_find(Z_ARRVAL_P(metadata), "timed_out", sizeof("timed_out"), (void**)&tmp) == SUCCESS) { convert_to_boolean_ex(tmp); if (Z_BVAL_PP(tmp)) { struct timeval rtimeout = {0, 0}; if (timeout > 0 && options->socketTimeoutMS != timeout) { rtimeout.tv_sec = timeout / 1000; rtimeout.tv_usec = (timeout % 1000) * 1000; } else { rtimeout.tv_sec = options->socketTimeoutMS / 1000; rtimeout.tv_usec = (options->socketTimeoutMS % 1000) * 1000; } *error_message = malloc(256); snprintf(*error_message, 256, "Read timed out after reading %d bytes, waited for %d.%06d seconds", num, rtimeout.tv_sec, rtimeout.tv_usec); zval_ptr_dtor(&metadata); return -80; } } if (zend_hash_find(Z_ARRVAL_P(metadata), "eof", sizeof("eof"), (void**)&tmp) == SUCCESS) { convert_to_boolean_ex(tmp); if (Z_BVAL_PP(tmp)) { *error_message = strdup("Remote server has closed the connection"); zval_ptr_dtor(&metadata); return -32; } } } zval_ptr_dtor(&metadata); } data = (char*)data + num; received += num; } /* PHP may have sent notify-progress of *more then* 'received' in some * cases. * PHP will read 8192 byte chunks at a time, but if we request less data * then that PHP will just buffer the rest, which is fine. It could * confuse users a little, why their progress update was higher then the * max-bytes-expected though... */ php_mongo_stream_notify_io(options, MONGO_STREAM_NOTIFY_IO_COMPLETED, received, size TSRMLS_CC); if (timeout > 0 && options->socketTimeoutMS != timeout) { struct timeval rtimeout = {0, 0}; rtimeout.tv_sec = options->socketTimeoutMS / 1000; rtimeout.tv_usec = (options->socketTimeoutMS % 1000) * 1000; php_stream_set_option(con->socket, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout); } return received; }
/* {{{ proto array accelerator_get_status([bool fetch_scripts]) Obtain statistics information regarding code acceleration */ static ZEND_FUNCTION(opcache_get_status) { long reqs; zval *memory_usage,*statistics,*scripts; zend_bool fetch_scripts = 1; /* keep the compiler happy */ (void)ht; (void)return_value_ptr; (void)this_ptr; (void)return_value_used; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &fetch_scripts) == FAILURE) { return; } if (!validate_api_restriction(TSRMLS_C)) { RETURN_FALSE; } if (!accel_startup_ok) { RETURN_FALSE; } array_init(return_value); /* Trivia */ add_assoc_bool(return_value, "opcache_enabled", ZCG(enabled) && (ZCG(counted) || ZCSG(accelerator_enabled))); add_assoc_bool(return_value, "cache_full", ZSMMG(memory_exhausted)); add_assoc_bool(return_value, "restart_pending", ZCSG(restart_pending)); add_assoc_bool(return_value, "restart_in_progress", ZCSG(restart_in_progress)); /* Memory usage statistics */ MAKE_STD_ZVAL(memory_usage); array_init(memory_usage); add_assoc_long(memory_usage, "used_memory", ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory)); add_assoc_long(memory_usage, "free_memory", zend_shared_alloc_get_free_memory()); add_assoc_long(memory_usage, "wasted_memory", ZSMMG(wasted_shared_memory)); add_assoc_double(memory_usage, "current_wasted_percentage", (((double) ZSMMG(wasted_shared_memory))/ZCG(accel_directives).memory_consumption)*100.0); add_assoc_zval(return_value, "memory_usage", memory_usage); #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO if (ZCSG(interned_strings_start) && ZCSG(interned_strings_end) && ZCSG(interned_strings_top)) { zval *interned_strings_usage; MAKE_STD_ZVAL(interned_strings_usage); array_init(interned_strings_usage); add_assoc_long(interned_strings_usage, "buffer_size", ZCSG(interned_strings_end) - ZCSG(interned_strings_start)); add_assoc_long(interned_strings_usage, "used_memory", ZCSG(interned_strings_top) - ZCSG(interned_strings_start)); add_assoc_long(interned_strings_usage, "free_memory", ZCSG(interned_strings_end) - ZCSG(interned_strings_top)); add_assoc_long(interned_strings_usage, "number_of_strings", ZCSG(interned_strings).nNumOfElements); add_assoc_zval(return_value, "interned_strings_usage", interned_strings_usage); } #endif /* Accelerator statistics */ MAKE_STD_ZVAL(statistics); array_init(statistics); add_assoc_long(statistics, "num_cached_scripts", ZCSG(hash).num_direct_entries); add_assoc_long(statistics, "num_cached_keys", ZCSG(hash).num_entries); add_assoc_long(statistics, "max_cached_keys", ZCSG(hash).max_num_entries); add_assoc_long(statistics, "hits", ZCSG(hits)); add_assoc_long(statistics, "start_time", ZCSG(start_time)); add_assoc_long(statistics, "last_restart_time", ZCSG(last_restart_time)); add_assoc_long(statistics, "oom_restarts", ZCSG(oom_restarts)); add_assoc_long(statistics, "hash_restarts", ZCSG(hash_restarts)); add_assoc_long(statistics, "manual_restarts", ZCSG(manual_restarts)); add_assoc_long(statistics, "misses", ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses)); add_assoc_long(statistics, "blacklist_misses", ZCSG(blacklist_misses)); reqs = ZCSG(hits)+ZCSG(misses); add_assoc_double(statistics, "blacklist_miss_ratio", reqs?(((double) ZCSG(blacklist_misses))/reqs)*100.0:0); add_assoc_double(statistics, "opcache_hit_rate", reqs?(((double) ZCSG(hits))/reqs)*100.0:0); add_assoc_zval(return_value, "opcache_statistics", statistics); if (fetch_scripts) { /* accelerated scripts */ scripts = accelerator_get_scripts(TSRMLS_C); if (scripts) { add_assoc_zval(return_value, "scripts", scripts); } } }
static void php_facedetect(INTERNAL_FUNCTION_PARAMETERS, int return_type) { char *file, *casc; long flen, clen; zval *array; CvHaarClassifierCascade* cascade; IplImage *img, *gray; CvMemStorage *storage; CvSeq *faces; CvRect *rect; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &file, &flen, &casc, &clen) == FAILURE) { RETURN_NULL(); } img = cvLoadImage(file, 1); if(!img) { RETURN_FALSE; } cascade = (CvHaarClassifierCascade*)cvLoad(casc, 0, 0, 0); if(!cascade) { RETURN_FALSE; } gray = cvCreateImage(cvSize(img->width, img->height), 8, 1); cvCvtColor(img, gray, CV_BGR2GRAY); cvEqualizeHist(gray, gray); storage = cvCreateMemStorage(0); faces = cvHaarDetectObjects(gray, cascade, storage, 1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(0, 0), cvSize(0, 0)); if(return_type) { array_init(return_value); if(faces && faces->total > 0) { int i; for(i = 0; i < faces->total; i++) { MAKE_STD_ZVAL(array); array_init(array); rect = (CvRect *)cvGetSeqElem(faces, i); add_assoc_long(array, "x", rect->x); add_assoc_long(array, "y", rect->y); add_assoc_long(array, "w", rect->width); add_assoc_long(array, "h", rect->height); add_next_index_zval(return_value, array); } } } else { RETVAL_LONG(faces ? faces->total : 0); } cvReleaseMemStorage(&storage); cvReleaseImage(&gray); cvReleaseImage(&img); }
PHP_METHOD(Rows, nextPage) { zval* timeout = NULL; cassandra_session* session = NULL; CassFuture* future = NULL; const CassResult* result = NULL; cassandra_rows* rows = NULL; cassandra_future_rows* future_rows = NULL; cassandra_rows* self = (cassandra_rows*) zend_object_store_get_object(getThis() TSRMLS_CC); if (self->next_page) { RETURN_ZVAL(self->next_page, 1, 0); } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z", &timeout) == FAILURE) { return; } if (self->future_next_page) { if (!instanceof_function(Z_OBJCE_P(self->future_next_page), cassandra_future_rows_ce TSRMLS_CC)) { zend_throw_exception_ex(cassandra_runtime_exception_ce, 0 TSRMLS_CC, "Unexpected future instance."); return; } future_rows = (cassandra_future_rows*) zend_object_store_get_object(self->future_next_page TSRMLS_CC); if (php_cassandra_future_wait_timed(future_rows->future, timeout TSRMLS_CC) == FAILURE) { return; } if (php_cassandra_future_is_error(future_rows->future TSRMLS_CC) == FAILURE) { return; } result = cass_future_get_result(future_rows->future); } else { if (self->result == NULL) { return; } ASSERT_SUCCESS(cass_statement_set_paging_state((CassStatement*) self->statement->data, self->result)); session = (cassandra_session*) zend_object_store_get_object(self->session TSRMLS_CC); future = cass_session_execute(session->session, (CassStatement*) self->statement->data); if (php_cassandra_future_wait_timed(future, timeout TSRMLS_CC) == FAILURE) { return; } if (php_cassandra_future_is_error(future TSRMLS_CC) == FAILURE) { return; } result = cass_future_get_result(future); cass_future_free(future); } if (!result) { zend_throw_exception_ex(cassandra_runtime_exception_ce, 0 TSRMLS_CC, "Future doesn't contain a result."); return; } MAKE_STD_ZVAL(self->next_page); object_init_ex(self->next_page, cassandra_rows_ce); rows = (cassandra_rows*) zend_object_store_get_object(self->next_page TSRMLS_CC); if (php_cassandra_get_result(result, &rows->rows TSRMLS_CC) == FAILURE) { cass_result_free(result); zval_dtor(self->next_page); self->next_page = NULL; return; } if (self->future_next_page) { zval_ptr_dtor(&self->future_next_page); self->future_next_page = NULL; } if (cass_result_has_more_pages(result)) { Z_ADDREF_P(self->session); rows->statement = php_cassandra_add_ref(self->statement); rows->session = self->session; rows->result = result; } else { cass_result_free(result); } php_cassandra_rows_clear(self); RETURN_ZVAL(self->next_page, 1, 0); }
php_ret samphp::parse_args(zval **params, zend_uint *count, char *argspec, va_list ap) { int i = 0; for(char *trav = argspec; *trav; trav++) { MAKE_STD_ZVAL(params[i]); switch(*trav) { case 'b': { // va promotes bools to ints int arg = va_arg(ap, int); ZVAL_BOOL(params[i], arg); } break; case 'i': { int arg = va_arg(ap, int); ZVAL_LONG(params[i], arg); } break; case 'l': { long arg = va_arg(ap, long); ZVAL_LONG(params[i], arg); } break; case 'd': { double arg = va_arg(ap, double); ZVAL_DOUBLE(params[i], arg); } break; case 's': { char *arg = va_arg(ap, char *); ZVAL_STRING(params[i], arg, 1); } break; case 'S': { char *arg = va_arg(ap, char *); unsigned int binStrLen = va_arg(ap, unsigned int); ZVAL_STRINGL(params[i], arg, binStrLen, 1); } break; default: status = FAIL; return status; } i++; } *count = i; return SUCCESS; }
static void php_swoole_aio_onComplete(swAio_event *event) { int isEOF = SW_FALSE; int64_t ret; zval *retval = NULL, *zcallback = NULL, *zwriten = NULL; zval *zcontent = NULL; zval **args[2]; swoole_async_file_request *file_req = NULL; swoole_async_dns_request *dns_req = NULL; TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); if (event->type == SW_AIO_DNS_LOOKUP) { dns_req = (swoole_async_dns_request *) event->req; if (dns_req->callback == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[2]"); return; } zcallback = dns_req->callback; } else { if (zend_hash_find(&php_sw_aio_callback, (char *)&(event->fd), sizeof(event->fd), (void**) &file_req) != SUCCESS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[1]"); return; } if (file_req->callback == NULL && file_req->type == SW_AIO_READ) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete callback not found[2]"); return; } zcallback = file_req->callback; } ret = event->ret; if (ret < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: Aio Error: %s[%d]", strerror(event->error), event->error); } else if (file_req != NULL) { if (ret == 0) { bzero(event->buf, event->nbytes); isEOF = SW_TRUE; } else if (file_req->once == 1 && ret < file_req->content_length) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: ret_length[%d] < req->length[%d].", (int) ret, file_req->content_length); } else if (event->type == SW_AIO_READ) { file_req->offset += event->ret; } } if (event->type == SW_AIO_READ) { MAKE_STD_ZVAL(zcontent); args[0] = &file_req->filename; args[1] = &zcontent; ZVAL_STRINGL(zcontent, event->buf, ret, 0); } else if (event->type == SW_AIO_WRITE) { MAKE_STD_ZVAL(zwriten); args[0] = &file_req->filename; args[1] = &zwriten; ZVAL_LONG(zwriten, ret); if (file_req->once != 1) { if (SwooleAIO.mode == SW_AIO_LINUX) { free(event->buf); } else { efree(event->buf); } } } else if(event->type == SW_AIO_DNS_LOOKUP) { MAKE_STD_ZVAL(zcontent); args[0] = &dns_req->domain; if (ret < 0) { ZVAL_STRING(zcontent, "", 0); } else { ZVAL_STRING(zcontent, event->buf, 0); } args[1] = &zcontent; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete unknow event type"); return; } if (zcallback) { if (call_user_function_ex(EG(function_table), NULL, zcallback, &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: onAsyncComplete handler error"); return; } } //readfile/writefile if (file_req != NULL) { //只操作一次,完成后释放缓存区并关闭文件 if (file_req->once == 1) { close_file: zval_ptr_dtor(&file_req->callback); zval_ptr_dtor(&file_req->filename); if (SwooleAIO.mode == SW_AIO_LINUX) { free(event->buf); } else { efree(event->buf); } close(event->fd); //remove from hashtable zend_hash_del(&php_sw_aio_callback, (char *)&(event->fd), sizeof(event->fd)); } else if(file_req->type == SW_AIO_WRITE) { if (retval != NULL && !Z_BVAL_P(retval)) { swHashMap_del(php_swoole_open_files, Z_STRVAL_P(file_req->filename), Z_STRLEN_P(file_req->filename)); goto close_file; } } else { if (!Z_BVAL_P(retval) || isEOF) { goto close_file; } else if (SwooleAIO.read(event->fd, event->buf, event->nbytes, file_req->offset) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "swoole_async: continue to read failed. Error: %s[%d]", strerror(event->error), event->error); } } } else if (dns_req != NULL) { zval_ptr_dtor(&dns_req->callback); zval_ptr_dtor(&dns_req->domain); efree(dns_req); efree(event->buf); } if (zcontent != NULL) { efree(zcontent); } if (zwriten != NULL) { zval_ptr_dtor(&zwriten); } if (retval != NULL) { zval_ptr_dtor(&retval); } if (php_sw_in_client && SwooleG.main_reactor->event_num == 1 && SwooleAIO.task_num == 1) { SwooleG.running = 0; } }
PHP_METHOD(MongoGridFS, __construct) { zval *zdb, *files = 0, *chunks = 0, *zchunks; zval *z_w = NULL; // chunks is deprecated if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|zz", &zdb, mongo_ce_DB, &files, &chunks) == FAILURE) { zval *object = getThis(); ZVAL_NULL(object); return; } if (!files && !chunks) { MAKE_STD_ZVAL(files); ZVAL_STRING(files, "fs.files", 1); MAKE_STD_ZVAL(chunks); ZVAL_STRING(chunks, "fs.chunks", 1); } else { zval *temp_file; char *temp; if (Z_TYPE_P(files) != IS_STRING || Z_STRLEN_P(files) == 0 ) { #if ZEND_MODULE_API_NO >= 20060613 zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "MongoGridFS::__construct(): invalid prefix"); #else zend_throw_exception_ex(zend_exception_get_default(), 0 TSRMLS_CC, "MongoGridFS::__construct(): invalid prefix"); #endif /* ZEND_MODULE_API_NO >= 20060613 */ return; } MAKE_STD_ZVAL(chunks); spprintf(&temp, 0, "%s.chunks", Z_STRVAL_P(files)); ZVAL_STRING(chunks, temp, 0); MAKE_STD_ZVAL(temp_file); spprintf(&temp, 0, "%s.files", Z_STRVAL_P(files)); ZVAL_STRING(temp_file, temp, 0); files = temp_file; } // create files collection MONGO_METHOD2(MongoCollection, __construct, return_value, getThis(), zdb, files); // create chunks collection MAKE_STD_ZVAL(zchunks); object_init_ex(zchunks, mongo_ce_Collection); MONGO_METHOD2(MongoCollection, __construct, return_value, zchunks, zdb, chunks); // add chunks collection as a property zend_update_property(mongo_ce_GridFS, getThis(), "chunks", strlen("chunks"), zchunks TSRMLS_CC); zend_update_property(mongo_ce_GridFS, getThis(), "filesName", strlen("filesName"), files TSRMLS_CC); zend_update_property(mongo_ce_GridFS, getThis(), "chunksName", strlen("chunksName"), chunks TSRMLS_CC); /* GridFS is forced in our codebase to be w=1 so this property doesn't actually mean * anything, but we can't lie to the user so we have to overwrite it if the MongoDB * object that created this object was w=0. * This property is initialized in the MongoCollection (which we extend) ctor */ z_w = zend_read_property(mongo_ce_GridFS, getThis(), "w", strlen("w"), NOISY TSRMLS_CC); if (Z_TYPE_P(z_w) != IS_STRING) { convert_to_long(z_w); if (Z_LVAL_P(z_w) < 2) { zend_update_property_long(mongo_ce_GridFS, getThis(), "w", strlen("w"), 1 TSRMLS_CC); } } // cleanup zval_ptr_dtor(&zchunks); zval_ptr_dtor(&files); zval_ptr_dtor(&chunks); }
/* {{{ proto array Riak\Bucket->indexQuery(IndexQuery $query[, IndexInput $input]) Apply given properties to this bucket */ PHP_METHOD(RiakBucket, indexQuery) { riak_connection *connection; riack_2i_query_req req; riack_string_list *result_keys; riack_string *continuation, *type; zval *zquery, *zinput, *zname, *zisrange, *zcontinuation, *zresult; int riackstatus; zinput = zquery = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|O", &zquery, riak_index_query_ce, &zinput, riak_index_input_ce) == FAILURE) { zend_throw_exception(riak_badarguments_exception_ce, "Bad or missing argument", 500 TSRMLS_CC); return; } // TODO Validate query have exact or ranged values connection = get_riak_connection(getThis() TSRMLS_CC); THROW_EXCEPTION_IF_CONNECTION_IS_NULL(connection); memset(&req, 0, sizeof(req)); type = riack_get_bucket_type_from_bucket(connection->client, getThis() TSRMLS_CC); if (type != NULL) { req.bucket_type.len = type->len; req.bucket_type.value = type->value; } req.bucket = riack_name_from_bucket(getThis() TSRMLS_CC); MAKE_STD_ZVAL(zname); RIAK_CALL_METHOD(Riak_Query_IndexQuery, getName, zname, zquery); req.index.len = Z_STRLEN_P(zname); req.index.value = Z_STRVAL_P(zname); continuation = NULL; zcontinuation = NULL; if (zinput) { zval *zmaxresults; MAKE_STD_ZVAL(zmaxresults); RIAK_CALL_METHOD(Riak_Input_IndexInput, getMaxResults, zmaxresults, zinput); if (Z_TYPE_P(zmaxresults) == IS_LONG) { req.max_results = Z_LVAL_P(zmaxresults); } zval_ptr_dtor(&zmaxresults); MAKE_STD_ZVAL(zcontinuation); RIAK_CALL_METHOD(Riak_Input_IndexInput, getContinuation, zcontinuation, zinput); if (Z_TYPE_P(zcontinuation) == IS_STRING) { req.continuation_token.len = Z_STRLEN_P(zcontinuation); req.continuation_token.value = Z_STRVAL_P(zcontinuation); } } MAKE_STD_ZVAL(zisrange); RIAK_CALL_METHOD(Riak_Query_IndexQuery, isRangeQuery, zisrange, zquery); if (Z_BVAL_P(zisrange)) { zval *zmin, *zmax; // TODO Call getter instead, this is cheat zmin = zend_read_property(riak_index_query_ce, zquery, "minValue", sizeof("minValue")-1, 1 TSRMLS_CC); zmax = zend_read_property(riak_index_query_ce, zquery, "maxValue", sizeof("maxValue")-1, 1 TSRMLS_CC); req.search_min.len = Z_STRLEN_P(zmin); req.search_min.value = Z_STRVAL_P(zmin); req.search_max.len = Z_STRLEN_P(zmax); req.search_max.value = Z_STRVAL_P(zmax); RIACK_RETRY_OP(riackstatus, connection, riack_2i_query(connection->client, &req, &result_keys, &continuation)); } else { zval *zexact; zexact = zend_read_property(riak_index_query_ce, zquery, "exactValue", sizeof("exactValue")-1, 1 TSRMLS_CC); req.search_exact.len = Z_STRLEN_P(zexact); req.search_exact.value = Z_STRVAL_P(zexact); RIACK_RETRY_OP(riackstatus, connection, riack_2i_query(connection->client, &req, &result_keys, &continuation)); } zval_ptr_dtor(&zname); zval_ptr_dtor(&zisrange); if (zcontinuation) { zval_ptr_dtor(&zcontinuation); } RFREE(connection->client, type); CHECK_RIACK_STATUS_THROW_AND_RETURN_ON_ERROR(connection, riackstatus); zresult = riak_index_output_from_string_list_and_continuation(result_keys, continuation TSRMLS_CC); riack_free_string_p(connection->client, &continuation); riack_free_string_list_p(connection->client, &result_keys); RETURN_ZVAL(zresult, 0, 1); }
PHP_SUHOSIN_API void suhosin_log(int loglevel, char *fmt, ...) { int s, r, i=0, fd; long written, towrite; int getcaller=0; char *wbuf; struct timeval tv; time_t now; struct tm tm; #if defined(AF_UNIX) struct sockaddr_un saun; #endif #ifdef PHP_WIN32 LPTSTR strs[2]; unsigned short etype; DWORD evid; #endif char buf[5000]; char error[5000]; char *ip_address; char *fname; char *alertstring; int lineno; va_list ap; TSRMLS_FETCH(); #if PHP_VERSION_ID >= 50500 getcaller = (loglevel & S_GETCALLER) == S_GETCALLER; #endif /* remove the S_GETCALLER flag */ loglevel = loglevel & ~S_GETCALLER; SDEBUG("(suhosin_log) loglevel: %d log_syslog: %u - log_sapi: %u - log_script: %u", loglevel, SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script)); /* dump core if wanted */ if (SUHOSIN_G(coredump) && loglevel == S_MEMORY) { volatile unsigned int *x = 0; volatile int y = *x; } if (SUHOSIN_G(log_use_x_forwarded_for)) { ip_address = suhosin_getenv("HTTP_X_FORWARDED_FOR", 20 TSRMLS_CC); if (ip_address == NULL) { ip_address = "X-FORWARDED-FOR not set"; } } else { ip_address = suhosin_getenv("REMOTE_ADDR", 11 TSRMLS_CC); if (ip_address == NULL) { ip_address = "REMOTE_ADDR not set"; } } va_start(ap, fmt); ap_php_vsnprintf(error, sizeof(error), fmt, ap); va_end(ap); while (error[i]) { if (error[i] < 32) error[i] = '.'; i++; } if (SUHOSIN_G(simulation)) { alertstring = "ALERT-SIMULATION"; } else { alertstring = "ALERT"; } if (zend_is_executing(TSRMLS_C)) { zend_execute_data *exdata = EG(current_execute_data); if (exdata) { if (getcaller && exdata->prev_execute_data) { lineno = exdata->prev_execute_data->opline->lineno; fname = (char *)exdata->prev_execute_data->op_array->filename; } else { lineno = exdata->opline->lineno; fname = (char *)exdata->op_array->filename; } } else { lineno = zend_get_executed_lineno(TSRMLS_C); fname = (char *)zend_get_executed_filename(TSRMLS_C); } ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s', line %u)", alertstring, error, ip_address, fname, lineno); } else { fname = suhosin_getenv("SCRIPT_FILENAME", 15 TSRMLS_CC); if (fname==NULL) { fname = "unknown"; } ap_php_snprintf(buf, sizeof(buf), "%s - %s (attacker '%s', file '%s')", alertstring, error, ip_address, fname); } /* Syslog-Logging disabled? */ if (((SUHOSIN_G(log_syslog)|S_INTERNAL) & loglevel)==0) { goto log_file; } #if defined(AF_UNIX) ap_php_snprintf(error, sizeof(error), "<%u>suhosin[%u]: %s\n", (unsigned int)(SUHOSIN_G(log_syslog_facility)|SUHOSIN_G(log_syslog_priority)),getpid(),buf); s = socket(AF_UNIX, SOCK_DGRAM, 0); if (s == -1) { goto log_file; } memset(&saun, 0, sizeof(saun)); saun.sun_family = AF_UNIX; strcpy(saun.sun_path, SYSLOG_PATH); /*saun.sun_len = sizeof(saun);*/ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); if (r) { close(s); s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) { goto log_file; } memset(&saun, 0, sizeof(saun)); saun.sun_family = AF_UNIX; strcpy(saun.sun_path, SYSLOG_PATH); /*saun.sun_len = sizeof(saun);*/ r = connect(s, (struct sockaddr *)&saun, sizeof(saun)); if (r) { close(s); goto log_file; } } send(s, error, strlen(error), 0); close(s); #endif #ifdef PHP_WIN32 ap_php_snprintf(error, sizeof(error), "suhosin[%u]: %s", getpid(),buf); switch (SUHOSIN_G(log_syslog_priority)) { /* translate UNIX type into NT type */ case 1: /*LOG_ALERT:*/ etype = EVENTLOG_ERROR_TYPE; break; case 6: /*LOG_INFO:*/ etype = EVENTLOG_INFORMATION_TYPE; break; default: etype = EVENTLOG_WARNING_TYPE; } evid = loglevel; strs[0] = error; /* report the event */ if (log_source == NULL) { log_source = RegisterEventSource(NULL, "Suhosin-" SUHOSIN_EXT_VERSION); } ReportEvent(log_source, etype, (unsigned short) SUHOSIN_G(log_syslog_priority), evid, NULL, 1, 0, strs, NULL); #endif log_file: /* File-Logging disabled? */ if ((SUHOSIN_G(log_file) & loglevel)==0) { goto log_sapi; } if (!SUHOSIN_G(log_filename) || !SUHOSIN_G(log_filename)[0]) { goto log_sapi; } fd = open(SUHOSIN_G(log_filename), O_CREAT|O_APPEND|O_WRONLY, 0640); if (fd == -1) { suhosin_log(S_INTERNAL, "Unable to open logfile: %s", SUHOSIN_G(log_filename)); return; } gettimeofday(&tv, NULL); now = tv.tv_sec; php_gmtime_r(&now, &tm); ap_php_snprintf(error, sizeof(error), "%s %2d %02d:%02d:%02d [%u] %s\n", month_names[tm.tm_mon], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, getpid(),buf); towrite = strlen(error); wbuf = error; php_flock(fd, LOCK_EX); while (towrite > 0) { written = write(fd, wbuf, towrite); if (written < 0) { break; } towrite -= written; wbuf += written; } php_flock(fd, LOCK_UN); close(fd); log_sapi: /* SAPI Logging activated? */ SDEBUG("(suhosin_log) log_syslog: %u - log_sapi: %u - log_script: %u - log_phpscript: %u", SUHOSIN_G(log_syslog), SUHOSIN_G(log_sapi), SUHOSIN_G(log_script), SUHOSIN_G(log_phpscript)); if (((SUHOSIN_G(log_sapi)|S_INTERNAL) & loglevel)!=0) { #if PHP_VERSION_ID < 50400 sapi_module.log_message(buf); #else sapi_module.log_message(buf TSRMLS_CC); #endif } if ((SUHOSIN_G(log_stdout) & loglevel)!=0) { printf("%s\n", buf); } /*log_script:*/ /* script logging activaed? */ if (((SUHOSIN_G(log_script) & loglevel)!=0) && SUHOSIN_G(log_scriptname)!=NULL) { char cmd[8192], *cmdpos, *bufpos; FILE *in; int space; struct stat st; char *sname = SUHOSIN_G(log_scriptname); while (isspace(*sname)) ++sname; if (*sname == 0) goto log_phpscript; if (VCWD_STAT(sname, &st) < 0) { suhosin_log(S_INTERNAL, "unable to find logging shell script %s - file dropped", sname); goto log_phpscript; } if (access(sname, X_OK|R_OK) < 0) { suhosin_log(S_INTERNAL, "logging shell script %s is not executable - file dropped", sname); goto log_phpscript; } /* TODO: clean up this code to calculate size of output dynamically */ ap_php_snprintf(cmd, sizeof(cmd) - 20, "%s %s \'", sname, loglevel2string(loglevel)); space = sizeof(cmd) - strlen(cmd) - 20; cmdpos = cmd + strlen(cmd); bufpos = buf; if (space <= 1) return; while (space > 2 && *bufpos) { if (*bufpos == '\'') { if (space<=5) break; *cmdpos++ = '\''; *cmdpos++ = '\\'; *cmdpos++ = '\''; *cmdpos++ = '\''; bufpos++; space-=4; } else { *cmdpos++ = *bufpos++; space--; } } *cmdpos++ = '\''; *cmdpos++ = ' '; *cmdpos++ = '2'; *cmdpos++ = '>'; *cmdpos++ = '&'; *cmdpos++ = '1'; *cmdpos = 0; if ((in=VCWD_POPEN(cmd, "r"))==NULL) { suhosin_log(S_INTERNAL, "Unable to execute logging shell script: %s", sname); goto log_phpscript; } /* read and forget the result */ while (1) { int readbytes = fread(cmd, 1, sizeof(cmd), in); if (readbytes<=0) { break; } if (strncmp(cmd, "sh: ", 4) == 0) { /* assume this is an error */ suhosin_log(S_INTERNAL, "Error while executing logging shell script: %s", sname); pclose(in); goto log_phpscript; } } pclose(in); } log_phpscript: if ((SUHOSIN_G(log_phpscript) & loglevel)!=0 && EG(in_execution) && SUHOSIN_G(log_phpscriptname) && SUHOSIN_G(log_phpscriptname)[0]) { zend_file_handle file_handle; zend_op_array *new_op_array; zval *result = NULL; long orig_execution_depth = SUHOSIN_G(execution_depth); #if PHP_VERSION_ID < 50400 zend_bool orig_safe_mode = PG(safe_mode); #endif char *orig_basedir = PG(open_basedir); char *phpscript = SUHOSIN_G(log_phpscriptname); SDEBUG("scriptname %s", SUHOSIN_G(log_phpscriptname)); #ifdef ZEND_ENGINE_2 if (zend_stream_open(phpscript, &file_handle TSRMLS_CC) == SUCCESS) { #else if (zend_open(phpscript, &file_handle) == SUCCESS && ZEND_IS_VALID_FILE_HANDLE(&file_handle)) { file_handle.filename = phpscript; file_handle.free_filename = 0; #endif if (!file_handle.opened_path) { file_handle.opened_path = estrndup(phpscript, strlen(phpscript)); } new_op_array = zend_compile_file(&file_handle, ZEND_REQUIRE TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); if (new_op_array) { HashTable *active_symbol_table = EG(active_symbol_table); zval *zerror, *zerror_class; if (active_symbol_table == NULL) { active_symbol_table = &EG(symbol_table); } EG(return_value_ptr_ptr) = &result; EG(active_op_array) = new_op_array; MAKE_STD_ZVAL(zerror); MAKE_STD_ZVAL(zerror_class); ZVAL_STRING(zerror, buf, 1); ZVAL_LONG(zerror_class, loglevel); zend_hash_update(active_symbol_table, "SUHOSIN_ERROR", sizeof("SUHOSIN_ERROR"), (void **)&zerror, sizeof(zval *), NULL); zend_hash_update(active_symbol_table, "SUHOSIN_ERRORCLASS", sizeof("SUHOSIN_ERRORCLASS"), (void **)&zerror_class, sizeof(zval *), NULL); SUHOSIN_G(execution_depth) = 0; if (SUHOSIN_G(log_phpscript_is_safe)) { #if PHP_VERSION_ID < 50400 PG(safe_mode) = 0; #endif PG(open_basedir) = NULL; } zend_execute(new_op_array TSRMLS_CC); SUHOSIN_G(execution_depth) = orig_execution_depth; #if PHP_VERSION_ID < 50400 PG(safe_mode) = orig_safe_mode; #endif PG(open_basedir) = orig_basedir; #ifdef ZEND_ENGINE_2 destroy_op_array(new_op_array TSRMLS_CC); #else destroy_op_array(new_op_array); #endif efree(new_op_array); #ifdef ZEND_ENGINE_2 if (!EG(exception)) #endif { if (EG(return_value_ptr_ptr)) { zval_ptr_dtor(EG(return_value_ptr_ptr)); EG(return_value_ptr_ptr) = NULL; } } } else { suhosin_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SUHOSIN_G(log_phpscriptname)); return; } } else { suhosin_log(S_INTERNAL, "Unable to execute logging PHP script: %s", SUHOSIN_G(log_phpscriptname)); return; } } }
void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval* return_value, HashTable* fieldspec) { zval** val_ptr; Z_TYPE_P(return_value) = IS_NULL; // just in case switch (thrift_typeID) { case T_STOP: case T_VOID: RETURN_NULL(); return; case T_STRUCT: { if (zend_hash_find(fieldspec, "class", 6, (void**)&val_ptr) != SUCCESS) { throw_tprotocolexception("no class type in spec", INVALID_DATA); skip_element(T_STRUCT, transport); RETURN_NULL(); } char* structType = Z_STRVAL_PP(val_ptr); createObject(structType, return_value); if (Z_TYPE_P(return_value) == IS_NULL) { // unable to create class entry skip_element(T_STRUCT, transport); RETURN_NULL(); } TSRMLS_FETCH(); zval* spec = zend_read_static_property(zend_get_class_entry(return_value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC); if (Z_TYPE_P(spec) != IS_ARRAY) { char errbuf[128]; snprintf(errbuf, 128, "spec for %s is wrong type: %d\n", structType, Z_TYPE_P(spec)); throw_tprotocolexception(errbuf, INVALID_DATA); RETURN_NULL(); } binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec)); return; } break; case T_BOOL: { uint8_t c; transport.readBytes(&c, 1); RETURN_BOOL(c != 0); } //case T_I08: // same numeric value as T_BYTE case T_BYTE: { uint8_t c; transport.readBytes(&c, 1); RETURN_LONG(c); } case T_I16: { uint16_t c; transport.readBytes(&c, 2); RETURN_LONG(ntohs(c)); } case T_I32: { uint32_t c; transport.readBytes(&c, 4); RETURN_LONG(ntohl(c)); } case T_U64: case T_I64: { uint64_t c; transport.readBytes(&c, 8); RETURN_LONG(ntohll(c)); } case T_DOUBLE: { union { uint64_t c; double d; } a; transport.readBytes(&(a.c), 8); a.c = ntohll(a.c); RETURN_DOUBLE(a.d); } //case T_UTF7: // aliases T_STRING case T_UTF8: case T_UTF16: case T_STRING: { uint32_t size = transport.readU32(); if (size) { char* strbuf = (char*) emalloc(size + 1); transport.readBytes(strbuf, size); strbuf[size] = '\0'; ZVAL_STRINGL(return_value, strbuf, size, 0); } else { ZVAL_EMPTY_STRING(return_value); } return; } case T_MAP: { // array of key -> value uint8_t types[2]; transport.readBytes(types, 2); uint32_t size = transport.readU32(); array_init(return_value); zend_hash_find(fieldspec, "key", 4, (void**)&val_ptr); HashTable* keyspec = Z_ARRVAL_PP(val_ptr); zend_hash_find(fieldspec, "val", 4, (void**)&val_ptr); HashTable* valspec = Z_ARRVAL_PP(val_ptr); for (uint32_t s = 0; s < size; ++s) { zval *value; MAKE_STD_ZVAL(value); zval* key; MAKE_STD_ZVAL(key); binary_deserialize(types[0], transport, key, keyspec); binary_deserialize(types[1], transport, value, valspec); if (Z_TYPE_P(key) == IS_LONG) { zend_hash_index_update(return_value->value.ht, Z_LVAL_P(key), &value, sizeof(zval *), NULL); } else { if (Z_TYPE_P(key) != IS_STRING) convert_to_string(key); zend_hash_update(return_value->value.ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL); } zval_ptr_dtor(&key); } return; // return_value already populated } case T_LIST: { // array with autogenerated numeric keys int8_t type = transport.readI8(); uint32_t size = transport.readU32(); zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr); HashTable* elemspec = Z_ARRVAL_PP(val_ptr); array_init(return_value); for (uint32_t s = 0; s < size; ++s) { zval *value; MAKE_STD_ZVAL(value); binary_deserialize(type, transport, value, elemspec); zend_hash_next_index_insert(return_value->value.ht, &value, sizeof(zval *), NULL); } return; } case T_SET: { // array of key -> TRUE uint8_t type; uint32_t size; transport.readBytes(&type, 1); transport.readBytes(&size, 4); size = ntohl(size); zend_hash_find(fieldspec, "elem", 5, (void**)&val_ptr); HashTable* elemspec = Z_ARRVAL_PP(val_ptr); array_init(return_value); for (uint32_t s = 0; s < size; ++s) { zval* key; zval* value; MAKE_STD_ZVAL(key); MAKE_STD_ZVAL(value); ZVAL_TRUE(value); binary_deserialize(type, transport, key, elemspec); if (Z_TYPE_P(key) == IS_LONG) { zend_hash_index_update(return_value->value.ht, Z_LVAL_P(key), &value, sizeof(zval *), NULL); } else { if (Z_TYPE_P(key) != IS_STRING) convert_to_string(key); zend_hash_update(return_value->value.ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL); } zval_ptr_dtor(&key); } return; } }; char errbuf[128]; sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID); throw_tprotocolexception(errbuf, INVALID_DATA); }
/* php_formatted_print() {{{ * New sprintf implementation for PHP. * * Modifiers: * * " " pad integers with spaces * "-" left adjusted field * n field size * "."n precision (floats only) * "+" Always place a sign (+ or -) in front of a number * * Type specifiers: * * "%" literal "%", modifiers are ignored. * "b" integer argument is printed as binary * "c" integer argument is printed as a single character * "d" argument is an integer * "f" the argument is a float * "o" integer argument is printed as octal * "s" argument is a string * "x" integer argument is printed as lowercase hexadecimal * "X" integer argument is printed as uppercase hexadecimal * */ static char * php_formatted_print(int ht, int *len, int use_array, int format_offset TSRMLS_DC) { zval ***args, **z_format; int argc, size = 240, inpos = 0, outpos = 0, temppos; int alignment, currarg, adjusting, argnum, width, precision; char *format, *result, padding; int always_sign; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) { return NULL; } /* verify the number of args */ if ((use_array && argc != (2 + format_offset)) || (!use_array && argc < (1 + format_offset))) { efree(args); WRONG_PARAM_COUNT_WITH_RETVAL(NULL); } if (use_array) { int i = 1; zval ***newargs; zval **array; z_format = args[format_offset]; array = args[1 + format_offset]; SEPARATE_ZVAL(array); convert_to_array_ex(array); argc = 1 + zend_hash_num_elements(Z_ARRVAL_PP(array)); newargs = (zval ***)safe_emalloc(argc, sizeof(zval *), 0); newargs[0] = z_format; for (zend_hash_internal_pointer_reset(Z_ARRVAL_PP(array)); zend_hash_get_current_data(Z_ARRVAL_PP(array), (void **)&newargs[i++]) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_PP(array))); efree(args); args = newargs; format_offset = 0; } convert_to_string_ex(args[format_offset]); format = Z_STRVAL_PP(args[format_offset]); result = emalloc(size); currarg = 1; while (inpos<Z_STRLEN_PP(args[format_offset])) { int expprec = 0, multiuse = 0; zval *tmp; PRINTF_DEBUG(("sprintf: format[%d]='%c'\n", inpos, format[inpos])); PRINTF_DEBUG(("sprintf: outpos=%d\n", outpos)); if (format[inpos] != '%') { php_sprintf_appendchar(&result, &outpos, &size, format[inpos++] TSRMLS_CC); } else if (format[inpos + 1] == '%') { php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC); inpos += 2; } else { /* starting a new format specifier, reset variables */ alignment = ALIGN_RIGHT; adjusting = 0; padding = ' '; always_sign = 0; inpos++; /* skip the '%' */ PRINTF_DEBUG(("sprintf: first looking at '%c', inpos=%d\n", format[inpos], inpos)); if (isascii((int)format[inpos]) && !isalpha((int)format[inpos])) { /* first look for argnum */ temppos = inpos; while (isdigit((int)format[temppos])) temppos++; if (format[temppos] == '$') { argnum = php_sprintf_getnumber(format, &inpos); if (argnum <= 0) { efree(result); efree(args); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument number must be greater than zero"); return NULL; } multiuse = 1; inpos++; /* skip the '$' */ } else { argnum = currarg++; } argnum += format_offset; /* after argnum comes modifiers */ PRINTF_DEBUG(("sprintf: looking for modifiers\n" "sprintf: now looking at '%c', inpos=%d\n", format[inpos], inpos)); for (;; inpos++) { if (format[inpos] == ' ' || format[inpos] == '0') { padding = format[inpos]; } else if (format[inpos] == '-') { alignment = ALIGN_LEFT; /* space padding, the default */ } else if (format[inpos] == '+') { always_sign = 1; } else if (format[inpos] == '\'') { padding = format[++inpos]; } else { PRINTF_DEBUG(("sprintf: end of modifiers\n")); break; } } PRINTF_DEBUG(("sprintf: padding='%c'\n", padding)); PRINTF_DEBUG(("sprintf: alignment=%s\n", (alignment == ALIGN_LEFT) ? "left" : "right")); /* after modifiers comes width */ if (isdigit((int)format[inpos])) { PRINTF_DEBUG(("sprintf: getting width\n")); if ((width = php_sprintf_getnumber(format, &inpos)) < 0) { efree(result); efree(args); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Width must be greater than zero and less than %d", INT_MAX); return NULL; } adjusting |= ADJ_WIDTH; } else { width = 0; } PRINTF_DEBUG(("sprintf: width=%d\n", width)); /* after width and argnum comes precision */ if (format[inpos] == '.') { inpos++; PRINTF_DEBUG(("sprintf: getting precision\n")); if (isdigit((int)format[inpos])) { if ((precision = php_sprintf_getnumber(format, &inpos)) < 0) { efree(result); efree(args); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Precision must be greater than zero and less than %d", INT_MAX); return NULL; } adjusting |= ADJ_PRECISION; expprec = 1; } else { precision = 0; } } else { precision = 0; } PRINTF_DEBUG(("sprintf: precision=%d\n", precision)); } else { width = precision = 0; argnum = currarg++ + format_offset; } if (argnum >= argc) { efree(result); efree(args); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too few arguments"); return NULL; } if (format[inpos] == 'l') { inpos++; } PRINTF_DEBUG(("sprintf: format character='%c'\n", format[inpos])); /* now we expect to find a type specifier */ if (multiuse) { MAKE_STD_ZVAL(tmp); *tmp = **(args[argnum]); INIT_PZVAL(tmp); zval_copy_ctor(tmp); } else { SEPARATE_ZVAL(args[argnum]); tmp = *(args[argnum]); } switch (format[inpos]) { case 's': { zval *var, var_copy; int use_copy; zend_make_printable_zval(tmp, &var_copy, &use_copy); if (use_copy) { var = &var_copy; } else { var = tmp; } php_sprintf_appendstring(&result, &outpos, &size, Z_STRVAL_P(var), width, precision, padding, alignment, Z_STRLEN_P(var), 0, expprec, 0); if (use_copy) { zval_dtor(&var_copy); } break; } case 'd': convert_to_long(tmp); php_sprintf_appendint(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, always_sign); break; case 'u': convert_to_long(tmp); php_sprintf_appenduint(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment); break; case 'g': case 'G': case 'e': case 'E': case 'f': case 'F': convert_to_double(tmp); php_sprintf_appenddouble(&result, &outpos, &size, Z_DVAL_P(tmp), width, padding, alignment, precision, adjusting, format[inpos], always_sign TSRMLS_CC); break; case 'c': convert_to_long(tmp); php_sprintf_appendchar(&result, &outpos, &size, (char) Z_LVAL_P(tmp) TSRMLS_CC); break; case 'o': convert_to_long(tmp); php_sprintf_append2n(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, 3, hexchars, expprec); break; case 'x': convert_to_long(tmp); php_sprintf_append2n(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, 4, hexchars, expprec); break; case 'X': convert_to_long(tmp); php_sprintf_append2n(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, 4, HEXCHARS, expprec); break; case 'b': convert_to_long(tmp); php_sprintf_append2n(&result, &outpos, &size, Z_LVAL_P(tmp), width, padding, alignment, 1, hexchars, expprec); break; case '%': php_sprintf_appendchar(&result, &outpos, &size, '%' TSRMLS_CC); break; default: break; } if (multiuse) { zval_ptr_dtor(&tmp); } inpos++; } } efree(args); /* possibly, we have to make sure we have room for the terminating null? */ result[outpos]=0; *len = outpos; return result; }
/* {{{ proto string MongoGridFSFile::getBytes() Returns this file's contents as a string of bytes */ PHP_METHOD(MongoGridFSFile, getBytes) { zval *file, *gridfs, *chunks, *query, *cursor, *sort, *temp; zval **id, **size; char *str, *str_ptr; int len; mongo_cursor *cursorobj; zval *flags; file = zend_read_property(mongo_ce_GridFSFile, getThis(), "file", strlen("file"), NOISY TSRMLS_CC); zend_hash_find(HASH_P(file), "_id", strlen("_id") + 1, (void**)&id); if (zend_hash_find(HASH_P(file), "length", strlen("length") + 1, (void**)&size) == FAILURE) { zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size", 14 TSRMLS_CC); return; } /* make sure that there's an index on chunks so we can sort by chunk num */ gridfs = zend_read_property(mongo_ce_GridFSFile, getThis(), "gridfs", strlen("gridfs"), NOISY TSRMLS_CC); chunks = zend_read_property(mongo_ce_GridFS, gridfs, "chunks", strlen("chunks"), NOISY TSRMLS_CC); MAKE_STD_ZVAL(temp); php_mongo_ensure_gridfs_index(temp, chunks TSRMLS_CC); zval_dtor(temp); /* query for chunks */ MAKE_STD_ZVAL(query); array_init(query); zval_add_ref(id); add_assoc_zval(query, "files_id", *id); MAKE_STD_ZVAL(cursor); MONGO_METHOD1(MongoCollection, find, cursor, chunks, query); /* Copy the flags from the original cursor and apply it to this one */ flags = zend_read_property(mongo_ce_GridFSFile, getThis(), "flags", strlen("flags"), NOISY TSRMLS_CC); cursorobj = (mongo_cursor*)zend_object_store_get_object(cursor TSRMLS_CC); convert_to_long(flags); cursorobj->opts = Z_LVAL_P(flags); MAKE_STD_ZVAL(sort); array_init(sort); add_assoc_long(sort, "n", 1); MONGO_METHOD1(MongoCursor, sort, temp, cursor, sort); zval_ptr_dtor(&temp); zval_ptr_dtor(&query); zval_ptr_dtor(&sort); if (Z_TYPE_PP(size) == IS_DOUBLE) { len = (int)Z_DVAL_PP(size); } else if (Z_TYPE_PP(size) == IS_LONG) { len = Z_LVAL_PP(size); } else if (Z_TYPE_PP(size) == IS_OBJECT && (Z_OBJCE_PP(size) == mongo_ce_Int32 || Z_OBJCE_PP(size) == mongo_ce_Int64)) { zval *sizet = zend_read_property(mongo_ce_Int64, *size, "value", strlen("value"), NOISY TSRMLS_CC); if (Z_TYPE_P(sizet) != IS_STRING) { zval_ptr_dtor(&cursor); zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size, value object broken", 0 TSRMLS_CC); return; } len = atoi(Z_STRVAL_P(sizet)); } else { zval_ptr_dtor(&cursor); zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size, property invalid", 0 TSRMLS_CC); return; } str = (char *)ecalloc(len + 1, 1); str_ptr = str; if (apply_to_cursor(cursor, copy_bytes, &str, len + 1 TSRMLS_CC) == FAILURE) { zval_ptr_dtor(&cursor); efree(str_ptr); if (EG(exception)) { return; } zend_throw_exception(mongo_ce_GridFSException, "error reading chunk of file", 17 TSRMLS_CC); return; } zval_ptr_dtor(&cursor); str_ptr[len] = '\0'; RETURN_STRINGL(str_ptr, len, 0); }
int ltd_process_entry( zval *values, char *keyval, int keyval_len, char *filename, int line_number ) { char *trim_keyval, *key, *trim_key, *val, *trim_val, *col = NULL, *tmp_val; int trim_keyval_len, key_len, trim_key_len, val_len, trim_val_len, col_pos; char *brace_open, *brace_close, *tmp_brace, *subarray; int brace_len, tmp_brace_len, subarray_len; int ret_val = SUCCESS; zval *subvalues; ltd_trim( keyval, keyval_len, &trim_keyval, &trim_keyval_len ); if ( trim_keyval[0] == '{' ) { trim_val = trim_keyval; trim_val_len = trim_keyval_len; } else { col = memchr( trim_keyval, ':', trim_keyval_len ); if ( col == NULL ) { trim_val = trim_keyval; trim_val_len = trim_keyval_len; } else { col_pos = (int)( col - trim_keyval ); key_len = col_pos; key = estrndup( trim_keyval, col_pos ); ltd_trim( key, key_len, &trim_key, &trim_key_len ); tmp_val = trim_keyval + col_pos + 1; val_len = trim_keyval_len - col_pos - 1; val = estrndup( tmp_val, val_len ); ltd_trim( val, val_len, &trim_val, &trim_val_len ); } } brace_open = memchr( trim_val, '{', trim_val_len ); if ( brace_open != NULL ) { brace_open++; brace_len = (int)( brace_open - trim_val ); brace_close = memchr( brace_open, '}', trim_val_len - brace_len ); if ( brace_close == NULL ) { php_error( E_WARNING, "Unbalanced brace count in '%s' on line %i", filename, line_number ); ret_val = FAILURE; goto out; } tmp_brace_len = (int)( brace_close - brace_open ); if ( memchr( brace_open, '{', tmp_brace_len ) != NULL ) { if ( ltd_skip_subarrays( brace_open, trim_val_len - brace_len, &tmp_brace, filename, line_number ) == FAILURE ) { ret_val = FAILURE; goto out; } tmp_brace_len = (int)( tmp_brace - trim_val ); brace_close = memchr( tmp_brace, '}', trim_val_len - tmp_brace_len ); } subarray_len = (int)( brace_close - brace_open ) - 1; subarray = estrndup( brace_open, subarray_len ); MAKE_STD_ZVAL( subvalues ); array_init( subvalues ); if( ltd_process_array( subvalues, subarray, subarray_len, filename, line_number ) == FAILURE ) { efree( subarray ); zval_dtor( subvalues ); ret_val = FAILURE; goto out; } if ( col == NULL ) { add_next_index_zval( values, subvalues ); } else { add_assoc_zval_ex( values, trim_key, trim_key_len + 1, subvalues ); } efree( subarray ); } else { if ( col == NULL ) { add_next_index_zval( values, ltd_transform_to_zval( trim_val, trim_val_len ) ); } else { add_assoc_zval_ex( values, trim_key, trim_key_len + 1, ltd_transform_to_zval( trim_val, trim_val_len ) ); } } out: if ( col != NULL ) { efree( key ); efree( val ); } return ret_val; }
/* {{{ proto int MongoGridFSFile::write([string filename = null]) Writes this file to the filesystem */ PHP_METHOD(MongoGridFSFile, write) { char *filename = 0; int filename_len, total = 0; zval *gridfs, *file, *chunks, *query, *cursor, *sort, tmp; zval **id, **size; int len; FILE *fp; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &filename, &filename_len) == FAILURE) { return; } gridfs = zend_read_property(mongo_ce_GridFSFile, getThis(), "gridfs", strlen("gridfs"), NOISY TSRMLS_CC); file = zend_read_property(mongo_ce_GridFSFile, getThis(), "file", strlen("file"), NOISY TSRMLS_CC); if (zend_hash_find(HASH_P(file), "length", strlen("length") + 1, (void**)&size) == FAILURE) { zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size", 14 TSRMLS_CC); return; } if (Z_TYPE_PP(size) == IS_DOUBLE) { len = (int)Z_DVAL_PP(size); } else if (Z_TYPE_PP(size) == IS_LONG) { len = Z_LVAL_PP(size); } else if (Z_TYPE_PP(size) == IS_OBJECT && (Z_OBJCE_PP(size) == mongo_ce_Int32 || Z_OBJCE_PP(size) == mongo_ce_Int64)) { zval *sizet = zend_read_property(mongo_ce_Int64, *size, "value", strlen("value"), NOISY TSRMLS_CC); if (Z_TYPE_P(sizet) != IS_STRING) { zval_ptr_dtor(&cursor); zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size, value object broken", 0 TSRMLS_CC); return; } len = atoi(Z_STRVAL_P(sizet)); } else { zval_ptr_dtor(&cursor); zend_throw_exception(mongo_ce_GridFSException, "couldn't find file size, property invalid", 0 TSRMLS_CC); return; } /* Make sure that there's an index on chunks so we can sort by chunk num */ chunks = zend_read_property(mongo_ce_GridFS, gridfs, "chunks", strlen("chunks"), NOISY TSRMLS_CC); php_mongo_ensure_gridfs_index(&tmp, chunks TSRMLS_CC); zval_dtor(&tmp); if (!filename) { zval **temp; if (zend_hash_find(HASH_P(file), "filename", strlen("filename") + 1, (void**) &temp) == SUCCESS) { convert_to_string_ex(temp); filename = Z_STRVAL_PP(temp); } else { zend_throw_exception(mongo_ce_GridFSException, "Cannot find filename", 15 TSRMLS_CC); return; } } fp = fopen(filename, "wb"); if (!fp) { zend_throw_exception_ex(mongo_ce_GridFSException, 16 TSRMLS_CC, "could not open destination file %s", filename); return; } zend_hash_find(HASH_P(file), "_id", strlen("_id") + 1, (void**)&id); MAKE_STD_ZVAL(query); array_init(query); zval_add_ref(id); add_assoc_zval(query, "files_id", *id); MAKE_STD_ZVAL(cursor); MONGO_METHOD1(MongoCollection, find, cursor, chunks, query); MAKE_STD_ZVAL(sort); array_init(sort); add_assoc_long(sort, "n", 1); MONGO_METHOD1(MongoCursor, sort, cursor, cursor, sort); if ((total = apply_to_cursor(cursor, copy_file, fp, len TSRMLS_CC)) == FAILURE) { zend_throw_exception(mongo_ce_GridFSException, "error reading chunk of file", 17 TSRMLS_CC); } fclose(fp); zval_ptr_dtor(&cursor); zval_ptr_dtor(&sort); zval_ptr_dtor(&query); RETURN_LONG(total); }
zval *value_to_zval(VALUE v) { zval *zv; MAKE_STD_ZVAL(zv); switch (TYPE(v)) { case T_FALSE: ZVAL_FALSE(zv); return zv; case T_TRUE: ZVAL_TRUE(zv); return zv; case T_UNDEF: case T_NIL: ZVAL_NULL(zv); return zv; case T_FIXNUM: ZVAL_LONG(zv, rb_fix2int(v)); return zv; case T_BIGNUM: ZVAL_LONG(zv, rb_big2long(v)); // FIXME: bignum over long return zv; case T_FLOAT: ZVAL_DOUBLE(zv, RFLOAT_VALUE(v)); return zv; case T_ARRAY: { int i; array_init(zv); for(i=0;i<RARRAY_LEN(v);++i) { zval *add = value_to_zval(RARRAY_PTR(v)[i]); zend_hash_next_index_insert(Z_ARRVAL_P(zv), &add, sizeof(zval *), NULL); } return zv; } case T_HASH: { array_init(zv); rb_hash_foreach(v, hash_to_zval, (VALUE)zv); return zv; } case T_SYMBOL: { VALUE symbol_str = rb_sym_to_s(v); ZVAL_STRINGL(zv, StringValuePtr(symbol_str), RSTRING_LEN(symbol_str), 1); return zv; } case T_STRING: { ZVAL_STRINGL(zv, StringValuePtr(v), RSTRING_LEN(v), 1); return zv; } default: { if (CLASS_OF(v) == cPhpEmbedValue) { php_value* pv; Data_Get_Struct(v, php_value, pv); MAKE_COPY_ZVAL(&pv->value, zv); return zv; } } FREE_ZVAL(zv); rb_raise(rb_eRuntimeError, "no implemented"); } }
PHP_METHOD(Edge_Controller, check_login) { zval *chktype, *uin, *key; int had_params = 1; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &chktype, &uin, &key) == FAILURE) { MAKE_STD_ZVAL(chktype); MAKE_STD_ZVAL(uin); MAKE_STD_ZVAL(key); ZVAL_NULL(chktype); ZVAL_NULL(uin); ZVAL_NULL(key); had_params = 0; //RETURN_FALSE; } zend_class_entry **login_ce; if(zend_lookup_class("If_Login", strlen("If_Login"), &login_ce TSRMLS_CC) == FAILURE) { RETURN_FALSE; } zval *login_obj; MAKE_STD_ZVAL(login_obj); object_init_ex(login_obj, *login_ce); zval **args[3]; zval *function_name; zval *ret = NULL; MAKE_STD_ZVAL(function_name); ZVAL_STRING(function_name, "check_login", 1); args[0] = &chktype; args[1] = &uin; args[2] = &key; if(call_user_function_ex(&((*login_ce)->function_table), &login_obj, function_name, &ret, 3, args, 0, NULL TSRMLS_CC )== FAILURE) { zval_ptr_dtor(&function_name); zval_ptr_dtor(&login_obj); RETURN_FALSE; } zval_ptr_dtor(&function_name); zval_ptr_dtor(&login_obj); if(had_params == 0) { zval_ptr_dtor(&chktype); zval_ptr_dtor(&uin); zval_ptr_dtor(&key); } RETURN_ZVAL(ret, 1, 1); /* if(Z_TYPE_P(ret) == IS_BOOL) { RETURN_FALSE; } zval *fret; MAKE_STD_ZVAL(fret); ZVAL_STRING(fret, Z_STRVAL_P(uin), 1); array_init(return_value); add_assoc_string(return_value, "nickname", Z_STRVAL_P(fret), 1); zval_ptr_dtor(&fret); */ }
static int http_request_on_header_value(php_http_parser *parser, const char *at, size_t length) { TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); http_client *client = parser->data; char *header_name = zend_str_tolower_dup(client->current_header_name, client->current_header_name_len); if (strncmp(header_name, "cookie", 6) == 0) { zval *cookie; MAKE_STD_ZVAL(cookie); array_init(cookie); zend_update_property(swoole_http_request_class_entry_ptr, client->zrequest, ZEND_STRL("cookie"), cookie TSRMLS_CC); struct { char *k; int klen; char *v; int vlen; } kv = { 0 }; char *_c = (char *) at; int n = 1; kv.k = _c; while (_c < at + length) { if (*_c == '=') { kv.v = _c + 1; kv.klen = n; n = 0; } else if (*_c == ';') { kv.vlen = n; add_assoc_stringl_ex(cookie, kv.k, kv.klen, kv.v, kv.vlen, 1); kv.k = _c + 2; n = 0; } else { n++; } _c++; } kv.vlen = n; add_assoc_stringl_ex(cookie, kv.k, kv.klen, kv.v, kv.vlen, 1); } else { zval *header = zend_read_property(swoole_http_request_class_entry_ptr, client->zrequest, ZEND_STRL("header"), 1 TSRMLS_CC); add_assoc_stringl_ex(header, header_name, client->current_header_name_len + 1, (char *) at, length, 1); } if (client->current_header_name_allocated) { efree(client->current_header_name); client->current_header_name_allocated = 0; } efree(header_name); return 0; }
PHP_METHOD(Edge_Controller, get) { char *name; int nlen = 0; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &nlen) == FAILURE) { return; } zval * data; data = edge_request_query(EDGE_REQUEST_VARS_GET, name); if(Z_TYPE_P(data) == IS_NULL && nlen != 0) { zval_ptr_dtor(&data); if(strncmp("model", name, nlen) == 0) { zval *arg; zval *ret; zend_object *zobj; zend_class_entry *ce; zobj = Z_OBJ_P(getThis()); ce = zobj->ce; char *controller_prefix; controller_prefix = estrndup(ce->name, ce->name_length - strlen("Controller")); char *model_class_name; spprintf(&model_class_name, 0, "%s", controller_prefix); MAKE_STD_ZVAL(arg); ZVAL_STRING(arg, model_class_name, 1); zend_call_method_with_1_params(&getThis(), edge_controller_ce, NULL, "model", &ret, arg); efree(model_class_name); zval_ptr_dtor(&arg); if(!Z_BVAL_P(ret)) { RETURN_ZVAL(ret, 1, 1); } efree(controller_prefix); RETURN_ZVAL(ret, 1, 1); } else { char *mg_class_name = NULL; name[0] = toupper(name[0]); int mg_class_len = spprintf(&mg_class_name, 0, "If_%s", name); zend_class_entry **mg_ce; if(zend_lookup_class(mg_class_name, mg_class_len, &mg_ce TSRMLS_CC) == FAILURE) { RETURN_FALSE; } zval *mg_obj; MAKE_STD_ZVAL(mg_obj); object_init_ex(mg_obj, *mg_ce); RETURN_ZVAL(mg_obj, 1, 1); } } RETURN_ZVAL(data, 1, 1); }
static int http_onReceive(swFactory *factory, swEventData *req) { TSRMLS_FETCH_FROM_CTX(sw_thread_ctx ? sw_thread_ctx : NULL); int fd = req->info.fd; http_client *client = swHashMap_find_int(php_sw_http_clients, fd); if (!client) { client = http_client_new(fd TSRMLS_CC); } php_http_parser *parser = &client->parser; zval *zrequest; MAKE_STD_ZVAL(zrequest); object_init_ex(zrequest, swoole_http_request_class_entry_ptr); zval *header; MAKE_STD_ZVAL(header); //request header array_init(header); zend_update_property(swoole_http_request_class_entry_ptr, zrequest, ZEND_STRL("header"), header TSRMLS_CC); zval *zresponse; MAKE_STD_ZVAL(zresponse); object_init_ex(zresponse, swoole_http_response_class_entry_ptr); //socket fd zend_update_property_long(swoole_http_response_class_entry_ptr, zresponse, ZEND_STRL("fd"), fd TSRMLS_CC); client->zresponse = zresponse; client->zrequest = zrequest; parser->data = client; php_http_parser_init(parser, PHP_HTTP_REQUEST); zval *zdata = php_swoole_get_data(req TSRMLS_CC); size_t n = php_http_parser_execute(parser, &http_parser_settings, Z_STRVAL_P(zdata), Z_STRLEN_P(zdata)); zval_ptr_dtor(&zdata); if (n < 0) { swWarn("php_http_parser_execute failed."); } else { zval *retval; zval **args[2]; args[0] = &zrequest; args[1] = &zresponse; if (call_user_function_ex(EG(function_table), NULL, php_sw_http_server_callbacks[0], &retval, 2, args, 0, NULL TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "onRequest handler error"); } if (EG(exception)) { zend_exception_error(EG(exception), E_WARNING TSRMLS_CC); } if (retval) { zval_ptr_dtor(&retval); } } return SW_OK; }
PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) { const unsigned char *cursor, *limit, *marker, *start; zval **rval_ref; limit = cursor = *p; if (var_hash && cursor[0] != 'R') { var_push(var_hash, rval); } start = cursor; #line 400 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; switch (yych) { case 'C': case 'O': goto yy13; case 'N': goto yy5; case 'R': goto yy2; case 'S': goto yy10; case 'a': goto yy11; case 'b': goto yy6; case 'd': goto yy8; case 'i': goto yy7; case 'o': goto yy12; case 'r': goto yy4; case 's': goto yy9; case '}': goto yy14; default: goto yy16; } yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: #line 722 "ext/standard/var_unserializer.re" { return 0; } #line 462 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; goto yy3; yy5: yych = *++YYCURSOR; if (yych == ';') goto yy87; goto yy3; yy6: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy83; goto yy3; yy7: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy77; goto yy3; yy8: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy53; goto yy3; yy9: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy46; goto yy3; yy10: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy39; goto yy3; yy11: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy32; goto yy3; yy12: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy25; goto yy3; yy13: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy17; goto yy3; yy14: ++YYCURSOR; #line 716 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } #line 511 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; yy17: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } if (yych == '+') goto yy19; yy18: YYCURSOR = YYMARKER; goto yy3; yy19: yych = *++YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } goto yy18; yy20: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yybm[0+yych] & 128) { goto yy20; } if (yych != ':') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 599 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; char *class_name; zend_class_entry *ce; zend_class_entry **pce; int incomplete_class = 0; int custom_object = 0; zval *user_func; zval *retval_ptr; zval **args[1]; zval *arg_func_name; if (*start == 'C') { custom_object = 1; } INIT_PZVAL(*rval); len2 = len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len || len == 0) { *p = start + 2; return 0; } class_name = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } if (*(YYCURSOR+1) != ':') { *p = YYCURSOR+1; return 0; } len3 = strspn(class_name, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\"); if (len3 != len) { *p = YYCURSOR + len3 - len; return 0; } class_name = estrndup(class_name, len); do { /* Try to find class directly */ if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { ce = *pce; break; } /* Check for unserialize callback */ if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) { incomplete_class = 1; ce = PHP_IC_ENTRY; break; } /* Call unserialize callback */ MAKE_STD_ZVAL(user_func); ZVAL_STRING(user_func, PG(unserialize_callback_func), 1); args[0] = &arg_func_name; MAKE_STD_ZVAL(arg_func_name); ZVAL_STRING(arg_func_name, class_name, 1); if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val); incomplete_class = 1; ce = PHP_IC_ENTRY; zval_ptr_dtor(&user_func); zval_ptr_dtor(&arg_func_name); break; } if (retval_ptr) { zval_ptr_dtor(&retval_ptr); } /* The callback function may have defined the class */ if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { ce = *pce; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val); incomplete_class = 1; ce = PHP_IC_ENTRY; } zval_ptr_dtor(&user_func); zval_ptr_dtor(&arg_func_name); break; } while (1); *p = YYCURSOR; if (custom_object) { int ret = object_custom(UNSERIALIZE_PASSTHRU, ce); if (ret && incomplete_class) { php_store_class_name(*rval, class_name, len2); } efree(class_name); return ret; } elements = object_common1(UNSERIALIZE_PASSTHRU, ce); if (incomplete_class) { php_store_class_name(*rval, class_name, len2); } efree(class_name); return object_common2(UNSERIALIZE_PASSTHRU, elements); } #line 658 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy26; if (yych <= '/') goto yy18; if (yych <= '9') goto yy27; goto yy18; } yy26: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy27: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy27; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 591 "ext/standard/var_unserializer.re" { INIT_PZVAL(*rval); return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } #line 691 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; goto yy18; yy33: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy34: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy34; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; #line 571 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ *p = YYCURSOR; if (elements < 0) { return 0; } INIT_PZVAL(*rval); array_init_size(*rval, elements); if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements)) { return 0; } return finish_nested_data(UNSERIALIZE_PASSTHRU); } #line 732 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; if (yych <= '/') goto yy18; if (yych <= '9') goto yy41; goto yy18; yy40: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy41: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy41; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 542 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) { return 0; } if (*(YYCURSOR) != '"') { efree(str); *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_STRINGL(*rval, str, len, 0); return 1; } #line 782 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; if (yych <= '/') goto yy18; if (yych <= '9') goto yy48; goto yy18; yy47: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy48: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy48; if (yych >= ';') goto yy18; yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; #line 514 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; len = parse_uiv(start + 2); maxlen = max - YYCURSOR; if (maxlen < len) { *p = start + 2; return 0; } str = (char*)YYCURSOR; YYCURSOR += len; if (*(YYCURSOR) != '"') { *p = YYCURSOR; return 0; } YYCURSOR += 2; *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_STRINGL(*rval, str, len, 1); return 1; } #line 831 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { if (yych <= ',') { if (yych == '+') goto yy57; goto yy18; } else { if (yych <= '-') goto yy55; if (yych <= '.') goto yy60; goto yy18; } } else { if (yych <= 'I') { if (yych <= '9') goto yy58; if (yych <= 'H') goto yy18; goto yy56; } else { if (yych != 'N') goto yy18; } } yych = *++YYCURSOR; if (yych == 'A') goto yy76; goto yy18; yy55: yych = *++YYCURSOR; if (yych <= '/') { if (yych == '.') goto yy60; goto yy18; } else { if (yych <= '9') goto yy58; if (yych != 'I') goto yy18; } yy56: yych = *++YYCURSOR; if (yych == 'N') goto yy72; goto yy18; yy57: yych = *++YYCURSOR; if (yych == '.') goto yy60; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy58: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ':') { if (yych <= '.') { if (yych <= '-') goto yy18; goto yy70; } else { if (yych <= '/') goto yy18; if (yych <= '9') goto yy58; goto yy18; } } else { if (yych <= 'E') { if (yych <= ';') goto yy63; if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy60: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy61: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ';') { if (yych <= '/') goto yy18; if (yych <= '9') goto yy61; if (yych <= ':') goto yy18; } else { if (yych <= 'E') { if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy63: ++YYCURSOR; #line 504 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 use_double: #endif *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); return 1; } #line 929 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy66; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; goto yy18; } yy66: yych = *++YYCURSOR; if (yych <= ',') { if (yych == '+') goto yy69; goto yy18; } else { if (yych <= '-') goto yy69; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; } yy67: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; if (yych == ';') goto yy63; goto yy18; yy69: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy67; goto yy18; yy70: ++YYCURSOR; if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; if (yych <= ';') { if (yych <= '/') goto yy18; if (yych <= '9') goto yy70; if (yych <= ':') goto yy18; goto yy63; } else { if (yych <= 'E') { if (yych <= 'D') goto yy18; goto yy65; } else { if (yych == 'e') goto yy65; goto yy18; } } yy72: yych = *++YYCURSOR; if (yych != 'F') goto yy18; yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; #line 489 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); if (!strncmp(start + 2, "NAN", 3)) { ZVAL_DOUBLE(*rval, php_get_nan()); } else if (!strncmp(start + 2, "INF", 3)) { ZVAL_DOUBLE(*rval, php_get_inf()); } else if (!strncmp(start + 2, "-INF", 4)) { ZVAL_DOUBLE(*rval, -php_get_inf()); } return 1; } #line 1003 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; goto yy18; yy77: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy78; if (yych <= '/') goto yy18; if (yych <= '9') goto yy79; goto yy18; } yy78: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy79: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; #line 462 "ext/standard/var_unserializer.re" { #if SIZEOF_LONG == 4 int digits = YYCURSOR - start - 3; if (start[2] == '-' || start[2] == '+') { digits--; } /* Use double for large long values that were serialized on a 64-bit system */ if (digits >= MAX_LENGTH_OF_LONG - 1) { if (digits == MAX_LENGTH_OF_LONG - 1) { int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1); if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) { goto use_double; } } else { goto use_double; } } #endif *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } #line 1057 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= '2') goto yy18; yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; #line 455 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } #line 1072 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; #line 448 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } #line 1082 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy90; if (yych <= '/') goto yy18; if (yych <= '9') goto yy91; goto yy18; } yy90: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy91: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; #line 425 "ext/standard/var_unserializer.re" { long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_iv(start + 2) - 1; if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) { return 0; } if (*rval == *rval_ref) return 0; if (*rval != NULL) { zval_ptr_dtor(rval); } *rval = *rval_ref; Z_ADDREF_PP(rval); Z_UNSET_ISREF_PP(rval); return 1; } #line 1128 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { if (yych != '+') goto yy18; } else { if (yych <= '-') goto yy96; if (yych <= '/') goto yy18; if (yych <= '9') goto yy97; goto yy18; } yy96: yych = *++YYCURSOR; if (yych <= '/') goto yy18; if (yych >= ':') goto yy18; yy97: ++YYCURSOR; if (YYLIMIT <= YYCURSOR) YYFILL(1); yych = *YYCURSOR; if (yych <= '/') goto yy18; if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; #line 404 "ext/standard/var_unserializer.re" { long id; *p = YYCURSOR; if (!var_hash) return 0; id = parse_iv(start + 2) - 1; if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) { return 0; } if (*rval != NULL) { zval_ptr_dtor(rval); } *rval = *rval_ref; Z_ADDREF_PP(rval); Z_SET_ISREF_PP(rval); return 1; } #line 1172 "ext/standard/var_unserializer.c" } #line 724 "ext/standard/var_unserializer.re" return 0; }
static char *proxy_callback( const char *url, const int url_len, zend_fcall_info *fci, zend_fcall_info_cache *fcc, char *callback_name ) { zval *zurl, *retval_ptr = NULL, **params; int retval; char *result = NULL; TSRMLS_FETCH(); if (fci == NULL || fci->size == 0) return NULL; /* should not happen */ MAKE_STD_ZVAL(zurl); ZVAL_STRINGL(zurl, url, url_len, 1); params = &zurl; fci->retval_ptr_ptr = &retval_ptr; fci->params = ¶ms; fci->param_count = 1; fci->no_separation = 1; retval = zend_call_function(fci, fcc TSRMLS_CC); if (retval != SUCCESS || fci->retval_ptr_ptr == NULL) { /* failure was most likely due to a previous exception (probably * in a previous URL), so don't throw yet another exception on * top of it */ if (!EG(exception)) { zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Call to PHP %s callback has failed", callback_name); } } else { /* success in zend_call_function, but there may've been an exception */ /* may have been changed by return by reference */ retval_ptr = *fci->retval_ptr_ptr; if (retval_ptr == NULL) { /* no retval - most likely an exception, but we feel confortable * stacking an exception here */ zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Call to PHP %s callback has failed (%s)", callback_name, EG(exception)?"exception":"no return value"); } else if (Z_TYPE_P(retval_ptr) == IS_NULL) { /* use the default string for the url */ } else { if (Z_TYPE_P(retval_ptr) != IS_STRING) { SEPARATE_ZVAL(&retval_ptr); convert_to_string(retval_ptr); } result = estrndup(Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr)); } } zval_ptr_dtor(&zurl); if (retval_ptr != NULL) { zval_ptr_dtor(&retval_ptr); } return result; }
php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, const char *path, const char *mode, int options, char **opened_path, php_stream_context *context, int redirect_max, int flags STREAMS_DC TSRMLS_DC) /* {{{ */ { php_stream *stream = NULL; php_url *resource = NULL; int use_ssl; int use_proxy = 0; char *scratch = NULL; char *tmp = NULL; char *ua_str = NULL; zval **ua_zval = NULL, **tmpzval = NULL, *ssl_proxy_peer_name = 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 = 0; char *transport_string, *errstr = NULL; int transport_len, have_header = 0, request_fulluri = 0, ignore_errors = 0; char *protocol_version = NULL; int protocol_version_len = 3; /* Default: "1.0" */ struct timeval timeout; char *user_headers = NULL; int header_init = ((flags & HTTP_WRAPPER_HEADER_INIT) != 0); int redirected = ((flags & HTTP_WRAPPER_REDIRECTED) != 0); int follow_location = 1; php_stream_filter *transfer_encoding = NULL; int response_code; tmp_line[0] = '\0'; if (redirect_max < 1) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Redirection limit reached, aborting"); 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"))) { if (!context || php_stream_context_get_option(context, wrapper->wops->label, "proxy", &tmpzval) == FAILURE || Z_TYPE_PP(tmpzval) != IS_STRING || Z_STRLEN_PP(tmpzval) <= 0) { php_url_free(resource); return php_stream_open_wrapper_ex(path, mode, REPORT_ERRORS, NULL, context); } /* Called from a non-http wrapper with http proxying requested (i.e. ftp) */ request_fulluri = 1; use_ssl = 0; use_proxy = 1; transport_len = Z_STRLEN_PP(tmpzval); transport_string = estrndup(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval)); } else { /* Normal http request (possibly with proxy) */ if (strpbrk(mode, "awx+")) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "HTTP wrapper does not support writeable connections"); php_url_free(resource); return NULL; } 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; if (context && php_stream_context_get_option(context, wrapper->wops->label, "proxy", &tmpzval) == SUCCESS && Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) { use_proxy = 1; transport_len = Z_STRLEN_PP(tmpzval); transport_string = estrndup(Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval)); } else { transport_len = spprintf(&transport_string, 0, "%s://%s:%d", use_ssl ? "ssl" : "tcp", resource->host, resource->port); } } if (context && php_stream_context_get_option(context, wrapper->wops->label, "timeout", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_double_ex(tmpzval); timeout.tv_sec = (time_t) Z_DVAL_PP(tmpzval); timeout.tv_usec = (size_t) ((Z_DVAL_PP(tmpzval) - timeout.tv_sec) * 1000000); } else { timeout.tv_sec = FG(default_socket_timeout); timeout.tv_usec = 0; } stream = php_stream_xport_create(transport_string, transport_len, options, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, NULL, &timeout, context, &errstr, NULL); if (stream) { php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &timeout); } if (errstr) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "%s", errstr); efree(errstr); errstr = NULL; } efree(transport_string); if (stream && use_proxy && use_ssl) { smart_str header = {0}; /* Set peer_name or name verification will try to use the proxy server name */ if (!context || php_stream_context_get_option(context, "ssl", "peer_name", &tmpzval) == FAILURE) { MAKE_STD_ZVAL(ssl_proxy_peer_name); ZVAL_STRING(ssl_proxy_peer_name, resource->host, 1); php_stream_context_set_option(stream->context, "ssl", "peer_name", ssl_proxy_peer_name); } smart_str_appendl(&header, "CONNECT ", sizeof("CONNECT ")-1); smart_str_appends(&header, resource->host); smart_str_appendc(&header, ':'); smart_str_append_unsigned(&header, resource->port); smart_str_appendl(&header, " HTTP/1.0\r\n", sizeof(" HTTP/1.0\r\n")-1); /* check if we have Proxy-Authorization header */ if (context && php_stream_context_get_option(context, "http", "header", &tmpzval) == SUCCESS) { char *s, *p; if (Z_TYPE_PP(tmpzval) == IS_ARRAY) { HashPosition pos; zval **tmpheader = NULL; for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(tmpzval), &pos); SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(tmpzval), (void *)&tmpheader, &pos); zend_hash_move_forward_ex(Z_ARRVAL_PP(tmpzval), &pos)) { if (Z_TYPE_PP(tmpheader) == IS_STRING) { s = Z_STRVAL_PP(tmpheader); do { while (*s == ' ' || *s == '\t') s++; p = s; while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++; if (*p == ':') { p++; if (p - s == sizeof("Proxy-Authorization:") - 1 && zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1, "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) { while (*p != 0 && *p != '\r' && *p !='\n') p++; smart_str_appendl(&header, s, p - s); smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1); goto finish; } else { while (*p != 0 && *p != '\r' && *p !='\n') p++; } } s = p; while (*s == '\r' || *s == '\n') s++; } while (*s != 0); } } } else if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) { s = Z_STRVAL_PP(tmpzval); do { while (*s == ' ' || *s == '\t') s++; p = s; while (*p != 0 && *p != ':' && *p != '\r' && *p !='\n') p++; if (*p == ':') { p++; if (p - s == sizeof("Proxy-Authorization:") - 1 && zend_binary_strcasecmp(s, sizeof("Proxy-Authorization:") - 1, "Proxy-Authorization:", sizeof("Proxy-Authorization:") - 1) == 0) { while (*p != 0 && *p != '\r' && *p !='\n') p++; smart_str_appendl(&header, s, p - s); smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1); goto finish; } else { while (*p != 0 && *p != '\r' && *p !='\n') p++; } } s = p; while (*s == '\r' || *s == '\n') s++; } while (*s != 0); } } finish: smart_str_appendl(&header, "\r\n", sizeof("\r\n")-1); if (php_stream_write(stream, header.c, header.len) != header.len) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Cannot connect to HTTPS server through proxy"); php_stream_close(stream); stream = NULL; } smart_str_free(&header); if (stream) { char header_line[HTTP_HEADER_BLOCK_SIZE]; /* get response header */ while (php_stream_gets(stream, header_line, HTTP_HEADER_BLOCK_SIZE-1) != NULL) { if (header_line[0] == '\n' || header_line[0] == '\r' || header_line[0] == '\0') { break; } } } /* enable SSL transport layer */ if (stream) { if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_ANY_CLIENT, NULL TSRMLS_CC) < 0 || php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Cannot connect to HTTPS server through proxy"); php_stream_close(stream); stream = NULL; } } } if (stream == NULL) goto out; /* avoid buffering issues while reading header */ if (options & STREAM_WILL_CAST) chunk_size = php_stream_set_chunk_size(stream, 1); /* 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 TSRMLS_CC); php_stream_notify_info(context, PHP_STREAM_NOTIFY_CONNECT, NULL, 0); if (header_init && context && php_stream_context_get_option(context, "http", "max_redirects", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_long_ex(tmpzval); redirect_max = Z_LVAL_PP(tmpzval); } if (context && php_stream_context_get_option(context, "http", "method", &tmpzval) == SUCCESS) { if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) { /* As per the RFC, automatically redirected requests MUST NOT use other methods than * GET and HEAD unless it can be confirmed by the user */ if (!redirected || (Z_STRLEN_PP(tmpzval) == 3 && memcmp("GET", Z_STRVAL_PP(tmpzval), 3) == 0) || (Z_STRLEN_PP(tmpzval) == 4 && memcmp("HEAD",Z_STRVAL_PP(tmpzval), 4) == 0) ) { scratch_len = strlen(path) + 29 + Z_STRLEN_PP(tmpzval); scratch = emalloc(scratch_len); strlcpy(scratch, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) + 1); strncat(scratch, " ", 1); } } } if (context && php_stream_context_get_option(context, "http", "protocol_version", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_double_ex(tmpzval); protocol_version_len = spprintf(&protocol_version, 0, "%.1F", Z_DVAL_PP(tmpzval)); } if (!scratch) { scratch_len = strlen(path) + 29 + protocol_version_len; scratch = emalloc(scratch_len); strncpy(scratch, "GET ", scratch_len); } /* Should we send the entire path in the request line, default to no. */ if (!request_fulluri && context && php_stream_context_get_option(context, "http", "request_fulluri", &tmpzval) == SUCCESS) { zval ztmp = **tmpzval; zval_copy_ctor(&ztmp); convert_to_boolean(&ztmp); request_fulluri = Z_BVAL(ztmp) ? 1 : 0; zval_dtor(&ztmp); } if (request_fulluri) { /* Ask for everything */ strcat(scratch, path); } else { /* Send the traditional /path/to/file?query_string */ /* 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 */ if (protocol_version) { strlcat(scratch, " HTTP/", scratch_len); strlcat(scratch, protocol_version, scratch_len); strlcat(scratch, "\r\n", scratch_len); } else { 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) { tmp = NULL; if (Z_TYPE_PP(tmpzval) == IS_ARRAY) { HashPosition pos; zval **tmpheader = NULL; smart_str tmpstr = {0}; for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(tmpzval), &pos); SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(tmpzval), (void *)&tmpheader, &pos); zend_hash_move_forward_ex(Z_ARRVAL_PP(tmpzval), &pos) ) { if (Z_TYPE_PP(tmpheader) == IS_STRING) { smart_str_appendl(&tmpstr, Z_STRVAL_PP(tmpheader), Z_STRLEN_PP(tmpheader)); smart_str_appendl(&tmpstr, "\r\n", sizeof("\r\n") - 1); } } smart_str_0(&tmpstr); /* Remove newlines and spaces from start and end. there's at least one extra \r\n at the end that needs to go. */ if (tmpstr.c) { tmp = php_trim(tmpstr.c, strlen(tmpstr.c), NULL, 0, NULL, 3 TSRMLS_CC); smart_str_free(&tmpstr); } } if (Z_TYPE_PP(tmpzval) == IS_STRING && 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 (tmp && strlen(tmp) > 0) { char *s; user_headers = estrdup(tmp); /* Make lowercase for easy comparison against 'standard' headers */ php_strtolower(tmp, strlen(tmp)); if (!header_init) { /* strip POST headers on redirect */ strip_header(user_headers, tmp, "content-length:"); strip_header(user_headers, tmp, "content-type:"); } if ((s = strstr(tmp, "user-agent:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_USER_AGENT; } if ((s = strstr(tmp, "host:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_HOST; } if ((s = strstr(tmp, "from:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_FROM; } if ((s = strstr(tmp, "authorization:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_AUTH; } if ((s = strstr(tmp, "content-length:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_CONTENT_LENGTH; } if ((s = strstr(tmp, "content-type:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_TYPE; } if ((s = strstr(tmp, "connection:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { have_header |= HTTP_HEADER_CONNECTION; } /* remove Proxy-Authorization header */ if (use_proxy && use_ssl && (s = strstr(tmp, "proxy-authorization:")) && (s == tmp || *(s-1) == '\r' || *(s-1) == '\n' || *(s-1) == '\t' || *(s-1) == ' ')) { char *p = s + sizeof("proxy-authorization:") - 1; while (s > tmp && (*(s-1) == ' ' || *(s-1) == '\t')) s--; while (*p != 0 && *p != '\r' && *p != '\n') p++; while (*p == '\r' || *p == '\n') p++; if (*p == 0) { if (s == tmp) { efree(user_headers); user_headers = NULL; } else { while (s > tmp && (*(s-1) == '\r' || *(s-1) == '\n')) s--; user_headers[s - tmp] = 0; } } else { memmove(user_headers + (s - tmp), user_headers + (p - tmp), strlen(p) + 1); } } } if (tmp) { efree(tmp); } } /* auth header if it was specified */ if (((have_header & HTTP_HEADER_AUTH) == 0) && resource->user) { /* decode the strings first */ php_url_decode(resource->user, strlen(resource->user)); /* scratch is large enough, since it was made large enough for the whole URL */ strcpy(scratch, resource->user); strcat(scratch, ":"); /* Note: password is optional! */ if (resource->pass) { php_url_decode(resource->pass, strlen(resource->pass)); 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) && FG(from_address)) { if (snprintf(scratch, scratch_len, "From: %s\r\n", FG(from_address)) > 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 && resource->port != 0) || (!use_ssl && resource->port != 80 && resource->port != 0)) { 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)); } } } /* Send a Connection: close header when using HTTP 1.1 or later to avoid * hanging when the server interprets the RFC literally and establishes a * keep-alive connection, unless the user specifically requests something * else by specifying a Connection header in the context options. */ if (protocol_version && ((have_header & HTTP_HEADER_CONNECTION) == 0) && (strncmp(protocol_version, "1.0", MIN(protocol_version_len, 3)) > 0)) { php_stream_write_string(stream, "Connection: close\r\n"); } if (context && php_stream_context_get_option(context, "http", "user_agent", &ua_zval) == SUCCESS && Z_TYPE_PP(ua_zval) == IS_STRING) { ua_str = Z_STRVAL_PP(ua_zval); } else if (FG(user_agent)) { ua_str = FG(user_agent); } if (((have_header & HTTP_HEADER_USER_AGENT) == 0) && 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 = emalloc(ua_len + 1); if ((ua_len = slprintf(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); } } } if (user_headers) { /* A bit weird, but some servers require that Content-Length be sent prior to Content-Type for POST * see bug #44603 for details. Since Content-Type maybe part of user's headers we need to do this check first. */ if ( header_init && context && !(have_header & HTTP_HEADER_CONTENT_LENGTH) && php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS && Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0 ) { scratch_len = slprintf(scratch, scratch_len, "Content-Length: %d\r\n", Z_STRLEN_PP(tmpzval)); php_stream_write(stream, scratch, scratch_len); have_header |= HTTP_HEADER_CONTENT_LENGTH; } php_stream_write(stream, user_headers, strlen(user_headers)); php_stream_write(stream, "\r\n", sizeof("\r\n")-1); efree(user_headers); } /* Request content, such as for POST requests */ if (header_init && context && php_stream_context_get_option(context, "http", "content", &tmpzval) == SUCCESS && Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval) > 0) { if (!(have_header & HTTP_HEADER_CONTENT_LENGTH)) { scratch_len = slprintf(scratch, scratch_len, "Content-Length: %d\r\n", Z_STRLEN_PP(tmpzval)); php_stream_write(stream, scratch, scratch_len); } if (!(have_header & HTTP_HEADER_TYPE)) { php_stream_write(stream, "Content-Type: application/x-www-form-urlencoded\r\n", sizeof("Content-Type: application/x-www-form-urlencoded\r\n") - 1); php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Content-type not specified assuming application/x-www-form-urlencoded"); } php_stream_write(stream, "\r\n", sizeof("\r\n")-1); php_stream_write(stream, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval)); } else { php_stream_write(stream, "\r\n", sizeof("\r\n")-1); } location[0] = '\0'; if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); } if (header_init) { zval *ztmp; MAKE_STD_ZVAL(ztmp); array_init(ztmp); ZEND_SET_SYMBOL(EG(active_symbol_table), "http_response_header", ztmp); } { zval **rh; zend_hash_find(EG(active_symbol_table), "http_response_header", sizeof("http_response_header"), (void **) &rh); response_header = *rh; } 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) != NULL) { zval *http_response; if (tmp_line_len > 9) { response_code = atoi(tmp_line + 9); } else { response_code = 0; } if (context && SUCCESS==php_stream_context_get_option(context, "http", "ignore_errors", &tmpzval)) { ignore_errors = zend_is_true(*tmpzval TSRMLS_CC); } /* when we request only the header, don't fail even on error codes */ if ((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) { reqok = 1; } /* all status codes in the 2xx range are defined by the specification as successful; * all status codes in the 3xx range are for redirection, and so also should never * fail */ if (response_code >= 200 && response_code < 400) { reqok = 1; } else { switch(response_code) { 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); } } if (tmp_line[tmp_line_len - 1] == '\n') { --tmp_line_len; if (tmp_line[tmp_line_len - 1] == '\r') { --tmp_line_len; } } MAKE_STD_ZVAL(http_response); ZVAL_STRINGL(http_response, tmp_line, tmp_line_len, 1); zend_hash_next_index_insert(Z_ARRVAL_P(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 = emalloc(HTTP_HEADER_BLOCK_SIZE); while (!body && !php_stream_eof(stream)) { size_t http_header_line_length; if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) && *http_header_line != '\n' && *http_header_line != '\r') { char *e = http_header_line + http_header_line_length - 1; if (*e != '\n') { do { /* partial header */ if (php_stream_get_line(stream, http_header_line, HTTP_HEADER_BLOCK_SIZE, &http_header_line_length) == NULL) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Failed to read HTTP headers"); goto out; } e = http_header_line + http_header_line_length - 1; } while (*e != '\n'); continue; } while (*e == '\n' || *e == '\r') { e--; } http_header_line_length = e - http_header_line + 1; http_header_line[http_header_line_length] = '\0'; if (!strncasecmp(http_header_line, "Location: ", 10)) { if (context && php_stream_context_get_option(context, "http", "follow_location", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_long_ex(tmpzval); follow_location = Z_LVAL_PP(tmpzval); } else if (!(response_code >= 300 && response_code < 304 || 307 == response_code || 308 == response_code)) { /* we shouldn't redirect automatically if follow_location isn't set and response_code not in (300, 301, 302, 303 and 307) see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1 RFC 7238 defines 308: http://tools.ietf.org/html/rfc7238 */ follow_location = 0; } 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); } else if (!strncasecmp(http_header_line, "Transfer-Encoding: chunked", sizeof("Transfer-Encoding: chunked"))) { /* create filter to decode response body */ if (!(options & STREAM_ONLY_GET_HEADERS)) { long decode = 1; if (context && php_stream_context_get_option(context, "http", "auto_decode", &tmpzval) == SUCCESS) { SEPARATE_ZVAL(tmpzval); convert_to_boolean(*tmpzval); decode = Z_LVAL_PP(tmpzval); } if (decode) { transfer_encoding = php_stream_filter_create("dechunk", NULL, php_stream_is_persistent(stream) TSRMLS_CC); if (transfer_encoding) { /* don't store transfer-encodeing header */ continue; } } } } 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_P(response_header), &http_header, sizeof(zval *), NULL); } } else { break; } } if (!reqok || (location[0] != '\0' && follow_location)) { if (!follow_location || (((options & STREAM_ONLY_GET_HEADERS) || ignore_errors) && redirect_max <= 1)) { goto out; } 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') { 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)); } php_url_free(resource); /* check for invalid redirection URLs */ if ((resource = php_url_parse(new_path)) == NULL) { php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect URL! %s", new_path); goto out; } #define CHECK_FOR_CNTRL_CHARS(val) { \ if (val) { \ unsigned char *s, *e; \ int l; \ l = php_url_decode(val, strlen(val)); \ s = (unsigned char*)val; e = s + l; \ while (s < e) { \ if (iscntrl(*s)) { \ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "Invalid redirect URL! %s", new_path); \ goto out; \ } \ s++; \ } \ } \ } /* check for control characters in login, password & path */ if (strncasecmp(new_path, "http://", sizeof("http://") - 1) || strncasecmp(new_path, "https://", sizeof("https://") - 1)) { CHECK_FOR_CNTRL_CHARS(resource->user) CHECK_FOR_CNTRL_CHARS(resource->pass) CHECK_FOR_CNTRL_CHARS(resource->path) } stream = php_stream_url_wrap_http_ex(wrapper, new_path, mode, options, opened_path, context, --redirect_max, HTTP_WRAPPER_REDIRECTED STREAMS_CC TSRMLS_CC); } else {
PHP_METHOD(MongoCursor, count) { zval *db_z, *coll, *query; mongo_cursor *cursor; mongo_collection *c; mongo_db *db; zend_bool all = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &all) == FAILURE) { return; } PHP_MONGO_GET_CURSOR(getThis()); // fake a MongoDB object MAKE_STD_ZVAL(db_z); object_init_ex(db_z, mongo_ce_DB); db = (mongo_db*)zend_object_store_get_object(db_z TSRMLS_CC); db->link = cursor->resource; MAKE_STD_ZVAL(db->name); ZVAL_STRING(db->name, estrndup(cursor->ns, strchr(cursor->ns, '.') - cursor->ns), 0); // fake a MongoCollection object MAKE_STD_ZVAL(coll); object_init_ex(coll, mongo_ce_Collection); c = (mongo_collection*)zend_object_store_get_object(coll TSRMLS_CC); MAKE_STD_ZVAL(c->ns); ZVAL_STRING(c->ns, estrdup(cursor->ns), 0); MAKE_STD_ZVAL(c->name); ZVAL_STRING(c->name, estrdup(cursor->ns + (strchr(cursor->ns, '.') - cursor->ns) + 1), 0); c->parent = db_z; if (cursor->query) { zval **inner_query = 0; if (!cursor->special) { query = cursor->query; zval_add_ref(&query); } else if (zend_hash_find(HASH_P(cursor->query), "$query", strlen("$query")+1, (void**)&inner_query) == SUCCESS) { query = *inner_query; zval_add_ref(&query); } } else { MAKE_STD_ZVAL(query); array_init(query); } if (all) { zval *limit_z, *skip_z; MAKE_STD_ZVAL(limit_z); MAKE_STD_ZVAL(skip_z); ZVAL_LONG(limit_z, cursor->limit); ZVAL_LONG(skip_z, cursor->skip); MONGO_METHOD3(MongoCollection, count, return_value, coll, query, limit_z, skip_z); zval_ptr_dtor(&limit_z); zval_ptr_dtor(&skip_z); } else { MONGO_METHOD1(MongoCollection, count, return_value, coll, query); } zval_ptr_dtor(&query); c->parent = 0; zend_objects_store_del_ref(coll TSRMLS_CC); zval_ptr_dtor(&coll); db->link = 0; zend_objects_store_del_ref(db_z TSRMLS_CC); zval_ptr_dtor(&db_z); }