Skip to content

Instantly share code, notes, and snippets.

@laruence
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laruence/010877b6e2ce21c5b3b7 to your computer and use it in GitHub Desktop.
Save laruence/010877b6e2ce21c5b3b7 to your computer and use it in GitHub Desktop.
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index f1e9614..e699bea 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -989,6 +989,58 @@ ZEND_API int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, const c
}
/* }}} */
+ZEND_API zend_string *zend_parse_parameter_str(int offset TSRMLS_DC) /* {{{ */ {
+ int arg_count = Z_LVAL_P(zend_vm_stack_top(TSRMLS_C) - 1);
+ if (UNEXPECTED(arg_count == 0)) {
+ const char *__space;
+ const char * __class_name = get_active_class_name(&__space TSRMLS_CC);
+ zend_error(E_WARNING, "%s%s%s() expects exactly at least %d parameters, %d given",
+ __class_name, __space, get_active_function_name(TSRMLS_C), offset + 1, arg_count);
+ return NULL;
+ } else {
+ zend_string *str = NULL;
+ const char *expected_type = NULL;
+ zval *arg = (zend_vm_stack_top(TSRMLS_C) - 1 - (arg_count - offset));
+ switch (Z_TYPE_P(arg)) {
+ case IS_STRING:
+ if (UNEXPECTED(Z_ISREF_P(arg))) {
+ /* it's dangerous to return pointers to string
+ buffer of referenced variable, because it can
+ be clobbered throug magic callbacks */
+ SEPARATE_ZVAL(arg);
+ }
+ str = Z_STR_P(arg);
+ break;
+ case IS_NULL:
+ case IS_LONG:
+ case IS_DOUBLE:
+ case IS_FALSE:
+ case IS_TRUE:
+ convert_to_string_ex(arg);
+ str = Z_STR_P(arg);
+ break;
+ case IS_OBJECT:
+ if (parse_arg_object_to_str(arg, &str, IS_STRING TSRMLS_CC) == SUCCESS) {
+ break;
+ }
+ case IS_ARRAY:
+ case IS_RESOURCE:
+ default:
+ expected_type = "string";
+ break;
+ }
+ if (expected_type) {
+ const char *__space;
+ const char * __class_name = get_active_class_name(&__space TSRMLS_CC);
+ zend_error(E_WARNING, "%s%s%s() expects parameter %d to be %s, %s given",
+ __class_name, __space, get_active_function_name(TSRMLS_C), offset + 1, expected_type,
+ zend_zval_type_name(arg));
+ return NULL;
+ }
+ return str;
+ }
+} /* }}} */
+
ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, const char *type_spec, ...) /* {{{ */
{
va_list va;
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 882841c..8461bd2 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -259,6 +259,7 @@ ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args TSRMLS_DC,
ZEND_API int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval *arg, const char *spec, ...);
+ZEND_API zend_string *zend_parse_parameter_str(int offset TSRMLS_DC);
/* End of parameter parsing API -- andrei */
ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type TSRMLS_DC);
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index d8b8287..0fe6000 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -480,9 +480,8 @@ ZEND_FUNCTION(func_get_args)
Get string length */
ZEND_FUNCTION(strlen)
{
- zend_string *s;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &s) == FAILURE) {
+ zend_string *s = zend_parse_parameter_str(0 TSRMLS_CC);
+ if (s == NULL) {
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment