Beispiel #1
0
/**
 * Push one or more elements onto the end of an array
 */
int phalcon_array_append(zval **arr, zval *value, int flags TSRMLS_DC) {

	if (Z_TYPE_PP(arr) != IS_ARRAY) {
		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
		return FAILURE;
	}

	if ((flags & PH_SEPARATE) == PH_SEPARATE) {
		if (Z_REFCOUNT_PP(arr) > 1) {
			zval *new_zv;
			Z_DELREF_PP(arr);
			ALLOC_ZVAL(new_zv);
			INIT_PZVAL_COPY(new_zv, *arr);
			*arr = new_zv;
			zval_copy_ctor(new_zv);
		}
	}

	Z_ADDREF_P(value);
	return add_next_index_zval(*arr, value);
}
Beispiel #2
0
PHP_METHOD(Spotify, getPlaylists)
{
	zval *thisptr = getThis(), tempretval;
	int i, timeout = 0, num_playlists;

	spotify_object *p = (spotify_object*)zend_object_store_get_object(thisptr TSRMLS_CC);

	SPOTIFY_METHOD(Spotify, initPlaylistContainer, &tempretval, thisptr);

	array_init(return_value);

	num_playlists = sp_playlistcontainer_num_playlists(p->playlistcontainer);
	for (i=0; i<num_playlists; i++) {
		sp_playlist *playlist = sp_playlistcontainer_playlist(p->playlistcontainer, i);

		zval *z_playlist;
		ALLOC_INIT_ZVAL(z_playlist);
		object_init_ex(z_playlist, spotifyplaylist_ce);
		SPOTIFY_METHOD2(SpotifyPlaylist, __construct, &tempretval, z_playlist, thisptr, playlist);
		add_next_index_zval(return_value, z_playlist);
	}
}
Beispiel #3
0
/**
 * Call single static function on a zval which requires parameters
 */
inline int phalcon_call_static_zval_func_params(zval *return_value, zval *mixed_name, char *method_name, int method_len, zend_uint param_count, zval *params[], int noreturn TSRMLS_DC){

	zval *fn;
	int status = FAILURE;

	if (!noreturn) {
		ALLOC_INIT_ZVAL(return_value);
	}

	ALLOC_INIT_ZVAL(fn);
	array_init(fn);
	add_next_index_zval(fn, mixed_name);
	add_next_index_stringl(fn, method_name, method_len, 1);

	status = phalcon_call_user_function(CG(function_table), NULL, fn, return_value, param_count, params TSRMLS_CC);
	if (status == FAILURE) {
		if(Z_TYPE_P(mixed_name) == IS_STRING) {
			php_error_docref(NULL TSRMLS_CC, E_ERROR, "Call to undefined function %s::%s()", Z_STRVAL_P(mixed_name), method_name);
		} else {
			php_error_docref(NULL TSRMLS_CC, E_ERROR, "Call to undefined function not-callable::%s()", method_name);
		}
	}

	zval_ptr_dtor(&fn);

	if (!noreturn) {
		zval_ptr_dtor(&return_value);
	}

	if (EG(exception)) {
		status = FAILURE;
	}

	if (status == FAILURE) {
		phalcon_memory_restore_stack(TSRMLS_C);
	}

	return status;
}
/* {{{ proto array cl_get_devices(void)
   */
static PHP_FUNCTION(cl_get_devices)
{
	clmandelbrot_t ctx = { 0 };
	cl_uint i = 0;

	RETVAL_FALSE;

	if (ZEND_NUM_ARGS() != 0) {
		WRONG_PARAM_COUNT;
	}

	if (clm_setup_device(&ctx TSRMLS_CC) == FAILURE) {
		return;
	}

	array_init(return_value);

	for (i = 0; i < ctx.deviceCount; i++) {
		zval *zinfo = clm_get_device_info(ctx.deviceList[i] TSRMLS_CC);
		add_next_index_zval(return_value, zinfo);
	}
}
Beispiel #5
0
static void
enumerate_providers_fn (const char * const name,
                        const char * const desc,
                        const char * const file,
                        void * ud) /* {{{ */
{
	zval *zdesc = (zval *) ud;
	zval *tmp_array;

	MAKE_STD_ZVAL(tmp_array);
	array_init(tmp_array);

	add_assoc_string(tmp_array, "name", (char *)name, 1);
	add_assoc_string(tmp_array, "desc", (char *)desc, 1);
	add_assoc_string(tmp_array, "file", (char *)file, 1);

	if (Z_TYPE_P(zdesc)!=IS_ARRAY) {
		array_init(zdesc);
	}

	add_next_index_zval(zdesc, tmp_array);
}
Beispiel #6
0
/* {{{ php_parsekit_parse_arginfo */
static void php_parsekit_parse_arginfo(zval *return_value, zend_uint num_args, zend_arg_info *arginfo, long options TSRMLS_DC)
{
	zend_uint i;

	array_init(return_value);

	for(i = 0; i < num_args; i++) {
		zval *tmpzval;

		MAKE_STD_ZVAL(tmpzval);
		array_init(tmpzval);
		add_assoc_stringl(tmpzval, "name", arginfo[i].name, arginfo[i].name_len, 1);
		if (arginfo[i].class_name_len) {
			add_assoc_stringl(tmpzval, "class_name", arginfo[i].class_name, arginfo[i].class_name_len, 1);
		} else if (options & PHP_PARSEKIT_ALWAYS_SET) {
			add_assoc_null(tmpzval, "class_name");
		}
		add_assoc_bool(tmpzval, "allow_null", arginfo[i].allow_null);
		add_assoc_bool(tmpzval, "pass_by_reference", arginfo[i].pass_by_reference);

		add_next_index_zval(return_value, tmpzval);
	}	
}
Beispiel #7
0
/* {{{ proto array Glib::filenameGetCharsets()
	   Determines the preferred character sets used for filenames. 
	   Returns an array. The first element is a boolean indicating if the filename encoding
	   is UTF-8. The second element is the filename encoding.
	   The final element is an array of character sets used when trying to generate a
	   displayable representation of a filename.
	   */
PHP_METHOD(Glib, filenameGetCharsets)
{
	const gchar **charsets;
	gboolean utf8;
	zval *charset_array;
	int i;

	if (zend_parse_parameters_none() == FAILURE) {
		return;
	}

	array_init(return_value);
	MAKE_STD_ZVAL(charset_array);
	array_init(charset_array);

	utf8 = g_get_filename_charsets(&charsets);
	add_next_index_bool(return_value, utf8);
	add_next_index_string(return_value, (char *)charsets[0], 1);
	for (i = 1; charsets[i]; i++) {
		add_next_index_string(charset_array, (char *)charsets[i], 1);
	}
	add_next_index_zval(return_value, charset_array);
}
Beispiel #8
0
/* {{{ php_parsekit_derive_arginfo 
	ZE1 Func Arg loading is done via opcodes "RECV"ing from the caller */
static void php_parsekit_derive_arginfo(zval *return_value, zend_op_array *op_array, long options TSRMLS_DC)
{
	int i;
	zend_op *opcodes = op_array->opcodes;

	array_init(return_value);

	/* Received vars come in pairs:
		A ZEND_FETCH_W, and a ZEND_RECV */
	for(i = 0; i < op_array->arg_types[0]; i++) {
		if (opcodes[i*2].opcode   == ZEND_FETCH_W &&
			opcodes[i*2].op1.op_type == IS_CONST &&
			opcodes[i*2].op1.u.constant.type == IS_STRING &&
			(opcodes[(i*2)+1].opcode == ZEND_RECV || opcodes[(i*2)+1].opcode == ZEND_RECV_INIT)) {
			zval *tmpzval;

			MAKE_STD_ZVAL(tmpzval);
			array_init(tmpzval);

			add_assoc_stringl(tmpzval, "name", opcodes[i*2].op1.u.constant.value.str.val, opcodes[i*2].op1.u.constant.value.str.len, 1);
			add_assoc_bool(tmpzval, "pass_by_reference", op_array->arg_types[i+1]);
			if (opcodes[(i*2)+1].opcode == ZEND_RECV_INIT &&
				opcodes[(i*2)+1].op2.op_type == IS_CONST) {
				zval *def;
	
				MAKE_STD_ZVAL(def);
				*def = opcodes[(i*2)+1].op2.u.constant;
				zval_copy_ctor(def);
				add_assoc_zval(tmpzval, "default", def);
				Z_SET_REFCOUNT_P(tmpzval, 1);
			}

			add_next_index_zval(return_value, tmpzval);
		}
	}
}
Beispiel #9
0
PHP_METHOD(WinGdiPath, getPath)
{
    wingdi_devicecontext_object *dc_obj;
    wingdi_path_object *path_obj;
    LPPOINT points;
    LPBYTE  types;
    zval *point_array;
    int result, i,
        points_total = 0;

    WINGDI_ERROR_HANDLING();
    if (zend_parse_parameters_none() == FAILURE)
        return;
    WINGDI_RESTORE_ERRORS();

    path_obj = zend_object_store_get_object(getThis() TSRMLS_CC);
    dc_obj   = zend_object_store_get_object(path_obj->device_context TSRMLS_CC);

    // Determine how many points exist in the path
    points_total = GetPath(dc_obj->hdc, NULL, NULL, 0);
    points = emalloc(sizeof(POINT) * points_total);
    types  = emalloc(sizeof(BYTE) * points_total);
    result = GetPath(dc_obj->hdc, points, types, points_total);

    array_init(return_value);
    for (i = 0; i < points_total; i++)
    {
        MAKE_STD_ZVAL(point_array);
        add_next_index_long(point_array, points[i].x);
        add_next_index_long(point_array, points[i].y);
        // Could the char -> long conversion here cause problems?
        add_next_index_long(point_array, types[i]);
        // Store this array in parent array
        add_next_index_zval(return_value, point_array);
    }
}
/* {{{ proto resource clmandelbrot(int width, int height[, float unit])
   */
static PHP_FUNCTION(clmandelbrot)
{
	long width = 0;
	long height = 0;
	double unit = 0.0;
	long device = 0;

	zend_fcall_info fci;
	zend_fcall_info_cache fcc;
	zval *zim = NULL, *callable, *args, *zwidth, *zheight;
	int err;
	gdImagePtr im;

	RETVAL_FALSE;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
			"ll|dl", &width, &height, &unit, &device) == FAILURE) {
		return;
	}

	MAKE_STD_ZVAL(callable);
	ZVAL_STRING(callable, "imagecreatetruecolor", 1);
	err = zend_fcall_info_init(callable, 0, &fci, &fcc,
	                           NULL, NULL TSRMLS_CC);

	if (err != SUCCESS) {
		zval_ptr_dtor(&callable);
		return;
	}

	MAKE_STD_ZVAL(args);
	MAKE_STD_ZVAL(zwidth);
	MAKE_STD_ZVAL(zheight);
	ZVAL_LONG(zwidth, width);
	ZVAL_LONG(zheight, height);
	array_init(args);
	add_next_index_zval(args, zwidth);
	add_next_index_zval(args, zheight);

	zend_fcall_info_call(&fci, &fcc, &zim, args TSRMLS_CC);
	zval_ptr_dtor(&callable);
	zval_ptr_dtor(&args);

	if (!zim) {
		return;
	}

	ZEND_FETCH_RESOURCE_NO_RETURN(im, gdImagePtr, &zim, -1,
	                              "Image", phpi_get_le_gd());
	if (im) {
		size_t len;
		clmandelbrot_t ctx = { 0 };
		ctx.deviceId = (cl_uint)device;
		ctx.width = gdImageSX(im);
		ctx.height = gdImageSY(im);
		if (unit > 0.0) {
			ctx.unit = (float)unit;
		} else {
			ctx.unit = 10.0f / (float)(ctx.width + ctx.height);
		}
		len = ctx.width * ctx.height;
		ctx.bitmap = ecalloc(len, sizeof(unsigned char));
		if (!ctx.bitmap) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING,
			                 "cannot allocate memory");
		} else {
			if (clm_process(im, &ctx TSRMLS_CC) == SUCCESS) {
				RETVAL_ZVAL(zim, 1, 0);
			}
		}
		clm_release(&ctx);
	}
	zval_ptr_dtor(&zim);
}
Beispiel #11
0
/* {{{ proto string q(string arg)
   Return Array,of which the 1st value is addr1 and the 2nd value is addr2*/
PHP_METHOD(qqwry,q)
{
	char *ip_string = NULL;
	int ipstring_len;
    zval * _this_zval = NULL;

    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,getThis(), "Os",&_this_zval,qqwry_class_entry_ptr, &ip_string, &ipstring_len) == FAILURE) {
        return;
    }   
	zval *zaddr1,*zaddr2;
	char *addr1=(char *)emalloc(QQWRY_ADDR1_LEN);
	char *addr2=(char *)emalloc(QQWRY_ADDR2_LEN);
	memset(addr1,0,QQWRY_ADDR1_LEN);
	memset(addr2,0,QQWRY_ADDR2_LEN);
	zval **tmp;
	char *qqwry_path;
	if (zend_hash_find(Z_OBJPROP_P(_this_zval),"f",sizeof("f"),(void **)&tmp)==FAILURE) {
		return;
	}
	qqwry_path=Z_STRVAL_PP(tmp);

	FILE *fp=NULL;
    qqwry_fp_list *qfl=QQWRY_G(fp_list);
	while (qfl) {
		if (!strcmp(qfl->filepath,qqwry_path)) {
			fp=qfl->fp;
			break;
		}
		qfl=qfl->next;
	}

	if (!fp) {
		qqwry_fp_list *pre_qfl=NULL;
		qfl=QQWRY_G(fp_list);
		while (qfl) {
			pre_qfl=qfl;
			qfl=qfl->next;
		}
		fp=fopen(qqwry_path,"rb");
		if (!fp) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING,"%s",strerror(errno));
			return;
		}
		qfl=emalloc(sizeof(qqwry_fp_list));
		qfl->filepath = estrndup(qqwry_path, strlen(qqwry_path));
		qfl->fp=fp;
		qfl->next=NULL;
		if (pre_qfl) {
			pre_qfl->next=qfl;
		} else {
			QQWRY_G(fp_list)=qfl;
		}
	}

	qqwry_get_location(addr1,addr2,ip_string,fp);
	MAKE_STD_ZVAL(zaddr1);
	ZVAL_STRING(zaddr1,addr1,0);
	MAKE_STD_ZVAL(zaddr2);
	ZVAL_STRING(zaddr2,addr2,0);

	array_init(return_value);
    add_next_index_zval(return_value,zaddr1);
    add_next_index_zval(return_value,zaddr2);
}
Beispiel #12
0
static zend_bool tokenize(zval *return_value, zend_string *source)
{
	zval source_zval;
	zend_lex_state original_lex_state;
	zval token;
	zval keyword;
	int token_type;
	int token_line = 1;
	int need_tokens = -1; /* for __halt_compiler lexing. -1 = disabled */

	ZVAL_STR_COPY(&source_zval, source);
	zend_save_lexical_state(&original_lex_state);

	if (zend_prepare_string_for_scanning(&source_zval, "") == FAILURE) {
		zend_restore_lexical_state(&original_lex_state);
		return 0;
	}

	LANG_SCNG(yy_state) = yycINITIAL;
	array_init(return_value);

	ZVAL_UNDEF(&token);
	while ((token_type = lex_scan(&token))) {
		if (token_type == T_CLOSE_TAG && zendtext[zendleng - 1] != '>') {
			CG(zend_lineno)++;
		}

		if (token_type >= 256) {
			array_init(&keyword);
			add_next_index_long(&keyword, token_type);
			if (token_type == T_END_HEREDOC) {
				if (CG(increment_lineno)) {
					token_line = ++CG(zend_lineno);
					CG(increment_lineno) = 0;
				}
			}
			add_next_index_stringl(&keyword, (char *)zendtext, zendleng);
			add_next_index_long(&keyword, token_line);
			add_next_index_zval(return_value, &keyword);
		} else {
			add_next_index_stringl(return_value, (char *)zendtext, zendleng);
		}

		if (Z_TYPE(token) != IS_UNDEF) {
			zval_dtor(&token);
			ZVAL_UNDEF(&token);
		}

		/* after T_HALT_COMPILER collect the next three non-dropped tokens */
		if (need_tokens != -1) {
			if (token_type != T_WHITESPACE && token_type != T_OPEN_TAG
				&& token_type != T_COMMENT && token_type != T_DOC_COMMENT
				&& --need_tokens == 0
			) {
				/* fetch the rest into a T_INLINE_HTML */
				if (zendcursor != zendlimit) {
					array_init(&keyword);
					add_next_index_long(&keyword, T_INLINE_HTML);
					add_next_index_stringl(&keyword, (char *)zendcursor, zendlimit - zendcursor);
					add_next_index_long(&keyword, token_line);
					add_next_index_zval(return_value, &keyword);
				}
				break;
			}
		} else if (token_type == T_HALT_COMPILER) {
			need_tokens = 3;
		}

		token_line = CG(zend_lineno);
	}

	zval_dtor(&source_zval);
	zend_restore_lexical_state(&original_lex_state);

	return 1;
}
Beispiel #13
0
static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
{
	xsltTransformContextPtr tctxt;
	zval *args;
	zval retval;
	int result, i;
	int error = 0;
	zend_fcall_info fci;
	zval handler;
	xmlXPathObjectPtr obj;
	char *str;
	xsl_object *intern;
	zend_string *callable = NULL;


	if (! zend_is_executing()) {
		xsltGenericError(xsltGenericErrorContext,
		"xsltExtFunctionTest: Function called from outside of PHP\n");
		error = 1;
	} else {
		tctxt = xsltXPathGetTransformContext(ctxt);
		if (tctxt == NULL) {
			xsltGenericError(xsltGenericErrorContext,
			"xsltExtFunctionTest: failed to get the transformation context\n");
			error = 1;
		} else {
			intern = (xsl_object*)tctxt->_private;
			if (intern == NULL) {
				xsltGenericError(xsltGenericErrorContext,
				"xsltExtFunctionTest: failed to get the internal object\n");
				error = 1;
			}
			else if (intern->registerPhpFunctions == 0) {
				xsltGenericError(xsltGenericErrorContext,
				"xsltExtFunctionTest: PHP Object did not register PHP functions\n");
				error = 1;
			}
		}
	}

	if (error == 1) {
		for (i = nargs - 1; i >= 0; i--) {
			obj = valuePop(ctxt);
			xmlXPathFreeObject(obj);
		}
		return;
	}

	fci.param_count = nargs - 1;
	if (fci.param_count > 0) {
		args = safe_emalloc(fci.param_count, sizeof(zval), 0);
	}
	/* Reverse order to pop values off ctxt stack */
	for (i = nargs - 2; i >= 0; i--) {
		obj = valuePop(ctxt);
		switch (obj->type) {
			case XPATH_STRING:
				ZVAL_STRING(&args[i], (char *)obj->stringval);
				break;
			case XPATH_BOOLEAN:
				ZVAL_BOOL(&args[i],  obj->boolval);
				break;
			case XPATH_NUMBER:
				ZVAL_DOUBLE(&args[i], obj->floatval);
				break;
			case XPATH_NODESET:
				if (type == 1) {
					str = (char*)xmlXPathCastToString(obj);
					ZVAL_STRING(&args[i], str);
					xmlFree(str);
				} else if (type == 2) {
					int j;
					dom_object *domintern = (dom_object *)intern->doc;
					array_init(&args[i]);
					if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
						for (j = 0; j < obj->nodesetval->nodeNr; j++) {
							xmlNodePtr node = obj->nodesetval->nodeTab[j];
							zval child;
							/* not sure, if we need this... it's copied from xpath.c */
							if (node->type == XML_NAMESPACE_DECL) {
								xmlNsPtr curns;
								xmlNodePtr nsparent;

								nsparent = node->_private;
								curns = xmlNewNs(NULL, node->name, NULL);
								if (node->children) {
									curns->prefix = xmlStrdup((char *)node->children);
								}
								if (node->children) {
									node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name);
								} else {
									node = xmlNewDocNode(node->doc, NULL, (const xmlChar *) "xmlns", node->name);
								}
								node->type = XML_NAMESPACE_DECL;
								node->parent = nsparent;
								node->ns = curns;
							} else {
								node = xmlDocCopyNodeList(domintern->document->ptr, node);
							}

							php_dom_create_object(node, &child, domintern);
							add_next_index_zval(&args[i], &child);
						}
					}
				}
				break;
			default:
				str = (char *) xmlXPathCastToString(obj);
				ZVAL_STRING(&args[i], str);
				xmlFree(str);
		}
		xmlXPathFreeObject(obj);
	}

	fci.size = sizeof(fci);
	fci.function_table = EG(function_table);
	if (fci.param_count > 0) {
		fci.params = args;
	} else {
		fci.params = NULL;
	}


	obj = valuePop(ctxt);
	if (obj->stringval == NULL) {
		php_error_docref(NULL, E_WARNING, "Handler name must be a string");
		xmlXPathFreeObject(obj);
		valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
		if (fci.param_count > 0) {
			for (i = 0; i < nargs - 1; i++) {
				zval_ptr_dtor(&args[i]);
			}
			efree(args);
		}
		return;
	}
	ZVAL_STRING(&handler, (char *) obj->stringval);
	xmlXPathFreeObject(obj);

	ZVAL_COPY_VALUE(&fci.function_name, &handler);
	fci.symbol_table = NULL;
	fci.object = NULL;
	fci.retval = &retval;
	fci.no_separation = 0;
	/*fci.function_handler_cache = &function_ptr;*/
	if (!zend_make_callable(&handler, &callable)) {
		php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", ZSTR_VAL(callable));
		valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
	} else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) {
		php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'", ZSTR_VAL(callable));
		/* Push an empty string, so that we at least have an xslt result... */
		valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
	} else {
		result = zend_call_function(&fci, NULL);
		if (result == FAILURE) {
			if (Z_TYPE(handler) == IS_STRING) {
				php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", Z_STRVAL(handler));
				valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
			}
		/* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */
		} else if (Z_ISUNDEF(retval)) {
		} else {
			if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) {
				xmlNode *nodep;
				dom_object *obj;
				if (intern->node_list == NULL) {
					ALLOC_HASHTABLE(intern->node_list);
					zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
				}
				Z_ADDREF(retval);
				zend_hash_next_index_insert(intern->node_list, &retval);
				obj = Z_DOMOBJ_P(&retval);
				nodep = dom_object_get_node(obj);
				valuePush(ctxt, xmlXPathNewNodeSet(nodep));
			} else if (Z_TYPE(retval) == IS_TRUE || Z_TYPE(retval) == IS_FALSE) {
				valuePush(ctxt, xmlXPathNewBoolean(Z_LVAL(retval)));
			} else if (Z_TYPE(retval) == IS_OBJECT) {
				php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
				valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
			} else {
				convert_to_string_ex(&retval);
				valuePush(ctxt, xmlXPathNewString((xmlChar *) Z_STRVAL(retval)));
			}
			zval_ptr_dtor(&retval);
		}
	}
	zend_string_release(callable);
	zval_ptr_dtor(&handler);
	if (fci.param_count > 0) {
		for (i = 0; i < nargs - 1; i++) {
			zval_ptr_dtor(&args[i]);
		}
		efree(args);
	}
}
Beispiel #14
0
static void php_xpath_eval(INTERNAL_FUNCTION_PARAMETERS, int type) /* {{{ */
{
	zval *id, retval, *context = NULL;
	xmlXPathContextPtr ctxp;
	xmlNodePtr nodep = NULL;
	xmlXPathObjectPtr xpathobjp;
	size_t expr_len, nsnbr = 0, xpath_type;
	dom_xpath_object *intern;
	dom_object *nodeobj;
	char *expr;
	xmlDoc *docp = NULL;
	xmlNsPtr *ns = NULL;
	zend_bool register_node_ns = 1;

	if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|O!b", &id, dom_xpath_class_entry, &expr, &expr_len, &context, dom_node_class_entry, &register_node_ns) == FAILURE) {
		return;
	}

	intern = Z_XPATHOBJ_P(id);

	ctxp = (xmlXPathContextPtr) intern->dom.ptr;
	if (ctxp == NULL) {
		php_error_docref(NULL, E_WARNING, "Invalid XPath Context");
		RETURN_FALSE;
	}

	docp = (xmlDocPtr) ctxp->doc;
	if (docp == NULL) {
		php_error_docref(NULL, E_WARNING, "Invalid XPath Document Pointer");
		RETURN_FALSE;
	}

	if (context != NULL) {
		DOM_GET_OBJ(nodep, context, xmlNodePtr, nodeobj);
	}

	if (!nodep) {
		nodep = xmlDocGetRootElement(docp);
	}

	if (nodep && docp != nodep->doc) {
		php_error_docref(NULL, E_WARNING, "Node From Wrong Document");
		RETURN_FALSE;
	}

	ctxp->node = nodep;

	if (register_node_ns) {
		/* Register namespaces in the node */
		ns = xmlGetNsList(docp, nodep);

		if (ns != NULL) {
			while (ns[nsnbr] != NULL)
			nsnbr++;
		}
	}


    ctxp->namespaces = ns;
    ctxp->nsNr = nsnbr;

	xpathobjp = xmlXPathEvalExpression((xmlChar *) expr, ctxp);
	ctxp->node = NULL;

	if (ns != NULL) {
		xmlFree(ns);
		ctxp->namespaces = NULL;
		ctxp->nsNr = 0;
	}

	if (! xpathobjp) {
		RETURN_FALSE;
	}

	if (type == PHP_DOM_XPATH_QUERY) {
		xpath_type = XPATH_NODESET;
	} else {
		xpath_type = xpathobjp->type;
	}

	switch (xpath_type) {

		case  XPATH_NODESET:
		{
			int i;
			xmlNodeSetPtr nodesetp;

			array_init(&retval);

			if (xpathobjp->type == XPATH_NODESET && NULL != (nodesetp = xpathobjp->nodesetval)) {

				for (i = 0; i < nodesetp->nodeNr; i++) {
					xmlNodePtr node = nodesetp->nodeTab[i];
					zval child;

					if (node->type == XML_NAMESPACE_DECL) {
						xmlNsPtr curns;
						xmlNodePtr nsparent;

						nsparent = node->_private;
						curns = xmlNewNs(NULL, node->name, NULL);
						if (node->children) {
							curns->prefix = xmlStrdup((xmlChar *) node->children);
						}
						if (node->children) {
							node = xmlNewDocNode(docp, NULL, (xmlChar *) node->children, node->name);
						} else {
							node = xmlNewDocNode(docp, NULL, (xmlChar *) "xmlns", node->name);
						}
						node->type = XML_NAMESPACE_DECL;
						node->parent = nsparent;
						node->ns = curns;
					}
					php_dom_create_object(node, &child, &intern->dom);
					add_next_index_zval(&retval, &child);
				}
			}
			php_dom_create_interator(return_value, DOM_NODELIST);
			nodeobj = Z_DOMOBJ_P(return_value);
			dom_xpath_iter(&retval, nodeobj);
			break;
		}

		case XPATH_BOOLEAN:
			RETVAL_BOOL(xpathobjp->boolval);
			break;

		case XPATH_NUMBER:
			RETVAL_DOUBLE(xpathobjp->floatval)
			break;

		case XPATH_STRING:
			RETVAL_STRING((char *) xpathobjp->stringval);
			break;

		default:
			RETVAL_NULL();
			break;
	}

	xmlXPathFreeObject(xpathobjp);
}
Beispiel #15
0
static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
{
	zval retval;
	int result, i;
	int error = 0;
	zend_fcall_info fci;
	xmlXPathObjectPtr obj;
	char *str;
	zend_string *callable = NULL;
	dom_xpath_object *intern;


	if (! zend_is_executing()) {
		xmlGenericError(xmlGenericErrorContext,
		"xmlExtFunctionTest: Function called from outside of PHP\n");
		error = 1;
	} else {
		intern = (dom_xpath_object *) ctxt->context->userData;
		if (intern == NULL) {
			xmlGenericError(xmlGenericErrorContext,
			"xmlExtFunctionTest: failed to get the internal object\n");
			error = 1;
		}
		else if (intern->registerPhpFunctions == 0) {
			xmlGenericError(xmlGenericErrorContext,
			"xmlExtFunctionTest: PHP Object did not register PHP functions\n");
			error = 1;
		}
	}

	if (error == 1) {
		for (i = nargs - 1; i >= 0; i--) {
			obj = valuePop(ctxt);
			xmlXPathFreeObject(obj);
		}
		return;
	}

	fci.param_count = nargs - 1;
	if (fci.param_count > 0) {
		fci.params = safe_emalloc(fci.param_count, sizeof(zval), 0);
	}
	/* Reverse order to pop values off ctxt stack */
	for (i = nargs - 2; i >= 0; i--) {
		obj = valuePop(ctxt);
		switch (obj->type) {
			case XPATH_STRING:
				ZVAL_STRING(&fci.params[i],  (char *)obj->stringval);
				break;
			case XPATH_BOOLEAN:
				ZVAL_BOOL(&fci.params[i],  obj->boolval);
				break;
			case XPATH_NUMBER:
				ZVAL_DOUBLE(&fci.params[i], obj->floatval);
				break;
			case XPATH_NODESET:
				if (type == 1) {
					str = (char *)xmlXPathCastToString(obj);
					ZVAL_STRING(&fci.params[i], str);
					xmlFree(str);
				} else if (type == 2) {
					int j;
					array_init(&fci.params[i]);
					if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
						for (j = 0; j < obj->nodesetval->nodeNr; j++) {
							xmlNodePtr node = obj->nodesetval->nodeTab[j];
							zval child;
							/* not sure, if we need this... it's copied from xpath.c */
							if (node->type == XML_NAMESPACE_DECL) {
								xmlNsPtr curns;
								xmlNodePtr nsparent;

								nsparent = node->_private;
								curns = xmlNewNs(NULL, node->name, NULL);
								if (node->children) {
									curns->prefix = xmlStrdup((xmlChar *) node->children);
								}
								if (node->children) {
									node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name);
								} else {
									node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name);
								}
								node->type = XML_NAMESPACE_DECL;
								node->parent = nsparent;
								node->ns = curns;
							}
							php_dom_create_object(node, &child, &intern->dom);
							add_next_index_zval(&fci.params[i], &child);
						}
					}
				}
				break;
			default:
			ZVAL_STRING(&fci.params[i], (char *)xmlXPathCastToString(obj));
		}
		xmlXPathFreeObject(obj);
	}

	fci.size = sizeof(fci);
	fci.function_table = EG(function_table);

	obj = valuePop(ctxt);
	if (obj->stringval == NULL) {
		php_error_docref(NULL, E_WARNING, "Handler name must be a string");
		xmlXPathFreeObject(obj);
		if (fci.param_count > 0) {
			for (i = 0; i < nargs - 1; i++) {
				zval_ptr_dtor(&fci.params[i]);
			}
			efree(fci.params);
		}
		return;
	}
	ZVAL_STRING(&fci.function_name, (char *) obj->stringval);
	xmlXPathFreeObject(obj);

	fci.symbol_table = NULL;
	fci.object = NULL;
	fci.retval = &retval;
	fci.no_separation = 0;

	if (!zend_make_callable(&fci.function_name, &callable)) {
		php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", callable->val);
	} else if (intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) {
		php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'.", callable->val);
		/* Push an empty string, so that we at least have an xslt result... */
		valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
	} else {
		result = zend_call_function(&fci, NULL);
		if (result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
			if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) {
				xmlNode *nodep;
				dom_object *obj;
				if (intern->node_list == NULL) {
					ALLOC_HASHTABLE(intern->node_list);
					zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
				}
				GC_REFCOUNT(&retval)++;
				zend_hash_next_index_insert(intern->node_list, &retval);
				obj = Z_DOMOBJ_P(&retval);
				nodep = dom_object_get_node(obj);
				valuePush(ctxt, xmlXPathNewNodeSet(nodep));
			} else if (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE) {
				valuePush(ctxt, xmlXPathNewBoolean(Z_TYPE(retval) == IS_TRUE));
			} else if (Z_TYPE(retval) == IS_OBJECT) {
				php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
				valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
			} else {
				zend_string *str = zval_get_string(&retval);
				valuePush(ctxt, xmlXPathNewString((xmlChar *) str->val));
				zend_string_release(str);
			}
			zval_ptr_dtor(&retval);
		}
	}
	zend_string_release(callable);
	zval_dtor(&fci.function_name);
	if (fci.param_count > 0) {
		for (i = 0; i < nargs - 1; i++) {
			zval_ptr_dtor(&fci.params[i]);
		}
		efree(fci.params);
	}
}
Beispiel #16
0
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; 

}
Beispiel #17
0
PHP_METHOD(air_mysql_waiter, step_0) {
	AIR_INIT_THIS;
	zval *services = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("_services"), 0 TSRMLS_CC);
	zval *responses = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("_responses"), 0 TSRMLS_CC);
	zval *context = zend_read_property(Z_OBJCE_P(self), self, ZEND_STRL("_context"), 0 TSRMLS_CC);
	zend_class_entry *mysqli_ce = air_get_ce(ZEND_STRL("mysqli") TSRMLS_CC);
	zval *async;
	MAKE_STD_ZVAL(async);
	ZVAL_LONG(async, MYSQLI_ASYNC);

	zval *wait_pool, *m2s;
	MAKE_STD_ZVAL(wait_pool);
	array_init(wait_pool);
	MAKE_STD_ZVAL(m2s);
	array_init(m2s);

	zval *service;
	ulong idx;
	uint _idx, key_len;
	char *key;
	zval *mysqli = NULL;
	HashTable *ah = Z_ARRVAL_P(services);
	for(zend_hash_internal_pointer_reset(ah);
			zend_hash_has_more_elements(ah) == SUCCESS;){
		zval **___tmp;
		if (zend_hash_get_current_data(ah, (void**)&___tmp) == FAILURE) {
			continue;
		}
		if(zend_hash_get_current_key_ex(ah, &key, &key_len, &idx, 0, NULL) != HASH_KEY_IS_STRING) {
			key = NULL; key_len = 0;
		}
		service = *___tmp;
		if(Z_TYPE_P(service) == IS_NULL){
			zend_hash_index_del(ah, idx);
			continue;
		}
		zval *service_id = zend_read_property(air_async_service_ce, service, ZEND_STRL("_id"), 1 TSRMLS_CC);
		zval *mysql = zend_read_property(air_async_service_ce, service, ZEND_STRL("_request"), 1 TSRMLS_CC);
		zval *status = zend_read_property(air_mysql_ce, mysql, ZEND_STRL("_status"), 0 TSRMLS_CC);
		if(Z_LVAL_P(status)){
			//ignore if the mysql's been executed
			zend_hash_index_del(ah, idx);
			continue;
		}
		zval *mysql_config = zend_read_property(air_mysql_ce, mysql, ZEND_STRL("_config"), 1 TSRMLS_CC);
		zval *mode = zend_read_property(air_mysql_ce, mysql, ZEND_STRL("_mode"), 1 TSRMLS_CC);
		if(Z_TYPE_P(mode) == IS_NULL){
			air_mysql_auto_mode(mysql TSRMLS_CC);
			mode = zend_read_property(air_mysql_ce, mysql, ZEND_STRL("_mode"), 1 TSRMLS_CC);
		}
		zval **acquire_params[2] = {&mysql_config, &mode};
		mysqli = NULL;
		air_call_static_method(air_mysql_keeper_ce, "acquire", &mysqli, 2, acquire_params);
		if(Z_TYPE_P(mysqli) != IS_NULL){
			zval **build_params[1] = {&mysqli};
			zval *sql = NULL;
			air_call_method(&mysql, air_mysql_ce, NULL, ZEND_STRL("build"), &sql, 1, build_params TSRMLS_CC);
			if(sql){
				zval **query_params[2] = {&sql, &async};
				air_call_method(&mysqli, mysqli_ce, NULL, ZEND_STRL("query"), NULL, 2, query_params TSRMLS_CC);
				add_next_index_zval(wait_pool, mysqli);
				Z_ADDREF_P(service_id);
				add_index_zval(m2s, air_mysqli_get_id(mysqli TSRMLS_CC), service_id);
				zval_ptr_dtor(&sql);
			}else{
				//should not happen
				php_error(E_ERROR, "sql not found");
				zval_ptr_dtor(&mysqli);
			}
		}else{
			zval_ptr_dtor(&mysqli);
		}
		zend_hash_move_forward(ah);
	}
	zval_ptr_dtor(&async);
	add_assoc_zval(context, "pool", wait_pool);
	add_assoc_zval(context, "m2s", m2s);
	add_assoc_long(context, "waited", zend_hash_num_elements(Z_ARRVAL_P(wait_pool)));
	add_assoc_long(context, "processed", 0);
	add_assoc_long(context, "step", 1);
}
Beispiel #18
0
static void php_mongo_enumerate_collections(INTERNAL_FUNCTION_PARAMETERS, int full_collection)
{
	zend_bool system_col = 0;
	zval *nss, *collection, *cursor, *list, *next;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &system_col) == FAILURE) {
		return;
	}

  // select db.system.namespaces collection
  MAKE_STD_ZVAL(nss);
  ZVAL_STRING(nss, "system.namespaces", 1);

  MAKE_STD_ZVAL(collection);
  MONGO_METHOD1(MongoDB, selectCollection, collection, getThis(), nss);

  // list to return
  MAKE_STD_ZVAL(list);
  array_init(list);

  // do find
  MAKE_STD_ZVAL(cursor);
  MONGO_METHOD(MongoCollection, find, cursor, collection);

  // populate list
  MAKE_STD_ZVAL(next);
  MONGO_METHOD(MongoCursor, getNext, next, cursor);
  while (!IS_SCALAR_P(next)) {
    zval *c, *zname;
    zval **collection;
    char *name, *first_dot, *system;

    // check that the ns is valid and not an index (contains $)
    if (zend_hash_find(HASH_P(next), "name", 5, (void**)&collection) == FAILURE ||
        strchr(Z_STRVAL_PP(collection), '$')) {

      zval_ptr_dtor(&next);
      MAKE_STD_ZVAL(next);
      ZVAL_NULL(next);

      MONGO_METHOD(MongoCursor, getNext, next, cursor);
      continue;
    }

    first_dot = strchr(Z_STRVAL_PP(collection), '.');
    system = strstr(Z_STRVAL_PP(collection), ".system.");
    // check that this isn't a system ns
    if (!system_col && (system && first_dot == system) ||
      (name = strchr(Z_STRVAL_PP(collection), '.')) == 0) {

      zval_ptr_dtor(&next);
      MAKE_STD_ZVAL(next);
      ZVAL_NULL(next);

      MONGO_METHOD(MongoCursor, getNext, next, cursor);
      continue;
    }

    // take a substring after the first "."
    name++;

    // "foo." was allowed in earlier versions
    if (name == '\0') {
      zval_ptr_dtor(&next);
      MAKE_STD_ZVAL(next);
      ZVAL_NULL(next);

      MONGO_METHOD(MongoCursor, getNext, next, cursor);
      continue;
    }

	if (full_collection) {
		MAKE_STD_ZVAL(c);
		ZVAL_NULL(c);

		MAKE_STD_ZVAL(zname);
		ZVAL_NULL(zname);

		// name must be copied because it is a substring of
		// a string that will be garbage collected in a sec
		ZVAL_STRING(zname, name, 1);
		MONGO_METHOD1(MongoDB, selectCollection, c, getThis(), zname);

		add_next_index_zval(list, c);

		zval_ptr_dtor(&zname);
	} else {
		add_next_index_string(list, name, 1);
	}
    zval_ptr_dtor(&next);
    MAKE_STD_ZVAL(next);

    MONGO_METHOD(MongoCursor, getNext, next, cursor);
  }

  zval_ptr_dtor(&next);
  zval_ptr_dtor(&nss);
  zval_ptr_dtor(&cursor);
  zval_ptr_dtor(&collection);

  RETURN_ZVAL(list, 0, 1);
}
Beispiel #19
0
PHP_METHOD(MongoDB, listCollections) {
  // select db.system.namespaces collection
  zval *nss, *collection, *cursor, *list, *next;

  MAKE_STD_ZVAL(nss);
  ZVAL_STRING(nss, "system.namespaces", 1);

  MAKE_STD_ZVAL(collection);
  MONGO_METHOD1(MongoDB, selectCollection, collection, getThis(), nss);

  // list to return
  MAKE_STD_ZVAL(list);
  array_init(list);

  // do find
  MAKE_STD_ZVAL(cursor);
  MONGO_METHOD(MongoCollection, find, cursor, collection);

  // populate list
  MAKE_STD_ZVAL(next);
  MONGO_METHOD(MongoCursor, getNext, next, cursor);
  while (!IS_SCALAR_P(next)) {
    zval *c, *zname;
    zval **collection;
    char *name, *first_dot, *system;

    // check that the ns is valid and not an index (contains $)
    if (zend_hash_find(HASH_P(next), "name", 5, (void**)&collection) == FAILURE ||
        strchr(Z_STRVAL_PP(collection), '$')) {

      zval_ptr_dtor(&next);
      MAKE_STD_ZVAL(next);
      ZVAL_NULL(next);

      MONGO_METHOD(MongoCursor, getNext, next, cursor);
      continue;
    }

    first_dot = strchr(Z_STRVAL_PP(collection), '.');
    system = strstr(Z_STRVAL_PP(collection), ".system.");
    // check that this isn't a system ns
    if ((system && first_dot == system) ||
	(name = strchr(Z_STRVAL_PP(collection), '.')) == 0) {

      zval_ptr_dtor(&next);
      MAKE_STD_ZVAL(next);
      ZVAL_NULL(next);

      MONGO_METHOD(MongoCursor, getNext, next, cursor);
      continue;
    }

    // take a substring after the first "."
    name++;

    // "foo." was allowed in earlier versions
    if (name == '\0') {
      zval_ptr_dtor(&next);
      MAKE_STD_ZVAL(next);
      ZVAL_NULL(next);

      MONGO_METHOD(MongoCursor, getNext, next, cursor);
      continue;
    }

    MAKE_STD_ZVAL(c);
    ZVAL_NULL(c);

    MAKE_STD_ZVAL(zname);
    ZVAL_NULL(zname);

    // name must be copied because it is a substring of
    // a string that will be garbage collected in a sec
    ZVAL_STRING(zname, name, 1);
    MONGO_METHOD1(MongoDB, selectCollection, c, getThis(), zname);

    add_next_index_zval(list, c);

    zval_ptr_dtor(&zname);
    zval_ptr_dtor(&next);
    MAKE_STD_ZVAL(next);

    MONGO_METHOD(MongoCursor, getNext, next, cursor);
  }

  zval_ptr_dtor(&next);
  zval_ptr_dtor(&nss);
  zval_ptr_dtor(&cursor);
  zval_ptr_dtor(&collection);

  RETURN_ZVAL(list, 0, 1);
}
int msgpack_convert_array(zval *return_value, zval *tpl, zval **value)
{
    TSRMLS_FETCH();

    if (Z_TYPE_P(tpl) == IS_ARRAY)
    {
        char *key;
        uint key_len;
        int key_type;
        ulong key_index;
        zval **data, **arydata;
        HashPosition pos, valpos;
        HashTable *ht, *htval;
        int num;

        ht = HASH_OF(tpl);
        // TODO: maybe need to release memory?
        array_init(return_value);

        num = zend_hash_num_elements(ht);
        if (num <= 0)
        {
            MSGPACK_WARNING(
                "[msgpack] (%s) template array length is 0",
                __FUNCTION__);
            zval_ptr_dtor(value);
            return FAILURE;
        }

        /* string */
        if (ht->nNumOfElements != ht->nNextFreeElement)
        {
            htval = HASH_OF(*value);
            if (!htval)
            {
                MSGPACK_WARNING(
                    "[msgpack] (%s) input data is not array",
                    __FUNCTION__);
                zval_ptr_dtor(value);
                return FAILURE;
            }

            zend_hash_internal_pointer_reset_ex(ht, &pos);
            zend_hash_internal_pointer_reset_ex(htval, &valpos);
            for (;; zend_hash_move_forward_ex(ht, &pos),
                        zend_hash_move_forward_ex(htval, &valpos))
            {
                key_type = zend_hash_get_current_key_ex(
                    ht, &key, &key_len, &key_index, 0, &pos);

                if (key_type == HASH_KEY_NON_EXISTANT)
                {
                    break;
                }

                if (zend_hash_get_current_data_ex(
                        ht, (void *)&data, &pos) != SUCCESS)
                {
                    continue;
                }

                if (key_type == HASH_KEY_IS_STRING)
                {
                    int (*convert_function)(zval *, zval *, zval **) = NULL;
                    zval **dataval, *val;

                    switch (Z_TYPE_PP(data))
                    {
                        case IS_ARRAY:
                            convert_function = msgpack_convert_array;
                            break;
                        case IS_OBJECT:
                        // case IS_STRING:
                            convert_function = msgpack_convert_object;
                            break;
                        default:
                            break;
                    }

                    if (zend_hash_get_current_data_ex(
                            htval, (void *)&dataval, &valpos) != SUCCESS)
                    {
                        MSGPACK_WARNING(
                            "[msgpack] (%s) can't get data",
                            __FUNCTION__);
                        zval_ptr_dtor(value);
                        return FAILURE;
                    }

                    MSGPACK_CONVERT_COPY_ZVAL(val, dataval);

                    if (convert_function)
                    {
                        zval *rv;
                        ALLOC_INIT_ZVAL(rv);
                        if (convert_function(rv, *data, &val) != SUCCESS)
                        {
                            zval_ptr_dtor(&val);
                            return FAILURE;
                        }
                        add_assoc_zval_ex(return_value, key, key_len, rv);
                    }
                    else
                    {
                        add_assoc_zval_ex(return_value, key, key_len, val);
                    }
                }
            }

            zval_ptr_dtor(value);

            return SUCCESS;
        }
        else
        {
            /* index */
            int (*convert_function)(zval *, zval *, zval **) = NULL;

            if (Z_TYPE_PP(value) != IS_ARRAY)
            {
                MSGPACK_WARNING(
                    "[msgpack] (%s) unserialized data must be array.",
                    __FUNCTION__);
                zval_ptr_dtor(value);
                return FAILURE;
            }

            zend_hash_internal_pointer_reset_ex(ht, &pos);

            key_type = zend_hash_get_current_key_ex(
                ht, &key, &key_len, &key_index, 0, &pos);

            if (key_type == HASH_KEY_NON_EXISTANT)
            {
                MSGPACK_WARNING(
                    "[msgpack] (%s) first element in template array is empty",
                    __FUNCTION__);
                zval_ptr_dtor(value);
                return FAILURE;
            }

            if (zend_hash_get_current_data_ex(
                    ht, (void *)&data, &pos) != SUCCESS)
            {
                MSGPACK_WARNING(
                    "[msgpack] (%s) invalid template: empty array?",
                    __FUNCTION__);
                zval_ptr_dtor(value);
                return FAILURE;
            }

            switch (Z_TYPE_PP(data))
            {
                case IS_ARRAY:
                    convert_function = msgpack_convert_array;
                    break;
                case IS_OBJECT:
                case IS_STRING:
                    convert_function = msgpack_convert_object;
                    break;
                default:
                    break;
            }

            htval = HASH_OF(*value);
            num = zend_hash_num_elements(htval);
            if (num <= 0)
            {
                MSGPACK_WARNING(
                    "[msgpack] (%s) array length is 0 in unserialized data",
                    __FUNCTION__);
                zval_ptr_dtor(value);
                return FAILURE;
            }

            zend_hash_internal_pointer_reset_ex(htval, &valpos);
            for (;; zend_hash_move_forward_ex(htval, &valpos))
            {
                key_type = zend_hash_get_current_key_ex(
                    htval, &key, &key_len, &key_index, 0, &valpos);

                if (key_type == HASH_KEY_NON_EXISTANT)
                {
                    break;
                }

                if (zend_hash_get_current_data_ex(
                        htval, (void *)&arydata, &valpos) != SUCCESS)
                {
                    MSGPACK_WARNING(
                        "[msgpack] (%s) can't get next data in indexed array",
                        __FUNCTION__);
                    continue;
                }

                switch (key_type)
                {
                    case HASH_KEY_IS_LONG:
                    {
                        zval *aryval, *rv;
                        ALLOC_INIT_ZVAL(rv);
                        MSGPACK_CONVERT_COPY_ZVAL(aryval, arydata);
                        if (convert_function)
                        {
                            if (convert_function(rv, *data, &aryval) != SUCCESS)
                            {
                                zval_ptr_dtor(&aryval);
                                MSGPACK_WARNING(
                                    "[msgpack] (%s) "
                                    "convert failure in HASH_KEY_IS_LONG "
                                    "in indexed array",
                                    __FUNCTION__);
                                zval_ptr_dtor(value);
                                return FAILURE;
                            }
                            add_next_index_zval(return_value, rv);
                        }
                        else
                        {
                            add_next_index_zval(return_value, aryval);
                        }
                        break;
                    }
                    case HASH_KEY_IS_STRING:
                        MSGPACK_WARNING(
                            "[msgpack] (%s) key is string",
                            __FUNCTION__);
                        zval_ptr_dtor(value);
                        return FAILURE;
                    default:
                        MSGPACK_WARNING(
                            "[msgpack] (%s) key is not string nor array",
                            __FUNCTION__);
                        zval_ptr_dtor(value);
                        return FAILURE;
                }
            }

            zval_ptr_dtor(value);
            return SUCCESS;
        }
    }
    else
    {
        // shouldn't reach
        MSGPACK_WARNING(
            "[msgpack] (%s) template is not array",
            __FUNCTION__);
        zval_ptr_dtor(value);
        return FAILURE;
    }

    // shouldn't reach
    zval_ptr_dtor(value);
    return FAILURE;
}
Beispiel #21
0
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);
}
Beispiel #22
0
ONPHP_METHOD(Singleton, getInstance)
{
	char *name;
	int length, argc = ZEND_NUM_ARGS();
	zend_class_entry **cep;
	zval *object, *args;
	zval **stored;
	zval ***params = NULL;
	
	if (argc < 1) {
		WRONG_PARAM_COUNT;
	}
	
	params = safe_emalloc(sizeof(zval **), argc, 0);
	
	if (zend_get_parameters_array_ex(argc, params) == FAILURE) {
		efree(params);
		ONPHP_THROW(
			BaseException,
			"Failed to get calling arguments for object creation"
		);
	}
	
	// replica of historical Singleton's behaviour
	if (argc > 2) {
		int i;
		ALLOC_INIT_ZVAL(args);
		array_init(args);
		
		for (i = 1; i < argc; ++i) {
			add_next_index_zval(args, *params[i]);
		}
		
		params[1] = &args;
		argc = 2;
	}
	
	if (Z_TYPE_PP(params[0]) != IS_STRING) {
		ONPHP_THROW(WrongArgumentException, "strange class name given");
	}
	
	name = estrdup(Z_STRVAL_PP(params[0]));
	
	length = strlen(name);
	
	if (
		zend_hash_find(
			Z_ARRVAL_P(instances),
			name,
			length + 1,
			(void **) &stored
		)
		== SUCCESS
	) {
		efree(params);
		efree(name);
		
		object = *stored;
		
		zval_copy_ctor(object);
	} else {
		// stolen from Reflection's newInstance()
		if (zend_lookup_class(name, length, &cep TSRMLS_CC) == SUCCESS) {
			zval *retval_ptr;
			zend_fcall_info fci;
			zend_fcall_info_cache fcc;
			zend_class_entry *ce = *cep;
			
			// can use ce->name instead now
			efree(name);
			
			if (!instanceof_function(ce, onphp_ce_Singleton TSRMLS_CC)) {
				efree(params);
				ONPHP_THROW(
					WrongArgumentException,
					"Class '%s' is something not a Singleton's child",
					ce->name
				);
			}
			
			// we can call protected consturctors,
			// since all classes are childs of Singleton
			if (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE) {
				efree(params);
				ONPHP_THROW(
					BaseException,
					"Can not call private constructor for '%s' creation",
					ce->name
				);
			} else if (ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC) {
				efree(params);
				ONPHP_THROW(
					BaseException,
					"Don't want to deal with '%s' class "
						"due to public constructor there",
					ce->name
				);
			}
			
			ALLOC_INIT_ZVAL(object);
			object_init_ex(object, ce);
			
			fci.size = sizeof(fci);
			fci.function_table = EG(function_table);
			fci.function_name = NULL;
			fci.symbol_table = NULL;
			fci.object_pp = &object;
			fci.retval_ptr_ptr = &retval_ptr;
			fci.param_count = argc - 1;
			fci.params = params + 1;
			
			fcc.initialized = 1;
			fcc.function_handler = ce->constructor;
			fcc.calling_scope = EG(scope);
			fcc.object_pp = &object;
			
			if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
				zend_throw_exception_ex(
					onphp_ce_BaseException,
					0 TSRMLS_CC,
					"Failed to call '%s' constructor",
					ce->name
				);
			}
			
			efree(params);
			
			if (retval_ptr) {
				zval_ptr_dtor(&retval_ptr);
			}
			
			if (EG(exception)) {
				return;
			}
			
			add_assoc_zval_ex(instances, ce->name, length + 1, object);
		}
	}
	
	RETURN_ZVAL(object, 1, 0);
}
Beispiel #23
0
/* Iterate over the given protobuf message pointer and transform values into native
   php types. writes an associative array into the given zval**. */
void message_php (zval* return_value, const ProtobufCMessage *message)
{
    unsigned int i, j;
    for (i=0;i<message->descriptor->n_fields;i++) {
        const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
        const void* member = get_member(message, field);
        size_t* num_fields = get_quantifier(message, field);
        const ProtobufCMessage** sub_messages;
        const ProtobufCMessage* sub_message;
        zval *inner, *inner_repeated;

        switch (field->type) {

            case PROTOBUF_C_TYPE_INT32:
                if (field->label == PROTOBUF_C_LABEL_OPTIONAL && (protobuf_c_boolean)*num_fields) {
                    int32_php_single(return_value, (char*)field->name, (const int32_t*)member);
                } else if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
                    int32_php_single(return_value, (char*)field->name, (const int32_t*)member);
                } else if (field->label == PROTOBUF_C_LABEL_REPEATED && *num_fields) {
                    int32_php_repeated(return_value, (char*)field->name, (const int32_t**)member, *num_fields);
                }
            break;

            case PROTOBUF_C_TYPE_UINT32:
                if (field->label == PROTOBUF_C_LABEL_OPTIONAL && (protobuf_c_boolean)*num_fields) {
                    uint32_php_single(return_value, (char*)field->name, (const uint32_t*)member);
                } else if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
                    uint32_php_single(return_value, (char*)field->name, (const uint32_t*)member);
                } else if (field->label == PROTOBUF_C_LABEL_REPEATED && *num_fields) {
                    uint32_php_repeated(return_value, (char*)field->name, (const uint32_t**)member, *num_fields);
                }
            break;

            case PROTOBUF_C_TYPE_STRING:
                if (field->label == PROTOBUF_C_LABEL_OPTIONAL) {
                    char** pos = (char**)member;
                    if (*pos != NULL) {
                        string_php_single(return_value, (char*)field->name, (char* const*)member);
                    }
                } else if (field->label == PROTOBUF_C_LABEL_REQUIRED) {
                    string_php_single(return_value, (char*)field->name, (char* const*)member);
                } else if (field->label == PROTOBUF_C_LABEL_REPEATED && *num_fields) {
                    string_php_repeated(return_value, (char*)field->name, (char** const*)member, *num_fields);
                }
            break;

            case PROTOBUF_C_TYPE_BOOL:
                bool_php(return_value, field->name, *(const protobuf_c_boolean *)member);
            break;

            case PROTOBUF_C_TYPE_MESSAGE:

                // optional or repeated field with no entries shouldn't make it to PHP
                if (field->label == PROTOBUF_C_LABEL_OPTIONAL || field->label == PROTOBUF_C_LABEL_REPEATED) {
                    if (*((const ProtobufCMessage**)member) == NULL) {
                        break;
                    }
                }

                MAKE_STD_ZVAL(inner);
                array_init(inner);

                if (field->label == PROTOBUF_C_LABEL_OPTIONAL || field->label == PROTOBUF_C_LABEL_REQUIRED) {
                    message_php(inner, *((const ProtobufCMessage**)member));
                } else if (field->label == PROTOBUF_C_LABEL_REPEATED) {
                    sub_messages = (const ProtobufCMessage**)*((const ProtobufCMessage**)member);
                    for (j=0;j<*num_fields;++j) {
                        MAKE_STD_ZVAL(inner_repeated);
                        array_init(inner_repeated);
                        message_php(inner_repeated, sub_messages[j]);
                        add_next_index_zval(inner, inner_repeated);
                    }
                }

                add_assoc_zval(return_value, (char*)field->name, inner);

            break;
                
            case PROTOBUF_C_TYPE_DOUBLE:
//                double_php(return_value, field->name, *(const uint64_t *)member);
            case PROTOBUF_C_TYPE_FLOAT:
//                float_php(return_value, field->name, *(const uint32_t *)member);
            case PROTOBUF_C_TYPE_SINT32:
//                sint32_php(return_value, field->name, *(const int32_t *)member);
            case PROTOBUF_C_TYPE_FIXED32:
//                fixed32_php(return_value, field->name, *(const uint32_t *)member);
            case PROTOBUF_C_TYPE_SFIXED32:
//                sfixed32_php(return_value, field->name, *(const uint32_t *)member);
            case PROTOBUF_C_TYPE_INT64:
//                int64_php(return_value, field->name, *(const uint64_t *)member);
            case PROTOBUF_C_TYPE_SINT64:
//                sint64_php(return_value, field->name, *(const int64_t *)member);
            case PROTOBUF_C_TYPE_UINT64:
//                uint64_php(return_value, field->name, *(const uint64_t *)member);
            case PROTOBUF_C_TYPE_FIXED64:
//                fixed64_php(return_value, field->name, *(const uint64_t *)member);
            case PROTOBUF_C_TYPE_SFIXED64:
//                sfixed64_php(return_value, field->name, *(const uint64_t *)member);
            // XXX unimplemented XXX
            case PROTOBUF_C_TYPE_ENUM:
            case PROTOBUF_C_TYPE_BYTES:
            default:
                break;
        }
    }
}
Beispiel #24
0
/**
 * 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, &timestamp, &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);
}
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;
}
Beispiel #26
0
static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
{
	zval **args = NULL;
	zval *retval;
	int result, i, ret;
	int error = 0;
	zend_fcall_info fci;
	zval handler;
	xmlXPathObjectPtr obj;
	char *str;
	char *callable = NULL;
	dom_xpath_object *intern;
	
	TSRMLS_FETCH();

	if (! zend_is_executing(TSRMLS_C)) {
		xmlGenericError(xmlGenericErrorContext,
		"xmlExtFunctionTest: Function called from outside of PHP\n");
		error = 1;
	} else {
		intern = (dom_xpath_object *) ctxt->context->userData;
		if (intern == NULL) {
			xmlGenericError(xmlGenericErrorContext,
			"xmlExtFunctionTest: failed to get the internal object\n");
			error = 1;
		}
		else if (intern->registerPhpFunctions == 0) {
			xmlGenericError(xmlGenericErrorContext,
			"xmlExtFunctionTest: PHP Object did not register PHP functions\n");
			error = 1;
		}
	}
	
	if (error == 1) {
		for (i = nargs - 1; i >= 0; i--) {
			obj = valuePop(ctxt);
			xmlXPathFreeObject(obj);
		}
		return;
	}
		
	fci.param_count = nargs - 1;
	if (fci.param_count > 0) {
		fci.params = safe_emalloc(fci.param_count, sizeof(zval**), 0);
		args = safe_emalloc(fci.param_count, sizeof(zval *), 0);
	}
	/* Reverse order to pop values off ctxt stack */
	for (i = nargs - 2; i >= 0; i--) {
		obj = valuePop(ctxt);
		MAKE_STD_ZVAL(args[i]);
		switch (obj->type) {
			case XPATH_STRING:
				ZVAL_STRING(args[i],  (char *)obj->stringval, 1);
				break;
			case XPATH_BOOLEAN:
				ZVAL_BOOL(args[i],  obj->boolval);
				break;
			case XPATH_NUMBER:
				ZVAL_DOUBLE(args[i], obj->floatval);
				break;
			case XPATH_NODESET:
				if (type == 1) {
					str = (char *)xmlXPathCastToString(obj);
					ZVAL_STRING(args[i], str, 1);
					xmlFree(str);
				} else if (type == 2) {
					int j;
					array_init(args[i]);
					if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
						for (j = 0; j < obj->nodesetval->nodeNr; j++) {
							xmlNodePtr node = obj->nodesetval->nodeTab[j];
							zval *child;
							MAKE_STD_ZVAL(child);
							/* not sure, if we need this... it's copied from xpath.c */
							if (node->type == XML_NAMESPACE_DECL) {
								xmlNsPtr curns;
								xmlNodePtr nsparent;
								
								nsparent = node->_private;
								curns = xmlNewNs(NULL, node->name, NULL);
								if (node->children) {
									curns->prefix = xmlStrdup((xmlChar *) node->children);
								}
								if (node->children) {
									node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name);
								} else {
									node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name);
								}
								node->type = XML_NAMESPACE_DECL;
								node->parent = nsparent;
								node->ns = curns;
							}
							child = php_dom_create_object(node, &ret, child, (dom_object *)intern TSRMLS_CC);
							add_next_index_zval(args[i], child);
						}
					}
				}
				break;
			default:
			ZVAL_STRING(args[i], (char *)xmlXPathCastToString(obj), 1);
		}
		xmlXPathFreeObject(obj);
		fci.params[i] = &args[i];
	}
	
	fci.size = sizeof(fci);
	fci.function_table = EG(function_table);
	
	obj = valuePop(ctxt);
	if (obj->stringval == NULL) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Handler name must be a string");
		xmlXPathFreeObject(obj);
		if (fci.param_count > 0) {
			for (i = 0; i < nargs - 1; i++) {
				zval_ptr_dtor(&args[i]);
			}
			efree(args);
			efree(fci.params);
		}
		return; 
	}
	INIT_PZVAL(&handler);
	ZVAL_STRING(&handler, obj->stringval, 1);
	xmlXPathFreeObject(obj);

	fci.function_name = &handler;
	fci.symbol_table = NULL;
	fci.object_ptr = NULL;
	fci.retval_ptr_ptr = &retval;
	fci.no_separation = 0;

	if (!zend_make_callable(&handler, &callable TSRMLS_CC)) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", callable);
		
	} else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable, strlen(callable) + 1) == 0) { 
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not allowed to call handler '%s()'.", callable);
		/* Push an empty string, so that we at least have an xslt result... */
		valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
	} else {
		result = zend_call_function(&fci, NULL TSRMLS_CC);
		if (result == FAILURE) {
			if (Z_TYPE(handler) == IS_STRING) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(&handler));
			}
		/* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */
		} else if (retval == NULL) {
		} else {
			if (retval->type == IS_OBJECT && instanceof_function( Z_OBJCE_P(retval), dom_node_class_entry TSRMLS_CC)) {
				xmlNode *nodep;
				dom_object *obj;
				if (intern->node_list == NULL) {
					ALLOC_HASHTABLE(intern->node_list);
					zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
				}
				zval_add_ref(&retval);
				zend_hash_next_index_insert(intern->node_list, &retval, sizeof(zval *), NULL);
				obj = (dom_object *)zend_object_store_get_object(retval TSRMLS_CC);
				nodep = dom_object_get_node(obj);
				valuePush(ctxt, xmlXPathNewNodeSet(nodep));
			} else if (retval->type == IS_BOOL) {
				valuePush(ctxt, xmlXPathNewBoolean(retval->value.lval));
			} else if (retval->type == IS_OBJECT) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
				valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
			} else {
				convert_to_string_ex(&retval);
				valuePush(ctxt, xmlXPathNewString( Z_STRVAL_P(retval)));
			}
			zval_ptr_dtor(&retval);
		}
	}
	efree(callable);
	zval_dtor(&handler);
	if (fci.param_count > 0) {
		for (i = 0; i < nargs - 1; i++) {
			zval_ptr_dtor(&args[i]);
		}
		efree(args);
		efree(fci.params);
	}
}
Beispiel #27
0
static void tidy_add_default_properties(PHPTidyObj *obj, tidy_obj_type type)
{

	TidyBuffer buf;
	TidyAttr	tempattr;
	TidyNode	tempnode;
	zval attribute, children, temp;
	PHPTidyObj *newobj;

	switch(type) {

		case is_node:
			if (!obj->std.properties) {
				rebuild_object_properties(&obj->std);
			}
			tidyBufInit(&buf);
			tidyNodeGetText(obj->ptdoc->doc, obj->node, &buf);
			ADD_PROPERTY_STRINGL(obj->std.properties, value, buf.bp, buf.size ? buf.size-1 : 0);
			tidyBufFree(&buf);

			ADD_PROPERTY_STRING(obj->std.properties, name, tidyNodeGetName(obj->node));
			ADD_PROPERTY_LONG(obj->std.properties, type, tidyNodeGetType(obj->node));
			ADD_PROPERTY_LONG(obj->std.properties, line, tidyNodeLine(obj->node));
			ADD_PROPERTY_LONG(obj->std.properties, column, tidyNodeColumn(obj->node));
			ADD_PROPERTY_BOOL(obj->std.properties, proprietary, tidyNodeIsProp(obj->ptdoc->doc, obj->node));

			switch(tidyNodeGetType(obj->node)) {
				case TidyNode_Root:
				case TidyNode_DocType:
				case TidyNode_Text:
				case TidyNode_Comment:
					break;

				default:
					ADD_PROPERTY_LONG(obj->std.properties, id, tidyNodeGetId(obj->node));
			}

			tempattr = tidyAttrFirst(obj->node);

			if (tempattr) {
				char *name, *val;
				array_init(&attribute);

				do {
					name = (char *)tidyAttrName(tempattr);
					val = (char *)tidyAttrValue(tempattr);
					if (name && val) {
						add_assoc_string(&attribute, name, val);
					}
				} while((tempattr = tidyAttrNext(tempattr)));
			} else {
				ZVAL_NULL(&attribute);
			}
			zend_hash_str_update(obj->std.properties, "attribute", sizeof("attribute") - 1, &attribute);

			tempnode = tidyGetChild(obj->node);

			if (tempnode) {
				array_init(&children);
				do {
					tidy_instanciate(tidy_ce_node, &temp);
					newobj = Z_TIDY_P(&temp);
					newobj->node = tempnode;
					newobj->type = is_node;
					newobj->ptdoc = obj->ptdoc;
					newobj->ptdoc->ref_count++;

					tidy_add_default_properties(newobj, is_node);
					add_next_index_zval(&children, &temp);

				} while((tempnode = tidyGetNext(tempnode)));

			} else {
				ZVAL_NULL(&children);
			}

			zend_hash_str_update(obj->std.properties, "child", sizeof("child") - 1, &children);

			break;

		case is_doc:
			if (!obj->std.properties) {
				rebuild_object_properties(&obj->std);
			}
			ADD_PROPERTY_NULL(obj->std.properties, errorBuffer);
			ADD_PROPERTY_NULL(obj->std.properties, value);
			break;
	}
}
static int php_mimepart_process_header(php_mimepart *part)
{
	php_rfc822_tokenized_t *toks;
	char *header_key, *header_val, *header_val_stripped;
	zval *zheaderval;
	zend_string *header_zstring;

	if (part->parsedata.headerbuf.len == 0)
		return SUCCESS;

	smart_string_0(&part->parsedata.headerbuf);

	/* parse the header line */
	toks = php_mailparse_rfc822_tokenize((const char*)part->parsedata.headerbuf.c, 0);

	/* valid headers consist of at least three tokens, with the first being a string and the
	 * second token being a ':' */
	if (toks->ntokens < 2 || toks->tokens[0].token != 0 || toks->tokens[1].token != ':') {
		part->parsedata.headerbuf.len = 0;

		php_rfc822_tokenize_free(toks);
		return FAILURE;
	}

	/* get a lower-case version of the first token */
	header_key = php_rfc822_recombine_tokens(toks, 0, 1, PHP_RFC822_RECOMBINE_IGNORE_COMMENTS|PHP_RFC822_RECOMBINE_STRTOLOWER);

	header_val = strchr(part->parsedata.headerbuf.c, ':');
	header_val_stripped = php_rfc822_recombine_tokens(toks, 2, toks->ntokens-2, PHP_RFC822_RECOMBINE_IGNORE_COMMENTS|PHP_RFC822_RECOMBINE_STRTOLOWER);

	if (header_val) {
		header_val++;
		while (isspace(*header_val))
			header_val++;

		/* add the header to the hash.
		 * join multiple To: or Cc: lines together */
		header_zstring = zend_string_init(header_key, strlen(header_key), 0);
		if ((strcmp(header_key, "to") == 0 || strcmp(header_key, "cc") == 0) && (zheaderval = zend_hash_find(Z_ARRVAL_P(&part->headerhash), header_zstring)) != NULL) {
			int newlen;
			char *newstr;

			newlen = strlen(header_val) + Z_STRLEN_P(zheaderval) + 3;
			newstr = emalloc(newlen);

			strcpy(newstr, Z_STRVAL_P(zheaderval));
			strcat(newstr, ", ");
			strcat(newstr, header_val);
			add_assoc_string(&part->headerhash, header_key, newstr);
			efree(newstr);
		} else {
			if((zheaderval = zend_hash_find(Z_ARRVAL_P(&part->headerhash), header_zstring)) != NULL) {
			      if(Z_TYPE_P(zheaderval) == IS_ARRAY) {
          add_next_index_string(zheaderval, header_val);
        } else {
          /* Create a nested array if there is more than one of the same header */
          zval zarr;
          array_init(&zarr);
          Z_ADDREF_P(zheaderval);

          add_next_index_zval(&zarr, zheaderval);
          add_next_index_string(&zarr, header_val);
          add_assoc_zval(&part->headerhash, header_key, &zarr);
        }
      } else {
        add_assoc_string(&part->headerhash, header_key, header_val);
      }
		}
		zend_string_release(header_zstring);
		/* if it is useful, keep a pointer to it in the mime part */
		if (strcmp(header_key, "mime-version") == 0)
			STR_SET_REPLACE(part->mime_version, header_val_stripped);

		if (strcmp(header_key, "content-location") == 0) {
			STR_FREE(part->content_location);
			part->content_location = php_rfc822_recombine_tokens(toks, 2, toks->ntokens-2, PHP_RFC822_RECOMBINE_IGNORE_COMMENTS);
		}
		if (strcmp(header_key, "content-base") == 0) {
			STR_FREE(part->content_base);
			part->content_base = php_rfc822_recombine_tokens(toks, 2, toks->ntokens-2, PHP_RFC822_RECOMBINE_IGNORE_COMMENTS);
		}

		if (strcmp(header_key, "content-transfer-encoding") == 0)
			STR_SET_REPLACE(part->content_transfer_encoding, header_val_stripped);
		if (strcmp(header_key, "content-type") == 0) {
			char *charset, *boundary;

			if (part->content_type) {
				php_mimeheader_free(part->content_type);
				part->content_type = NULL;
			}

			part->content_type = php_mimeheader_alloc_from_tok(toks);

			boundary = php_mimepart_attribute_get(part->content_type, "boundary");
			if (boundary) {
				part->boundary = estrdup(boundary);
			}

			charset = php_mimepart_attribute_get(part->content_type, "charset");
			if (charset) {
				STR_SET_REPLACE(part->charset, charset);
			}
		}
		if (strcmp(header_key, "content-disposition") == 0) {
			part->content_disposition = php_mimeheader_alloc_from_tok(toks);
		}

	}
	STR_FREE(header_key);
	STR_FREE(header_val_stripped);

	php_rfc822_tokenize_free(toks);

	/* zero the buffer size */
	part->parsedata.headerbuf.len = 0;
	return SUCCESS;
}
Beispiel #29
0
PHPAPI int php_sscanf_internal( char *string, char *format,
				int argCount, zval *args,
				int varStart, zval *return_value)
{
	int  numVars, nconversions, totalVars = -1;
	int  i, result;
	zend_long value;
	int  objIndex;
	char *end, *baseString;
	zval *current;
	char op   = 0;
	int  base = 0;
	int  underflow = 0;
	size_t width;
	zend_long (*fn)() = NULL;
	char *ch, sch;
	int  flags;
	char buf[64];	/* Temporary buffer to hold scanned number
					 * strings before they are passed to strtoul() */

	/* do some sanity checking */
	if ((varStart > argCount) || (varStart < 0)){
		varStart = SCAN_MAX_ARGS + 1;
	}
	numVars = argCount - varStart;
	if (numVars < 0) {
		numVars = 0;
	}

#if 0
	zend_printf("<br>in sscanf_internal : <br> string is \"%s\", format = \"%s\"<br> NumVars = %d. VarStart = %d<br>-------------------------<br>",
					string, format, numVars, varStart);
#endif
	/*
	 * Check for errors in the format string.
	 */
	if (ValidateFormat(format, numVars, &totalVars) != SCAN_SUCCESS) {
		scan_set_error_return( numVars, return_value );
		return SCAN_ERROR_INVALID_FORMAT;
	}

	objIndex = numVars ? varStart : 0;

	/*
	 * If any variables are passed, make sure they are all passed by reference
	 */
	if (numVars) {
		for (i = varStart;i < argCount;i++){
			if ( ! Z_ISREF(args[ i ] ) ) {
				php_error_docref(NULL, E_WARNING, "Parameter %d must be passed by reference", i);
				scan_set_error_return(numVars, return_value);
				return SCAN_ERROR_VAR_PASSED_BYVAL;
			}
		}
	}

	/*
	 * Allocate space for the result objects. Only happens when no variables
	 * are specified
	 */
	if (!numVars) {
		zval tmp;

		/* allocate an array for return */
		array_init(return_value);

		for (i = 0; i < totalVars; i++) {
			ZVAL_NULL(&tmp);
			if (add_next_index_zval(return_value, &tmp) == FAILURE) {
				scan_set_error_return(0, return_value);
				return FAILURE;
			}
		}
		varStart = 0; /* Array index starts from 0 */
	}

	baseString = string;

	/*
	 * Iterate over the format string filling in the result objects until
	 * we reach the end of input, the end of the format string, or there
	 * is a mismatch.
	 */
	nconversions = 0;
	/* note ! - we need to limit the loop for objIndex to keep it in bounds */

	while (*format != '\0') {
		ch    = format++;
		flags = 0;

		/*
		 * If we see whitespace in the format, skip whitespace in the string.
		 */
		if ( isspace( (int)*ch ) ) {
			sch = *string;
			while ( isspace( (int)sch ) ) {
				if (*string == '\0') {
					goto done;
				}
				string++;
				sch = *string;
			}
			continue;
		}

		if (*ch != '%') {
literal:
			if (*string == '\0') {
				underflow = 1;
				goto done;
			}
			sch = *string;
			string++;
			if (*ch != sch) {
				goto done;
			}
			continue;
		}

		ch = format++;
		if (*ch == '%') {
			goto literal;
		}

		/*
		 * Check for assignment suppression ('*') or an XPG3-style
		 * assignment ('%n$').
		 */
		if (*ch == '*') {
			flags |= SCAN_SUPPRESS;
			ch = format++;
		} else if ( isdigit(UCHAR(*ch))) {
			value = ZEND_STRTOUL(format-1, &end, 10);
			if (*end == '$') {
				format = end+1;
				ch = format++;
				objIndex = varStart + value - 1;
			}
		}

		/*
		 * Parse any width specifier.
		 */
		if ( isdigit(UCHAR(*ch))) {
			width = ZEND_STRTOUL(format-1, &format, 10);
			ch = format++;
		} else {
			width = 0;
		}

		/*
		 * Ignore size specifier.
		 */
		if ((*ch == 'l') || (*ch == 'L') || (*ch == 'h')) {
			ch = format++;
		}

		/*
		 * Handle the various field types.
		 */
		switch (*ch) {
			case 'n':
				if (!(flags & SCAN_SUPPRESS)) {
					if (numVars && objIndex >= argCount) {
						break;
					} else if (numVars) {
						current = Z_REFVAL(args[objIndex++]);
						zval_ptr_dtor(current);
						ZVAL_LONG(current, (zend_long)(string - baseString) );
					} else {
						add_index_long(return_value, objIndex++, string - baseString);
					}
				}
				nconversions++;
				continue;

			case 'd':
			case 'D':
				op = 'i';
				base = 10;
				fn = (zend_long (*)())ZEND_STRTOL_PTR;
				break;
			case 'i':
				op = 'i';
				base = 0;
				fn = (zend_long (*)())ZEND_STRTOL_PTR;
				break;
			case 'o':
				op = 'i';
				base = 8;
				fn = (zend_long (*)())ZEND_STRTOL_PTR;
				break;
			case 'x':
			case 'X':
				op = 'i';
				base = 16;
				fn = (zend_long (*)())ZEND_STRTOL_PTR;
				break;
			case 'u':
				op = 'i';
				base = 10;
				flags |= SCAN_UNSIGNED;
				fn = (zend_long (*)())ZEND_STRTOUL_PTR;
				break;

			case 'f':
			case 'e':
			case 'E':
			case 'g':
				op = 'f';
				break;

			case 's':
				op = 's';
				break;

			case 'c':
				op = 's';
				flags |= SCAN_NOSKIP;
				/*-cc-*/
				if (0 == width) {
					width = 1;
				}
				/*-cc-*/
				break;
			case '[':
				op = '[';
				flags |= SCAN_NOSKIP;
				break;
		}   /* switch */

		/*
		 * At this point, we will need additional characters from the
		 * string to proceed.
		 */
		if (*string == '\0') {
			underflow = 1;
			goto done;
		}

		/*
		 * Skip any leading whitespace at the beginning of a field unless
		 * the format suppresses this behavior.
		 */
		if (!(flags & SCAN_NOSKIP)) {
			while (*string != '\0') {
				sch = *string;
				if (! isspace((int)sch) ) {
					break;
				}
				string++;
			}
			if (*string == '\0') {
				underflow = 1;
				goto done;
			}
		}

		/*
		 * Perform the requested scanning operation.
		 */
		switch (op) {
			case 'c':
			case 's':
				/*
				 * Scan a string up to width characters or whitespace.
				 */
				if (width == 0) {
					width = (size_t) ~0;
				}
				end = string;
				while (*end != '\0') {
					sch = *end;
					if ( isspace( (int)sch ) ) {
						break;
					}
					end++;
					if (--width == 0) {
					   break;
					}
				}
				if (!(flags & SCAN_SUPPRESS)) {
					if (numVars && objIndex >= argCount) {
						break;
					} else if (numVars) {
						current = Z_REFVAL(args[objIndex++]);
						zval_ptr_dtor(current);
						ZVAL_STRINGL(current, string, end-string);
					} else {
						add_index_stringl(return_value, objIndex++, string, end-string);
					}
				}
				string = end;
				break;

			case '[': {
				CharSet cset;

				if (width == 0) {
					width = (size_t) ~0;
				}
				end = string;

				format = BuildCharSet(&cset, format);
				while (*end != '\0') {
					sch = *end;
					if (!CharInSet(&cset, (int)sch)) {
						break;
					}
					end++;
					if (--width == 0) {
						break;
					}
				}
				ReleaseCharSet(&cset);

				if (string == end) {
					/*
					 * Nothing matched the range, stop processing
					 */
					goto done;
				}
				if (!(flags & SCAN_SUPPRESS)) {
					if (numVars && objIndex >= argCount) {
						break;
					} else if (numVars) {
						current = Z_REFVAL(args[objIndex++]);
						zval_ptr_dtor(current);
						ZVAL_STRINGL(current, string, end-string);
					} else {
						add_index_stringl(return_value, objIndex++, string, end-string);
					}
				}
				string = end;
				break;
			}
/*
			case 'c':
			   / Scan a single character./

				sch = *string;
				string++;
				if (!(flags & SCAN_SUPPRESS)) {
					if (numVars) {
						char __buf[2];
						__buf[0] = sch;
						__buf[1] = '\0';;
						current = args[objIndex++];
						zval_dtor(*current);
						ZVAL_STRINGL( *current, __buf, 1);
					} else {
						add_index_stringl(return_value, objIndex++, &sch, 1);
					}
				}
				break;
*/
			case 'i':
				/*
				 * Scan an unsigned or signed integer.
				 */
				/*-cc-*/
				buf[0] = '\0';
				/*-cc-*/
				if ((width == 0) || (width > sizeof(buf) - 1)) {
					width = sizeof(buf) - 1;
				}

				flags |= SCAN_SIGNOK | SCAN_NODIGITS | SCAN_NOZERO;
				for (end = buf; width > 0; width--) {
					switch (*string) {
						/*
						 * The 0 digit has special meaning at the beginning of
						 * a number.  If we are unsure of the base, it
						 * indicates that we are in base 8 or base 16 (if it is
						 * followed by an 'x').
						 */
						case '0':
							/*-cc-*/
							if (base == 16) {
								flags |= SCAN_XOK;
							}
							/*-cc-*/
							if (base == 0) {
								base = 8;
								flags |= SCAN_XOK;
							}
							if (flags & SCAN_NOZERO) {
								flags &= ~(SCAN_SIGNOK | SCAN_NODIGITS | SCAN_NOZERO);
							} else {
								flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
							}
							goto addToInt;

						case '1': case '2': case '3': case '4':
						case '5': case '6': case '7':
							if (base == 0) {
								base = 10;
							}
							flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
							goto addToInt;

						case '8': case '9':
							if (base == 0) {
								base = 10;
							}
							if (base <= 8) {
							   break;
							}
							flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
							goto addToInt;

						case 'A': case 'B': case 'C':
						case 'D': case 'E': case 'F':
						case 'a': case 'b': case 'c':
						case 'd': case 'e': case 'f':
							if (base <= 10) {
								break;
							}
							flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
							goto addToInt;

						case '+': case '-':
							if (flags & SCAN_SIGNOK) {
								flags &= ~SCAN_SIGNOK;
								goto addToInt;
							}
							break;

						case 'x': case 'X':
							if ((flags & SCAN_XOK) && (end == buf+1)) {
								base = 16;
								flags &= ~SCAN_XOK;
								goto addToInt;
							}
							break;
					}

					/*
					 * We got an illegal character so we are done accumulating.
					 */
					break;

addToInt:
					/*
					 * Add the character to the temporary buffer.
					 */
					*end++ = *string++;
					if (*string == '\0') {
						break;
					}
				}

				/*
				 * Check to see if we need to back up because we only got a
				 * sign or a trailing x after a 0.
				 */
				if (flags & SCAN_NODIGITS) {
					if (*string == '\0') {
						underflow = 1;
					}
					goto done;
				} else if (end[-1] == 'x' || end[-1] == 'X') {
					end--;
					string--;
				}

				/*
				 * Scan the value from the temporary buffer.  If we are
				 * returning a large unsigned value, we have to convert it back
				 * to a string since PHP only supports signed values.
				 */
				if (!(flags & SCAN_SUPPRESS)) {
					*end = '\0';
					value = (zend_long) (*fn)(buf, NULL, base);
					if ((flags & SCAN_UNSIGNED) && (value < 0)) {
						snprintf(buf, sizeof(buf), ZEND_ULONG_FMT, value); /* INTL: ISO digit */
						if (numVars && objIndex >= argCount) {
							break;
						} else if (numVars) {
						  /* change passed value type to string */
							current = Z_REFVAL(args[objIndex++]);
							zval_ptr_dtor(current);
							ZVAL_STRING(current, buf);
						} else {
							add_index_string(return_value, objIndex++, buf);
						}
					} else {
						if (numVars && objIndex >= argCount) {
							break;
						} else if (numVars) {
							current = Z_REFVAL(args[objIndex++]);
							zval_ptr_dtor(current);
							ZVAL_LONG(current, value);
						} else {
							add_index_long(return_value, objIndex++, value);
						}
					}
				}
				break;

			case 'f':
				/*
				 * Scan a floating point number
				 */
				buf[0] = '\0';     /* call me pedantic */
				if ((width == 0) || (width > sizeof(buf) - 1)) {
					width = sizeof(buf) - 1;
				}
				flags |= SCAN_SIGNOK | SCAN_NODIGITS | SCAN_PTOK | SCAN_EXPOK;
				for (end = buf; width > 0; width--) {
					switch (*string) {
						case '0': case '1': case '2': case '3':
						case '4': case '5': case '6': case '7':
						case '8': case '9':
							flags &= ~(SCAN_SIGNOK | SCAN_NODIGITS);
							goto addToFloat;
						case '+':
						case '-':
							if (flags & SCAN_SIGNOK) {
								flags &= ~SCAN_SIGNOK;
								goto addToFloat;
							}
							break;
						case '.':
							if (flags & SCAN_PTOK) {
								flags &= ~(SCAN_SIGNOK | SCAN_PTOK);
								goto addToFloat;
							}
							break;
						case 'e':
						case 'E':
							/*
							 * An exponent is not allowed until there has
							 * been at least one digit.
							 */
							if ((flags & (SCAN_NODIGITS | SCAN_EXPOK)) == SCAN_EXPOK) {
								flags = (flags & ~(SCAN_EXPOK|SCAN_PTOK))
									| SCAN_SIGNOK | SCAN_NODIGITS;
								goto addToFloat;
							}
							break;
					}

					/*
					 * We got an illegal character so we are done accumulating.
					 */
					break;

addToFloat:
					/*
					 * Add the character to the temporary buffer.
					 */
					*end++ = *string++;
					if (*string == '\0') {
						break;
					}
				}

				/*
				 * Check to see if we need to back up because we saw a
				 * trailing 'e' or sign.
				 */
				if (flags & SCAN_NODIGITS) {
					if (flags & SCAN_EXPOK) {
						/*
						 * There were no digits at all so scanning has
						 * failed and we are done.
						 */
						if (*string == '\0') {
							underflow = 1;
						}
						goto done;
					}

					/*
					 * We got a bad exponent ('e' and maybe a sign).
					 */
					end--;
					string--;
					if (*end != 'e' && *end != 'E') {
						end--;
						string--;
					}
				}

				/*
				 * Scan the value from the temporary buffer.
				 */
				if (!(flags & SCAN_SUPPRESS)) {
					double dvalue;
					*end = '\0';
					dvalue = zend_strtod(buf, NULL);
					if (numVars && objIndex >= argCount) {
						break;
					} else if (numVars) {
						current = Z_REFVAL(args[objIndex++]);
						zval_ptr_dtor(current);
						ZVAL_DOUBLE(current, dvalue);
					} else {
						add_index_double(return_value, objIndex++, dvalue );
					}
				}
				break;
		} /* switch (op) */
		nconversions++;
	} /*  while (*format != '\0') */

done:
	result = SCAN_SUCCESS;

	if (underflow && (0==nconversions)) {
		scan_set_error_return( numVars, return_value );
		result = SCAN_ERROR_EOF;
	} else if (numVars) {
		convert_to_long(return_value );
		Z_LVAL_P(return_value) = nconversions;
	} else if (nconversions < totalVars) {
		/* TODO: not all elements converted. we need to prune the list - cc */
	}
	return result;
}
Beispiel #30
0
static void tokenize(zval *return_value)
{
	zval token;
	zval keyword;
	int token_type;
	zend_bool destroy;
	int token_line = 1;
	int need_tokens = -1; // for __halt_compiler lexing. -1 = disabled

	array_init(return_value);

	ZVAL_NULL(&token);
	while ((token_type = lex_scan(&token))) {
		destroy = 1;
		switch (token_type) {
			case T_CLOSE_TAG:
				if (zendtext[zendleng - 1] != '>') {
					CG(zend_lineno)++;
				}
			case T_OPEN_TAG:
			case T_OPEN_TAG_WITH_ECHO:
			case T_WHITESPACE:
			case T_COMMENT:
			case T_DOC_COMMENT:
				destroy = 0;
				break;
		}

		if (token_type >= 256) {
			array_init(&keyword);
			add_next_index_long(&keyword, token_type);
			if (token_type == T_END_HEREDOC) {
				if (CG(increment_lineno)) {
					token_line = ++CG(zend_lineno);
					CG(increment_lineno) = 0;
				}
			}
			add_next_index_stringl(&keyword, (char *)zendtext, zendleng);
			add_next_index_long(&keyword, token_line);
			add_next_index_zval(return_value, &keyword);
		} else {
			add_next_index_stringl(return_value, (char *)zendtext, zendleng);
		}
		if (destroy && Z_TYPE(token) != IS_NULL) {
			zval_dtor(&token);
		}
		ZVAL_NULL(&token);

		// after T_HALT_COMPILER collect the next three non-dropped tokens
		if (need_tokens != -1) {
			if (token_type != T_WHITESPACE && token_type != T_OPEN_TAG
			    && token_type != T_COMMENT && token_type != T_DOC_COMMENT
			    && --need_tokens == 0
			) {
				// fetch the rest into a T_INLINE_HTML
				if (zendcursor != zendlimit) {
					array_init(&keyword);
					add_next_index_long(&keyword, T_INLINE_HTML);
					add_next_index_stringl(&keyword, (char *)zendcursor, zendlimit - zendcursor);
					add_next_index_long(&keyword, token_line);
					add_next_index_zval(return_value, &keyword);
				}
				break;
			}
		} else if (token_type == T_HALT_COMPILER) {
			need_tokens = 3;
		}

		token_line = CG(zend_lineno);
	}
}