mirror of
https://github.com/php/php-src.git
synced 2024-12-02 06:13:40 +08:00
Unicode support
This commit is contained in:
parent
39072c42c4
commit
b80cb7bd2f
@ -17,7 +17,7 @@ libZend_la_SOURCES=\
|
||||
zend_objects_API.c zend_ts_hash.c zend_stream.c zend_mm.c \
|
||||
zend_default_classes.c zend_reflection_api.c \
|
||||
zend_iterators.c zend_interfaces.c zend_exceptions.c \
|
||||
zend_strtod.c zend_multibyte.c
|
||||
zend_strtod.c zend_multibyte.c zend_strtod.c zend_strtol.c
|
||||
|
||||
libZend_la_LDFLAGS =
|
||||
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
|
||||
|
15
Zend/Zend.m4
15
Zend/Zend.m4
@ -160,12 +160,15 @@ AC_ARG_ENABLE(memory-limit,
|
||||
ZEND_MEMORY_LIMIT=no
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE(zend-multibyte,
|
||||
[ --enable-zend-multibyte Compile with zend multibyte support], [
|
||||
ZEND_MULTIBYTE=$enableval
|
||||
],[
|
||||
ZEND_MULTIBYTE=no
|
||||
])
|
||||
dnl AC_ARG_ENABLE(zend-multibyte,
|
||||
dnl [ --enable-zend-multibyte Compile with zend multibyte support], [
|
||||
dnl ZEND_MULTIBYTE=$enableval
|
||||
dnl ],[
|
||||
dnl ZEND_MULTIBYTE=no
|
||||
dnl ])
|
||||
|
||||
dnl Unicode PHP doesn't need ZEND_MULTIBYTE
|
||||
ZEND_MULTIBYTE=no
|
||||
|
||||
AC_MSG_CHECKING([virtual machine dispatch method])
|
||||
AC_MSG_RESULT($PHP_ZEND_VM)
|
||||
|
@ -440,18 +440,6 @@ YY_MALLOC_DECL
|
||||
#define ECHO /* There is no output */
|
||||
#endif
|
||||
|
||||
#ifdef ZEND_MULTIBYTE
|
||||
# define YY_INPUT(buf, result, max_size) \
|
||||
if ( ((result = zend_multibyte_yyinput(yyin, buf, max_size TSRMLS_CC)) == 0) \
|
||||
&& zend_stream_ferror( yyin TSRMLS_CC) ) \
|
||||
YY_FATAL_ERROR( "input in flex scanner failed" );
|
||||
#else
|
||||
# define YY_INPUT(buf, result, max_size) \
|
||||
if ( ((result = zend_stream_read(yyin, buf, max_size TSRMLS_CC)) == 0) \
|
||||
&& zend_stream_ferror( yyin TSRMLS_CC) ) \
|
||||
YY_FATAL_ERROR( "input in flex scanner failed" );
|
||||
#endif
|
||||
|
||||
#ifndef ECHO
|
||||
%- Standard (non-C++) definition
|
||||
/* This used to be an fputs(), but since the string might contain NUL's,
|
||||
|
914
Zend/zend.c
914
Zend/zend.c
File diff suppressed because it is too large
Load Diff
49
Zend/zend.h
49
Zend/zend.h
@ -35,6 +35,7 @@
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* general definitions
|
||||
@ -225,6 +226,8 @@ char *alloca ();
|
||||
|
||||
#include "zend_types.h"
|
||||
|
||||
#include <unicode/utypes.h>
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
@ -237,6 +240,8 @@ char *alloca ();
|
||||
#define LONG_MIN (- LONG_MAX - 1)
|
||||
#endif
|
||||
|
||||
#define EMPTY_STR "\0\0"
|
||||
|
||||
#undef SUCCESS
|
||||
#undef FAILURE
|
||||
#define SUCCESS 0
|
||||
@ -258,6 +263,13 @@ void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((nore
|
||||
# define zend_error_noreturn zend_error
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(DARWIN)
|
||||
# define ZEND_VM_ALWAYS_INLINE __attribute__ ((always_inline))
|
||||
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((noreturn));
|
||||
#else
|
||||
# define ZEND_VM_ALWAYS_INLINE
|
||||
# define zend_error_noreturn zend_error
|
||||
#endif
|
||||
|
||||
/*
|
||||
* zval
|
||||
@ -287,10 +299,14 @@ struct _zend_object_value {
|
||||
typedef union _zvalue_value {
|
||||
long lval; /* long value */
|
||||
double dval; /* double value */
|
||||
struct {
|
||||
struct { /* 8-bit legacy string type */
|
||||
char *val;
|
||||
int len;
|
||||
} str;
|
||||
struct { /* Unicode string type */
|
||||
UChar *val;
|
||||
int32_t len;
|
||||
} ustr;
|
||||
HashTable *ht; /* hash table value */
|
||||
zend_object_value obj;
|
||||
} zvalue_value;
|
||||
@ -371,8 +387,8 @@ struct _zend_class_entry {
|
||||
|
||||
#include "zend_stream.h"
|
||||
typedef struct _zend_utility_functions {
|
||||
void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
|
||||
int (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
|
||||
void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
|
||||
int (*printf_function)(const char *format, ...);
|
||||
int (*write_function)(const char *str, uint str_length);
|
||||
FILE *(*fopen_function)(const char *filename, char **opened_path);
|
||||
void (*message_handler)(long message, void *data);
|
||||
@ -407,6 +423,8 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
|
||||
((n) ? (((n)>0) ? 1 : -1) : 0)
|
||||
#define ZEND_TRUTH(x) ((x) ? 1 : 0)
|
||||
#define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b))
|
||||
#define ZEND_COLL_RESULT(n) \
|
||||
((n) == UCOL_EQUAL ? 0 : ((n) == UCOL_GREATER ? 1 : -1))
|
||||
|
||||
|
||||
|
||||
@ -422,6 +440,8 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
|
||||
#define IS_RESOURCE 7
|
||||
#define IS_CONSTANT 8
|
||||
#define IS_CONSTANT_ARRAY 9
|
||||
#define IS_UNICODE 10
|
||||
#define IS_BINARY 11
|
||||
|
||||
/* Ugly hack to support constants as static array indices */
|
||||
#define IS_CONSTANT_INDEX 0x80
|
||||
@ -432,14 +452,13 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
|
||||
#define OE_IS_OBJECT (1<<1)
|
||||
#define OE_IS_METHOD (1<<2)
|
||||
|
||||
|
||||
int zend_startup(zend_utility_functions *utility_functions, char **extensions, int start_builtin_functions);
|
||||
void zend_shutdown(TSRMLS_D);
|
||||
void zend_register_standard_ini_entries(TSRMLS_D);
|
||||
|
||||
#ifdef ZTS
|
||||
//#ifdef ZTS
|
||||
void zend_post_startup(TSRMLS_D);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
void zend_set_utility_values(zend_utility_values *utility_values);
|
||||
|
||||
@ -468,12 +487,14 @@ END_EXTERN_C()
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API char *get_zend_version(void);
|
||||
ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy);
|
||||
ZEND_API void zend_make_string_zval(zval *expr, zval *expr_copy, int *use_copy);
|
||||
ZEND_API void zend_make_unicode_zval(zval *expr, zval *expr_copy, int *use_copy);
|
||||
ZEND_API int zend_print_zval(zval *expr, int indent);
|
||||
ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent);
|
||||
ZEND_API void zend_print_zval_r(zval *expr, int indent TSRMLS_DC);
|
||||
ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC);
|
||||
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC);
|
||||
ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
|
||||
ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...);
|
||||
END_EXTERN_C()
|
||||
|
||||
void zend_activate(TSRMLS_D);
|
||||
@ -510,20 +531,20 @@ END_EXTERN_C()
|
||||
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
extern ZEND_API int (*zend_printf)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
|
||||
extern ZEND_API int (*zend_printf)(const char *format, ...);
|
||||
extern ZEND_API zend_write_func_t zend_write;
|
||||
extern ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
|
||||
extern ZEND_API void (*zend_block_interruptions)(void);
|
||||
extern ZEND_API void (*zend_unblock_interruptions)(void);
|
||||
extern ZEND_API void (*zend_ticks_function)(int ticks);
|
||||
extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
|
||||
extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
|
||||
extern void (*zend_on_timeout)(int seconds TSRMLS_DC);
|
||||
extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
|
||||
extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
|
||||
extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
|
||||
|
||||
|
||||
ZEND_API void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
|
||||
ZEND_API void zend_error(int type, const char *format, ...);
|
||||
|
||||
void zenderror(char *error);
|
||||
|
||||
@ -545,6 +566,7 @@ BEGIN_EXTERN_C()
|
||||
ZEND_API void zend_message_dispatcher(long message, void *data);
|
||||
|
||||
ZEND_API int zend_get_configuration_directive(char *name, uint name_length, zval *contents);
|
||||
ZEND_API void zend_reset_locale_deps(TSRMLS_D);
|
||||
END_EXTERN_C()
|
||||
|
||||
|
||||
@ -644,8 +666,15 @@ END_EXTERN_C()
|
||||
|
||||
#define ZEND_MAX_RESERVED_RESOURCES 4
|
||||
|
||||
#define ZEND_INTERNAL_ENCODING "UTF-16"
|
||||
|
||||
#include "zend_variables.h"
|
||||
|
||||
#define ZEND_U_EQUAL(type, ustr, ulen, str, slen) \
|
||||
((type == IS_STRING)? \
|
||||
(!memcmp((ustr),(str),(slen))): \
|
||||
(!zend_cmp_unicode_and_literal(((UChar*)(ustr)), ulen, str, slen)))
|
||||
|
||||
#endif /* ZEND_H */
|
||||
|
||||
/*
|
||||
|
691
Zend/zend_API.c
691
Zend/zend_API.c
File diff suppressed because it is too large
Load Diff
109
Zend/zend_API.h
109
Zend/zend_API.h
@ -126,6 +126,8 @@ typedef struct _zend_function_entry {
|
||||
class_container.constructor = NULL; \
|
||||
class_container.destructor = NULL; \
|
||||
class_container.clone = NULL; \
|
||||
class_container.serialize = NULL; \
|
||||
class_container.unserialize = NULL; \
|
||||
class_container.create_object = NULL; \
|
||||
class_container.interface_gets_implemented = NULL; \
|
||||
class_container.__call = handle_fcall; \
|
||||
@ -212,6 +214,8 @@ ZEND_API int zend_declare_property_double(zend_class_entry *ce, char *name, int
|
||||
ZEND_API int zend_declare_property_string(zend_class_entry *ce, char *name, int name_length, char *value, int access_type TSRMLS_DC);
|
||||
ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, char *name, int name_length, char *value, int value_len, int access_type TSRMLS_DC);
|
||||
|
||||
ZEND_API int zend_u_declare_property(zend_class_entry *ce, zend_uchar type, void *name, int name_length, zval *property, int access_type TSRMLS_DC);
|
||||
|
||||
ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC);
|
||||
ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *name, int name_length, zval *value TSRMLS_DC);
|
||||
ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length TSRMLS_DC);
|
||||
@ -225,6 +229,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *n
|
||||
|
||||
ZEND_API zend_class_entry *zend_get_class_entry(zval *zobject TSRMLS_DC);
|
||||
ZEND_API int zend_get_object_classname(zval *object, char **class_name, zend_uint *class_name_len TSRMLS_DC);
|
||||
ZEND_API zend_uchar zend_get_best_string_type(int num_args, ...);
|
||||
|
||||
#define getThis() (this_ptr)
|
||||
|
||||
@ -260,6 +265,8 @@ ZEND_API int add_assoc_resource_ex(zval *arg, char *key, uint key_len, int r);
|
||||
ZEND_API int add_assoc_double_ex(zval *arg, char *key, uint key_len, double d);
|
||||
ZEND_API int add_assoc_string_ex(zval *arg, char *key, uint key_len, char *str, int duplicate);
|
||||
ZEND_API int add_assoc_stringl_ex(zval *arg, char *key, uint key_len, char *str, uint length, int duplicate);
|
||||
ZEND_API int add_assoc_unicode_ex(zval *arg, char *key, uint key_len, void *str, int duplicate);
|
||||
ZEND_API int add_assoc_unicodel_ex(zval *arg, char *key, uint key_len, void *str, uint length, int duplicate);
|
||||
ZEND_API int add_assoc_zval_ex(zval *arg, char *key, uint key_len, zval *value);
|
||||
|
||||
#define add_assoc_long(__arg, __key, __n) add_assoc_long_ex(__arg, __key, strlen(__key)+1, __n)
|
||||
@ -269,8 +276,14 @@ ZEND_API int add_assoc_zval_ex(zval *arg, char *key, uint key_len, zval *value);
|
||||
#define add_assoc_double(__arg, __key, __d) add_assoc_double_ex(__arg, __key, strlen(__key)+1, __d)
|
||||
#define add_assoc_string(__arg, __key, __str, __duplicate) add_assoc_string_ex(__arg, __key, strlen(__key)+1, __str, __duplicate)
|
||||
#define add_assoc_stringl(__arg, __key, __str, __length, __duplicate) add_assoc_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate)
|
||||
#define add_assoc_unicode(__arg, __key, __str, __duplicate) add_assoc_unicode_ex(__arg, __key, strlen(__key)+1, __str, __duplicate)
|
||||
#define add_assoc_unicodel(__arg, __key, __str, __length, __duplicate) add_assoc_unicodel_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate)
|
||||
#define add_assoc_zval(__arg, __key, __value) add_assoc_zval_ex(__arg, __key, strlen(__key)+1, __value)
|
||||
|
||||
ZEND_API int add_u_assoc_zval_ex(zval *arg, zend_uchar type, void *key, uint key_len, zval *value);
|
||||
|
||||
#define add_u_assoc_zval(__arg, __type, __key, __value) add_u_assoc_zval_ex(__arg, __type, __key, (((__type)==IS_UNICODE)?u_strlen((UChar*)__key):strlen(__key))+1, __value)
|
||||
|
||||
/* unset() functions are only suported for legacy modules and null() functions should be used */
|
||||
#define add_assoc_unset(__arg, __key) add_assoc_null_ex(__arg, __key, strlen(__key) + 1)
|
||||
#define add_index_unset(__arg, __key) add_index_null(__arg, __key)
|
||||
@ -284,6 +297,10 @@ ZEND_API int add_index_resource(zval *arg, uint idx, int r);
|
||||
ZEND_API int add_index_double(zval *arg, uint idx, double d);
|
||||
ZEND_API int add_index_string(zval *arg, uint idx, char *str, int duplicate);
|
||||
ZEND_API int add_index_stringl(zval *arg, uint idx, char *str, uint length, int duplicate);
|
||||
ZEND_API int add_index_binary(zval *arg, uint idx, char *str, int duplicate);
|
||||
ZEND_API int add_index_binaryl(zval *arg, uint idx, char *str, uint length, int duplicate);
|
||||
ZEND_API int add_index_unicode(zval *arg, uint idx, UChar *str, int duplicate);
|
||||
ZEND_API int add_index_unicodel(zval *arg, uint idx, UChar *str, uint length, int duplicate);
|
||||
ZEND_API int add_index_zval(zval *arg, uint index, zval *value);
|
||||
|
||||
ZEND_API int add_next_index_long(zval *arg, long n);
|
||||
@ -293,6 +310,10 @@ ZEND_API int add_next_index_resource(zval *arg, int r);
|
||||
ZEND_API int add_next_index_double(zval *arg, double d);
|
||||
ZEND_API int add_next_index_string(zval *arg, char *str, int duplicate);
|
||||
ZEND_API int add_next_index_stringl(zval *arg, char *str, uint length, int duplicate);
|
||||
ZEND_API int add_next_index_binary(zval *arg, char *str, int duplicate);
|
||||
ZEND_API int add_next_index_binaryl(zval *arg, char *str, uint length, int duplicate);
|
||||
ZEND_API int add_next_index_unicode(zval *arg, UChar *str, int duplicate);
|
||||
ZEND_API int add_next_index_unicodel(zval *arg, UChar *str, uint length, int duplicate);
|
||||
ZEND_API int add_next_index_zval(zval *arg, zval *value);
|
||||
|
||||
ZEND_API int add_get_assoc_string_ex(zval *arg, char *key, uint key_len, char *str, void **dest, int duplicate);
|
||||
@ -305,6 +326,10 @@ ZEND_API int add_get_index_long(zval *arg, uint idx, long l, void **dest);
|
||||
ZEND_API int add_get_index_double(zval *arg, uint idx, double d, void **dest);
|
||||
ZEND_API int add_get_index_string(zval *arg, uint idx, char *str, void **dest, int duplicate);
|
||||
ZEND_API int add_get_index_stringl(zval *arg, uint idx, char *str, uint length, void **dest, int duplicate);
|
||||
ZEND_API int add_get_index_binary(zval *arg, uint idx, char *str, void **dest, int duplicate);
|
||||
ZEND_API int add_get_index_binaryl(zval *arg, uint idx, char *str, uint length, void **dest, int duplicate);
|
||||
ZEND_API int add_get_index_unicode(zval *arg, uint idx, UChar *str, void **dest, int duplicate);
|
||||
ZEND_API int add_get_index_unicodel(zval *arg, uint idx, UChar *str, uint length, void **dest, int duplicate);
|
||||
|
||||
ZEND_API int add_property_long_ex(zval *arg, char *key, uint key_len, long l TSRMLS_DC);
|
||||
ZEND_API int add_property_null_ex(zval *arg, char *key, uint key_len TSRMLS_DC);
|
||||
@ -358,6 +383,9 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
|
||||
zend_bool is_ref, int num_symbol_tables, ...);
|
||||
|
||||
ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC);
|
||||
ZEND_API int zend_u_delete_global_variable(zend_uchar type, void *name, int name_len TSRMLS_DC);
|
||||
|
||||
ZEND_API zend_class_entry* zend_get_named_class_entry(char* name, int name_length TSRMLS_DC);
|
||||
|
||||
ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC);
|
||||
|
||||
@ -367,14 +395,24 @@ ZEND_API ZEND_FUNCTION(display_disabled_function);
|
||||
ZEND_API ZEND_FUNCTION(display_disabled_class);
|
||||
END_EXTERN_C()
|
||||
|
||||
|
||||
#define BINARY_TYPE (UG(unicode) ? IS_BINARY : IS_STRING)
|
||||
|
||||
|
||||
#if ZEND_DEBUG
|
||||
#define CHECK_ZVAL_STRING(z) \
|
||||
if ((z)->value.str.val[ (z)->value.str.len ] != '\0') { zend_error(E_WARNING, "String is not zero-terminated (%s)", (z)->value.str.val); }
|
||||
#define CHECK_ZVAL_STRING_REL(z) \
|
||||
if ((z)->value.str.val[ (z)->value.str.len ] != '\0') { zend_error(E_WARNING, "String is not zero-terminated (%s) (source: %s:%d)", (z)->value.str.val ZEND_FILE_LINE_RELAY_CC); }
|
||||
#define CHECK_ZVAL_UNICODE(z) \
|
||||
if ((z)->value.ustr.val[ (z)->value.ustr.len ] != 0 ) { zend_error(E_WARNING, "String is not zero-terminated"); }
|
||||
#define CHECK_ZVAL_UNICODE_REL(z) \
|
||||
if ((z)->value.ustr.val[ (z)->value.ustr.len ] != 0) { zend_error(E_WARNING, "String is not zero-terminated (source: %s:%d)", ZEND_FILE_LINE_RELAY_C); }
|
||||
#else
|
||||
#define CHECK_ZVAL_STRING(z)
|
||||
#define CHECK_ZVAL_STRING_REL(z)
|
||||
#define CHECK_ZVAL_UNICODE(z)
|
||||
#define CHECK_ZVAL_UNICODE_REL(z)
|
||||
#endif
|
||||
|
||||
#define ZVAL_RESOURCE(z, l) { \
|
||||
@ -415,12 +453,52 @@ END_EXTERN_C()
|
||||
(z)->type = IS_STRING; \
|
||||
}
|
||||
|
||||
#define ZVAL_UNICODE(z, u, duplicate) { \
|
||||
UChar *__u=(u); \
|
||||
(z)->value.ustr.len = u_strlen(__u); \
|
||||
(z)->value.ustr.val = (duplicate?eustrndup(__u, (z)->value.ustr.len):__u); \
|
||||
(z)->type = IS_UNICODE; \
|
||||
}
|
||||
|
||||
#define ZVAL_UNICODEL(z, u, l, duplicate) { \
|
||||
UChar *__u=(u); int32_t __l=l; \
|
||||
(z)->value.ustr.len = __l; \
|
||||
(z)->value.ustr.val = (duplicate?eustrndup(__u, __l):__u); \
|
||||
(z)->type = IS_UNICODE; \
|
||||
}
|
||||
|
||||
#define ZVAL_BINARY(z, s, duplicate) { \
|
||||
char *__s=(s); \
|
||||
(z)->value.str.len = strlen(__s); \
|
||||
(z)->value.str.val = (duplicate?estrndup(__s, (z)->value.str.len):__s); \
|
||||
(z)->type = BINARY_TYPE; \
|
||||
}
|
||||
|
||||
#define ZVAL_BINARYL(z, s, l, duplicate) { \
|
||||
char *__s=(s); int __l=l; \
|
||||
(z)->value.str.len = __l; \
|
||||
(z)->value.str.val = (duplicate?estrndup(__s, __l):__s); \
|
||||
(z)->type = BINARY_TYPE; \
|
||||
}
|
||||
|
||||
#define ZVAL_EMPTY_STRING(z) { \
|
||||
(z)->value.str.len = 0; \
|
||||
(z)->value.str.val = STR_EMPTY_ALLOC(); \
|
||||
(z)->type = IS_STRING; \
|
||||
}
|
||||
|
||||
#define ZVAL_EMPTY_UNICODE(z) { \
|
||||
(z)->value.ustr.len = 0; \
|
||||
(z)->value.ustr.val = USTR_MAKE(""); \
|
||||
(z)->type = IS_UNICODE; \
|
||||
}
|
||||
|
||||
#define ZVAL_EMPTY_BINARY(z) { \
|
||||
(z)->value.str.len = 0; \
|
||||
(z)->value.str.val = STR_EMPTY_ALLOC(); \
|
||||
(z)->type = BINARY_TYPE; \
|
||||
}
|
||||
|
||||
#define ZVAL_ZVAL(z, zv, copy, dtor) { \
|
||||
int is_ref, refcount; \
|
||||
is_ref = (z)->is_ref; \
|
||||
@ -450,9 +528,32 @@ END_EXTERN_C()
|
||||
#define RETVAL_STRING(s, duplicate) ZVAL_STRING(return_value, s, duplicate)
|
||||
#define RETVAL_STRINGL(s, l, duplicate) ZVAL_STRINGL(return_value, s, l, duplicate)
|
||||
#define RETVAL_EMPTY_STRING() ZVAL_EMPTY_STRING(return_value)
|
||||
#define RETVAL_UNICODE(u, duplicate) ZVAL_UNICODE(return_value, u, duplicate)
|
||||
#define RETVAL_UNICODEL(u, l, duplicate) ZVAL_UNICODEL(return_value, u, l, duplicate)
|
||||
#define RETVAL_EMPTY_UNICODE() ZVAL_EMPTY_UNICODE(return_value)
|
||||
#define RETVAL_BINARY(s, duplicate) ZVAL_BINARY(return_value, s, duplicate)
|
||||
#define RETVAL_BINARYL(s, l, duplicate) ZVAL_BINARYL(return_value, s, l, duplicate)
|
||||
#define RETVAL_EMPTY_BINARY() ZVAL_EMPTY_BINARY(return_value)
|
||||
#define RETVAL_ZVAL(zv, copy, dtor) ZVAL_ZVAL(return_value, zv, copy, dtor)
|
||||
#define RETVAL_FALSE ZVAL_BOOL(return_value, 0)
|
||||
#define RETVAL_TRUE ZVAL_BOOL(return_value, 1)
|
||||
#define RETVAL_TEXT(t, duplicate) \
|
||||
do { \
|
||||
if (UG(unicode)) { \
|
||||
RETVAL_UNICODE(t, duplicate); \
|
||||
} else { \
|
||||
RETVAL_STRING(t, duplicate); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define RETVAL_TEXTL(t, l, duplicate) \
|
||||
do { \
|
||||
if (UG(unicode)) { \
|
||||
RETVAL_UNICODEL(t, l, duplicate); \
|
||||
} else { \
|
||||
RETVAL_STRINGL(t, l, duplicate); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
#define RETURN_RESOURCE(l) { RETVAL_RESOURCE(l); return; }
|
||||
#define RETURN_BOOL(b) { RETVAL_BOOL(b); return; }
|
||||
@ -462,9 +563,17 @@ END_EXTERN_C()
|
||||
#define RETURN_STRING(s, duplicate) { RETVAL_STRING(s, duplicate); return; }
|
||||
#define RETURN_STRINGL(s, l, duplicate) { RETVAL_STRINGL(s, l, duplicate); return; }
|
||||
#define RETURN_EMPTY_STRING() { RETVAL_EMPTY_STRING(); return; }
|
||||
#define RETURN_UNICODE(u, duplicate) { RETVAL_UNICODE(u, duplicate); return; }
|
||||
#define RETURN_UNICODEL(u, l, duplicate) { RETVAL_UNICODEL(u, l, duplicate); return; }
|
||||
#define RETURN_EMPTY_UNICODE() { RETVAL_EMPTY_UNICODE(); return; }
|
||||
#define RETURN_BINARY(s, duplicate) { RETVAL_BINARY(s, duplicate); return; }
|
||||
#define RETURN_BINARYL(s, l, duplicate) { RETVAL_BINARYL(s, l, duplicate); return; }
|
||||
#define RETURN_EMPTY_BINARY() { RETVAL_EMPTY_BINARY(); return; }
|
||||
#define RETURN_ZVAL(zv, copy, dtor) { RETVAL_ZVAL(zv, copy, dtor); return; }
|
||||
#define RETURN_FALSE { RETVAL_FALSE; return; }
|
||||
#define RETURN_TRUE { RETVAL_TRUE; return; }
|
||||
#define RETURN_TEXT(t, duplicate) { RETVAL_TEXT(t, duplicate); return; }
|
||||
#define RETURN_TEXTL(t, l, duplicate) { RETVAL_TEXTL(t, l, duplicate); return; }
|
||||
|
||||
#define SET_VAR_STRING(n, v) { \
|
||||
{ \
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "zend_alloc.h"
|
||||
#include "zend_globals.h"
|
||||
#include "zend_fast_cache.h"
|
||||
#include "zend_unicode.h"
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
# include <signal.h>
|
||||
#endif
|
||||
@ -409,6 +410,24 @@ ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
return p;
|
||||
}
|
||||
|
||||
ZEND_API UChar *_eustrdup(const UChar *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
{
|
||||
int length;
|
||||
UChar *p;
|
||||
|
||||
length = u_strlen(s)+1;
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
p = (UChar *) _emalloc(sizeof(UChar) * length ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
if (!p) {
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
return (UChar *)NULL;
|
||||
}
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
u_memcpy(p, s, length);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
{
|
||||
char *p;
|
||||
@ -426,6 +445,23 @@ ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_
|
||||
}
|
||||
|
||||
|
||||
ZEND_API UChar *_eustrndup(const UChar *s, int32_t length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
|
||||
{
|
||||
UChar *p;
|
||||
|
||||
HANDLE_BLOCK_INTERRUPTIONS();
|
||||
p = (UChar *) _emalloc(sizeof(UChar) * (length+1) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
|
||||
if (!p) {
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
return (UChar *)NULL;
|
||||
}
|
||||
HANDLE_UNBLOCK_INTERRUPTIONS();
|
||||
memcpy(p, s, length * sizeof(UChar));
|
||||
p[length] = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API char *zend_strndup(const char *s, uint length)
|
||||
{
|
||||
char *p;
|
||||
@ -441,6 +477,21 @@ ZEND_API char *zend_strndup(const char *s, uint length)
|
||||
return p;
|
||||
}
|
||||
|
||||
ZEND_API UChar *zend_ustrndup(const UChar *s, uint length)
|
||||
{
|
||||
UChar *p;
|
||||
|
||||
p = (UChar *) malloc(UBYTES(length+1));
|
||||
if (!p) {
|
||||
return (UChar *)NULL;
|
||||
}
|
||||
if (length) {
|
||||
memcpy(p, s, UBYTES(length));
|
||||
}
|
||||
p[length] = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_set_memory_limit(unsigned int memory_limit)
|
||||
{
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "zend_globals_macros.h"
|
||||
|
||||
#include "zend_mm.h"
|
||||
#include <unicode/utypes.h>
|
||||
|
||||
#define MEM_BLOCK_START_MAGIC 0x7312F8DCL
|
||||
#define MEM_BLOCK_END_MAGIC 0x2A8FCC84L
|
||||
@ -75,6 +76,7 @@ typedef union _align_test {
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
ZEND_API char *zend_strndup(const char *s, unsigned int length) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API UChar *zend_ustrndup(const UChar *s, uint length) ZEND_ATTRIBUTE_MALLOC;
|
||||
|
||||
ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
@ -84,6 +86,8 @@ ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI
|
||||
ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
|
||||
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API UChar *_eustrdup(const UChar *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
ZEND_API UChar *_eustrndup(const UChar *s, int32_t length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
|
||||
|
||||
#if USE_ZEND_ALLOC
|
||||
|
||||
@ -96,16 +100,23 @@ ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZE
|
||||
#define erealloc_recoverable(ptr, size) _erealloc((ptr), (size), 1 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
|
||||
#define estrdup(s) _estrdup((s) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
|
||||
#define estrndup(s, length) _estrndup((s), (length) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
|
||||
#define eumalloc(size) (UChar*)_emalloc(UBYTES(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
|
||||
#define eurealloc(ptr, size) (UChar*)_erealloc((ptr), UBYTES(size), 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
|
||||
#define eustrndup(s, length) _eustrndup((s), (length) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
|
||||
#define eustrdup(s) _eustrdup((s) ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
|
||||
|
||||
/* Relay wrapper macros */
|
||||
#define emalloc_rel(size) _emalloc((size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define safe_emalloc_rel(nmemb, size, offset) _safe_emalloc((nmemb), (size), (offset) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define efree_rel(ptr) _efree((ptr) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define ecalloc_rel(nmemb, size) _ecalloc((nmemb), (size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define erealloc_rel(ptr, size) _erealloc((ptr), (size), 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define erealloc_rel(ptr, size) _erealloc((ptr), (size), 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define erealloc_recoverable_rel(ptr, size) _erealloc((ptr), (size), 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define estrdup_rel(s) _estrdup((s) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define estrndup_rel(s, length) _estrndup((s), (length) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define eumalloc_rel(size) (UChar*)_emalloc(UBYTES(size) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define eurealloc_rel(ptr, size) (UChar*)_erealloc((ptr), UBYTES(size), 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
#define eustrndup_rel(s, length) _eustrndup((s), (length) ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_CC)
|
||||
|
||||
/* Selective persistent/non persistent allocation macros */
|
||||
#define pemalloc(size, persistent) ((persistent)?malloc(size):emalloc(size))
|
||||
@ -115,6 +126,8 @@ ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC ZE
|
||||
#define perealloc(ptr, size, persistent) ((persistent)?realloc((ptr), (size)):erealloc((ptr), (size)))
|
||||
#define perealloc_recoverable(ptr, size, persistent) ((persistent)?realloc((ptr), (size)):erealloc_recoverable((ptr), (size)))
|
||||
#define pestrdup(s, persistent) ((persistent)?strdup(s):estrdup(s))
|
||||
#define peumalloc(size, persistent) ((persistent)?malloc(UBYTES(size)):eumalloc(size))
|
||||
#define peurealloc(ptr, size, persistent) ((persistent)?realloc((ptr),UBYTES(size)):eurealloc((ptr),size))
|
||||
|
||||
#define pemalloc_rel(size, persistent) ((persistent)?malloc(size):emalloc_rel(size))
|
||||
#define pefree_rel(ptr, persistent) ((persistent)?free(ptr):efree_rel(ptr))
|
||||
|
@ -279,8 +279,27 @@ ZEND_NAMED_FUNCTION(zend_if_strlen)
|
||||
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
|
||||
ZEND_WRONG_PARAM_COUNT();
|
||||
}
|
||||
convert_to_string_ex(str);
|
||||
RETVAL_LONG((*str)->value.str.len);
|
||||
|
||||
switch (Z_TYPE_PP(str)) {
|
||||
case IS_UNICODE:
|
||||
RETVAL_LONG(u_countChar32(Z_USTRVAL_PP(str), Z_USTRLEN_PP(str)));
|
||||
break;
|
||||
|
||||
case IS_STRING:
|
||||
case IS_BINARY:
|
||||
RETVAL_LONG(Z_STRLEN_PP(str));
|
||||
break;
|
||||
|
||||
default:
|
||||
if (UG(unicode)) {
|
||||
convert_to_unicode_ex(str);
|
||||
RETVAL_LONG(Z_USTRLEN_PP(str));
|
||||
} else {
|
||||
convert_to_string_ex(str);
|
||||
RETVAL_LONG(Z_STRLEN_PP(str));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -396,6 +415,12 @@ ZEND_FUNCTION(each)
|
||||
case HASH_KEY_IS_STRING:
|
||||
add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, 0);
|
||||
break;
|
||||
case HASH_KEY_IS_BINARY:
|
||||
add_get_index_binaryl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, 0);
|
||||
break;
|
||||
case HASH_KEY_IS_UNICODE:
|
||||
add_get_index_unicodel(return_value, 0, (UChar*)string_key, string_key_len-1, (void **) &inserted_pointer, 0);
|
||||
break;
|
||||
case HASH_KEY_IS_LONG:
|
||||
add_get_index_long(return_value, 0, num_key, (void **) &inserted_pointer);
|
||||
break;
|
||||
@ -470,6 +495,8 @@ ZEND_FUNCTION(define)
|
||||
case IS_LONG:
|
||||
case IS_DOUBLE:
|
||||
case IS_STRING:
|
||||
case IS_BINARY:
|
||||
case IS_UNICODE:
|
||||
case IS_BOOL:
|
||||
case IS_RESOURCE:
|
||||
case IS_NULL:
|
||||
@ -479,15 +506,22 @@ ZEND_FUNCTION(define)
|
||||
RETURN_FALSE;
|
||||
break;
|
||||
}
|
||||
convert_to_string_ex(var);
|
||||
|
||||
if (Z_TYPE_PP(var) != IS_STRING && Z_TYPE_PP(var) != IS_UNICODE) {
|
||||
convert_to_string_ex(var);
|
||||
}
|
||||
|
||||
c.value = **val;
|
||||
zval_copy_ctor(&c.value);
|
||||
c.flags = case_sensitive; /* non persistent */
|
||||
c.name = zend_strndup((*var)->value.str.val, (*var)->value.str.len);
|
||||
c.name_len = (*var)->value.str.len+1;
|
||||
if (Z_TYPE_PP(var) == IS_UNICODE) {
|
||||
c.name = (char*)zend_ustrndup(Z_USTRVAL_PP(var), Z_USTRLEN_PP(var));
|
||||
} else {
|
||||
c.name = zend_strndup(Z_STRVAL_PP(var), Z_STRLEN_PP(var));
|
||||
}
|
||||
c.name_len = Z_UNILEN_PP(var)+1;
|
||||
c.module_number = PHP_USER_CONSTANT;
|
||||
if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {
|
||||
if (zend_u_register_constant(Z_TYPE_PP(var), &c TSRMLS_CC) == SUCCESS) {
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
@ -507,8 +541,8 @@ ZEND_FUNCTION(defined)
|
||||
ZEND_WRONG_PARAM_COUNT();
|
||||
}
|
||||
|
||||
convert_to_string_ex(var);
|
||||
if (zend_get_constant((*var)->value.str.val, (*var)->value.str.len, &c TSRMLS_CC)) {
|
||||
convert_to_text_ex(var);
|
||||
if (zend_get_constant(Z_UNIVAL_PP(var), Z_UNILEN_PP(var), &c TSRMLS_CC)) {
|
||||
zval_dtor(&c);
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
@ -523,13 +557,17 @@ ZEND_FUNCTION(defined)
|
||||
ZEND_FUNCTION(get_class)
|
||||
{
|
||||
zval **arg;
|
||||
char *name = "";
|
||||
char *name = EMPTY_STR;
|
||||
zend_uint name_len = 0;
|
||||
int dup;
|
||||
|
||||
if (!ZEND_NUM_ARGS()) {
|
||||
if (EG(scope)) {
|
||||
RETURN_STRINGL(EG(scope)->name, EG(scope)->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
RETURN_UNICODEL((UChar*)EG(scope)->name, EG(scope)->name_length, 1);
|
||||
} else {
|
||||
RETURN_STRINGL(EG(scope)->name, EG(scope)->name_length, 1);
|
||||
}
|
||||
} else {
|
||||
zend_error(E_ERROR, "get_class() called without object from outside a class");
|
||||
}
|
||||
@ -543,7 +581,11 @@ ZEND_FUNCTION(get_class)
|
||||
|
||||
dup = zend_get_object_classname(*arg, &name, &name_len TSRMLS_CC);
|
||||
|
||||
RETURN_STRINGL(name, name_len, dup);
|
||||
if (UG(unicode)) {
|
||||
RETURN_UNICODEL((UChar*)name, name_len, 0);
|
||||
} else {
|
||||
RETURN_STRINGL(name, name_len, 0);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -560,7 +602,11 @@ ZEND_FUNCTION(get_parent_class)
|
||||
if (!ZEND_NUM_ARGS()) {
|
||||
ce = EG(scope);
|
||||
if (ce && ce->parent) {
|
||||
RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
RETURN_UNICODEL((UChar*)ce->parent->name, ce->parent->name_length, 1);
|
||||
} else {
|
||||
RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
|
||||
}
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -572,20 +618,28 @@ ZEND_FUNCTION(get_parent_class)
|
||||
if (Z_TYPE_PP(arg) == IS_OBJECT) {
|
||||
if (Z_OBJ_HT_PP(arg)->get_class_name
|
||||
&& Z_OBJ_HT_PP(arg)->get_class_name(*arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) {
|
||||
RETURN_STRINGL(name, name_length, 0);
|
||||
if (UG(unicode)) {
|
||||
RETURN_UNICODEL((UChar*)name, name_length, 0);
|
||||
} else{
|
||||
RETURN_STRINGL(name, name_length, 0);
|
||||
}
|
||||
} else {
|
||||
ce = zend_get_class_entry(*arg TSRMLS_CC);
|
||||
}
|
||||
} else if (Z_TYPE_PP(arg) == IS_STRING) {
|
||||
} else if (Z_TYPE_PP(arg) == IS_STRING || Z_TYPE_PP(arg) == IS_UNICODE) {
|
||||
zend_class_entry **pce;
|
||||
|
||||
if (zend_lookup_class(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &pce TSRMLS_CC) == SUCCESS) {
|
||||
if (zend_u_lookup_class(Z_TYPE_PP(arg), Z_UNIVAL_PP(arg), Z_UNILEN_PP(arg), &pce TSRMLS_CC) == SUCCESS) {
|
||||
ce = *pce;
|
||||
}
|
||||
}
|
||||
|
||||
if (ce && ce->parent) {
|
||||
RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
RETURN_UNICODEL((UChar*)ce->parent->name, ce->parent->name_length, 1);
|
||||
} else {
|
||||
RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
|
||||
}
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -606,7 +660,7 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
|
||||
|
||||
if (only_subclass && Z_TYPE_PP(obj) == IS_STRING) {
|
||||
zend_class_entry **the_ce;
|
||||
if (zend_lookup_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), &the_ce TSRMLS_CC) == FAILURE) {
|
||||
if (zend_u_lookup_class(Z_TYPE_PP(obj), Z_UNIVAL_PP(obj), Z_UNILEN_PP(obj), &the_ce TSRMLS_CC) == FAILURE) {
|
||||
zend_error(E_WARNING, "Unknown class passed as parameter");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
@ -624,7 +678,7 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
|
||||
|
||||
convert_to_string_ex(class_name);
|
||||
|
||||
if (zend_lookup_class(Z_STRVAL_PP(class_name), Z_STRLEN_PP(class_name), &ce TSRMLS_CC) == FAILURE) {
|
||||
if (zend_u_lookup_class(Z_TYPE_PP(class_name), Z_UNIVAL_PP(class_name), Z_UNILEN_PP(class_name), &ce TSRMLS_CC) == FAILURE) {
|
||||
retval = 0;
|
||||
} else {
|
||||
if (only_subclass) {
|
||||
@ -686,8 +740,9 @@ static void add_class_vars(zend_class_entry *ce, HashTable *properties, zval *re
|
||||
uint key_len;
|
||||
ulong num_index;
|
||||
zval *prop_copy;
|
||||
zend_uchar key_type;
|
||||
|
||||
zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos);
|
||||
key_type = zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos);
|
||||
zend_hash_move_forward_ex(properties, &pos);
|
||||
zend_unmangle_property_name(key, &class_name, &prop_name);
|
||||
if (class_name) {
|
||||
@ -712,7 +767,7 @@ static void add_class_vars(zend_class_entry *ce, HashTable *properties, zval *re
|
||||
zval_update_constant(&prop_copy, 0 TSRMLS_CC);
|
||||
}
|
||||
|
||||
add_assoc_zval(return_value, prop_name, prop_copy);
|
||||
add_u_assoc_zval(return_value, key_type==HASH_KEY_IS_UNICODE?IS_UNICODE:IS_STRING, prop_name, prop_copy);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -725,13 +780,14 @@ ZEND_FUNCTION(get_class_vars)
|
||||
{
|
||||
char *class_name;
|
||||
int class_name_len;
|
||||
zend_uchar type;
|
||||
zend_class_entry **pce;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &class_name, &class_name_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &class_name, &class_name_len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC) == FAILURE) {
|
||||
if (zend_u_lookup_class(type, class_name, class_name_len, &pce TSRMLS_CC) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
array_init(return_value);
|
||||
@ -774,17 +830,19 @@ ZEND_FUNCTION(get_object_vars)
|
||||
zend_hash_internal_pointer_reset_ex(properties, &pos);
|
||||
|
||||
while (zend_hash_get_current_data_ex(properties, (void **) &value, &pos) == SUCCESS) {
|
||||
if (zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos) == HASH_KEY_IS_STRING) {
|
||||
if (key[0]) {
|
||||
if (zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos) == (UG(unicode)?HASH_KEY_IS_UNICODE:HASH_KEY_IS_STRING)) {
|
||||
zend_u_unmangle_property_name(UG(unicode)?IS_UNICODE:IS_STRING, key, &class_name, &prop_name);
|
||||
if (class_name == NULL) {
|
||||
/* Not separating references */
|
||||
(*value)->refcount++;
|
||||
add_assoc_zval_ex(return_value, key, key_len, *value);
|
||||
add_u_assoc_zval_ex(return_value, UG(unicode)?IS_UNICODE:IS_STRING, key, key_len, *value);
|
||||
} else if (instanceof) {
|
||||
zend_unmangle_property_name(key, &class_name, &prop_name);
|
||||
if (!memcmp(class_name, "*", 2) || (Z_OBJCE_P(EG(This)) == Z_OBJCE_PP(obj) && !strcmp(Z_OBJCE_P(EG(This))->name, class_name))) {
|
||||
if (class_name[0] == '*' ||
|
||||
(Z_OBJCE_P(EG(This)) == Z_OBJCE_PP(obj) &&
|
||||
UG(unicode)?!u_strcmp((UChar*)Z_OBJCE_P(EG(This))->name, (UChar*)class_name):!strcmp(Z_OBJCE_P(EG(This))->name, class_name))) {
|
||||
/* Not separating references */
|
||||
(*value)->refcount++;
|
||||
add_assoc_zval_ex(return_value, prop_name, strlen(prop_name)+1, *value);
|
||||
add_u_assoc_zval(return_value, UG(unicode)?IS_UNICODE:IS_STRING, prop_name, *value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -814,8 +872,8 @@ ZEND_FUNCTION(get_class_methods)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ce = Z_OBJCE_PP(class);
|
||||
} else if (Z_TYPE_PP(class) == IS_STRING) {
|
||||
if (zend_lookup_class(Z_STRVAL_PP(class), Z_STRLEN_PP(class), &pce TSRMLS_CC) == SUCCESS) {
|
||||
} else if (Z_TYPE_PP(class) == IS_STRING || Z_TYPE_PP(class) == IS_UNICODE) {
|
||||
if (zend_u_lookup_class(Z_TYPE_PP(class), Z_UNIVAL_PP(class), Z_UNILEN_PP(class), &pce TSRMLS_CC) == SUCCESS) {
|
||||
ce = *pce;
|
||||
}
|
||||
}
|
||||
@ -835,7 +893,11 @@ ZEND_FUNCTION(get_class_methods)
|
||||
|| ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
|
||||
EG(scope) == mptr->common.scope)))) {
|
||||
MAKE_STD_ZVAL(method_name);
|
||||
ZVAL_STRING(method_name, mptr->common.function_name, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(method_name, (UChar*)mptr->common.function_name, 1);
|
||||
} else {
|
||||
ZVAL_STRING(method_name, mptr->common.function_name, 1);
|
||||
}
|
||||
zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
|
||||
}
|
||||
zend_hash_move_forward_ex(&ce->function_table, &pos);
|
||||
@ -849,6 +911,7 @@ ZEND_FUNCTION(get_class_methods)
|
||||
ZEND_FUNCTION(method_exists)
|
||||
{
|
||||
zval **klass, **method_name;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
zend_class_entry * ce, **pce;
|
||||
|
||||
@ -867,8 +930,8 @@ ZEND_FUNCTION(method_exists)
|
||||
}
|
||||
|
||||
convert_to_string_ex(method_name);
|
||||
lcname = zend_str_tolower_dup(Z_STRVAL_PP(method_name), Z_STRLEN_PP(method_name));
|
||||
if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method_name)+1)) {
|
||||
lcname = zend_u_str_case_fold(Z_TYPE_PP(method_name), Z_UNIVAL_PP(method_name), Z_UNILEN_PP(method_name), 1, &lcname_len);
|
||||
if (zend_u_hash_exists(&ce->function_table, Z_TYPE_PP(method_name), lcname, lcname_len+1)) {
|
||||
efree(lcname);
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
@ -962,26 +1025,26 @@ ZEND_FUNCTION(property_exists)
|
||||
Checks if the class exists */
|
||||
ZEND_FUNCTION(class_exists)
|
||||
{
|
||||
char *class_name, *lc_name;
|
||||
unsigned int lc_name_len;
|
||||
void *class_name, *lc_name;
|
||||
zend_class_entry **ce;
|
||||
int class_name_len;
|
||||
zend_bool autoload = 1;
|
||||
zend_uchar type;
|
||||
int found;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &class_name, &class_name_len, &autoload) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t|b", &class_name, &class_name_len, &type, &autoload) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!autoload) {
|
||||
lc_name = do_alloca(class_name_len + 1);
|
||||
zend_str_tolower_copy(lc_name, class_name, class_name_len);
|
||||
|
||||
found = zend_hash_find(EG(class_table), lc_name, class_name_len+1, (void **) &ce);
|
||||
free_alloca(lc_name);
|
||||
lc_name = zend_u_str_case_fold(type, class_name, class_name_len, 1, &lc_name_len);
|
||||
found = zend_u_hash_find(EG(class_table), type, lc_name, lc_name_len+1, (void **) &ce);
|
||||
efree(lc_name);
|
||||
RETURN_BOOL(found == SUCCESS && !((*ce)->ce_flags & ZEND_ACC_INTERFACE));
|
||||
}
|
||||
|
||||
if (zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC) == SUCCESS) {
|
||||
if (zend_u_lookup_class(type, class_name, class_name_len, &ce TSRMLS_CC) == SUCCESS) {
|
||||
RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) == 0);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
@ -993,26 +1056,26 @@ ZEND_FUNCTION(class_exists)
|
||||
Checks if the class exists */
|
||||
ZEND_FUNCTION(interface_exists)
|
||||
{
|
||||
char *iface_name, *lc_name;
|
||||
unsigned int lc_name_len;
|
||||
void *iface_name, *lc_name;
|
||||
zend_class_entry **ce;
|
||||
int iface_name_len;
|
||||
zend_uchar type;
|
||||
zend_bool autoload = 1;
|
||||
int found;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &iface_name, &iface_name_len, &autoload) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t|b", &iface_name, &iface_name_len, &type, &autoload) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!autoload) {
|
||||
lc_name = do_alloca(iface_name_len + 1);
|
||||
zend_str_tolower_copy(lc_name, iface_name, iface_name_len);
|
||||
|
||||
found = zend_hash_find(EG(class_table), lc_name, iface_name_len+1, (void **) &ce);
|
||||
free_alloca(lc_name);
|
||||
lc_name = zend_u_str_case_fold(type, iface_name, iface_name_len, 1, &lc_name_len);
|
||||
found = zend_u_hash_find(EG(class_table), type, lc_name, lc_name_len+1, (void **) &ce);
|
||||
efree(lc_name);
|
||||
RETURN_BOOL(found == SUCCESS && (*ce)->ce_flags & ZEND_ACC_INTERFACE);
|
||||
}
|
||||
|
||||
if (zend_lookup_class(iface_name, iface_name_len, &ce TSRMLS_CC) == SUCCESS) {
|
||||
if (zend_u_lookup_class(type, iface_name, iface_name_len, &ce TSRMLS_CC) == SUCCESS) {
|
||||
RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) > 0);
|
||||
} else {
|
||||
RETURN_FALSE;
|
||||
@ -1027,6 +1090,7 @@ ZEND_FUNCTION(function_exists)
|
||||
{
|
||||
zval **function_name;
|
||||
zend_function *func;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
zend_bool retval;
|
||||
|
||||
@ -1034,9 +1098,9 @@ ZEND_FUNCTION(function_exists)
|
||||
ZEND_WRONG_PARAM_COUNT();
|
||||
}
|
||||
convert_to_string_ex(function_name);
|
||||
lcname = zend_str_tolower_dup((*function_name)->value.str.val, (*function_name)->value.str.len);
|
||||
lcname = zend_u_str_case_fold(Z_TYPE_PP(function_name), Z_UNIVAL_PP(function_name), Z_UNILEN_PP(function_name), 1, &lcname_len);
|
||||
|
||||
retval = (zend_hash_find(EG(function_table), lcname, (*function_name)->value.str.len+1, (void **)&func) == SUCCESS);
|
||||
retval = (zend_u_hash_find(EG(function_table), Z_TYPE_PP(function_name), lcname, lcname_len+1, (void **)&func) == SUCCESS);
|
||||
|
||||
efree(lcname);
|
||||
|
||||
@ -1283,10 +1347,17 @@ static int copy_class_or_interface_name(zend_class_entry **pce, int num_args, va
|
||||
zend_uint comply = va_arg(args, zend_uint);
|
||||
zend_uint comply_mask = (comply)? mask:0;
|
||||
zend_class_entry *ce = *pce;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if ((hash_key->nKeyLength==0 || hash_key->arKey[0]!=0)
|
||||
if ((hash_key->nKeyLength==0 ||
|
||||
(hash_key->type == IS_UNICODE && hash_key->u.unicode[0] != 0) ||
|
||||
(hash_key->type == IS_STRING && hash_key->u.string[0] != 0))
|
||||
&& (comply_mask == (ce->ce_flags & mask))) {
|
||||
add_next_index_stringl(array, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
add_next_index_unicodel(array, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
add_next_index_stringl(array, ce->name, ce->name_length, 1);
|
||||
}
|
||||
}
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
@ -1330,14 +1401,29 @@ static int copy_function_name(zend_function *func, int num_args, va_list args, z
|
||||
zval *internal_ar = va_arg(args, zval *),
|
||||
*user_ar = va_arg(args, zval *);
|
||||
|
||||
if (hash_key->nKeyLength == 0 || hash_key->arKey[0] == 0) {
|
||||
if (hash_key->nKeyLength == 0 ||
|
||||
hash_key->type == IS_BINARY ||
|
||||
(hash_key->type == IS_UNICODE && hash_key->u.unicode[0] == 0) ||
|
||||
(hash_key->type == IS_STRING && hash_key->u.unicode[0] == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (func->type == ZEND_INTERNAL_FUNCTION) {
|
||||
add_next_index_stringl(internal_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
|
||||
if (hash_key->type == IS_STRING) {
|
||||
add_next_index_stringl(internal_ar, hash_key->u.string, hash_key->nKeyLength-1, 1);
|
||||
} else if (hash_key->type == IS_BINARY) {
|
||||
add_next_index_binaryl(internal_ar, hash_key->u.string, hash_key->nKeyLength-1, 1);
|
||||
} else {
|
||||
add_next_index_unicodel(internal_ar, hash_key->u.unicode, hash_key->nKeyLength-1, 1);
|
||||
}
|
||||
} else if (func->type == ZEND_USER_FUNCTION) {
|
||||
add_next_index_stringl(user_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
|
||||
if (hash_key->type == IS_STRING) {
|
||||
add_next_index_stringl(user_ar, hash_key->u.string, hash_key->nKeyLength-1, 1);
|
||||
} else if (hash_key->type == IS_BINARY) {
|
||||
add_next_index_binaryl(user_ar, hash_key->u.string, hash_key->nKeyLength-1, 1);
|
||||
} else {
|
||||
add_next_index_unicodel(user_ar, hash_key->u.unicode, hash_key->nKeyLength-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1431,7 +1517,7 @@ ZEND_FUNCTION(create_function)
|
||||
RETURN_FALSE;
|
||||
}
|
||||
new_function = *func;
|
||||
function_add_ref(&new_function);
|
||||
function_add_ref(&new_function TSRMLS_CC);
|
||||
|
||||
function_name = (char *) emalloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG);
|
||||
|
||||
@ -1507,7 +1593,7 @@ static int add_constant_info(zend_constant *constant, void *arg TSRMLS_DC)
|
||||
*const_val = constant->value;
|
||||
zval_copy_ctor(const_val);
|
||||
INIT_PZVAL(const_val);
|
||||
add_assoc_zval_ex(name_array, constant->name, constant->name_len, const_val);
|
||||
add_u_assoc_zval_ex(name_array, UG(unicode)?IS_UNICODE:IS_STRING, constant->name, constant->name_len, const_val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1695,6 +1781,7 @@ ZEND_FUNCTION(debug_print_backtrace)
|
||||
|
||||
while (ptr) {
|
||||
char *free_class_name = NULL;
|
||||
int function_name_string = 1;
|
||||
|
||||
class_name = call_type = NULL;
|
||||
arg_array = NULL;
|
||||
@ -1721,6 +1808,7 @@ ZEND_FUNCTION(debug_print_backtrace)
|
||||
function_name = ptr->function_state.function->common.function_name;
|
||||
|
||||
if (function_name) {
|
||||
function_name_string = !UG(unicode);
|
||||
if (ptr->object) {
|
||||
if (ptr->function_state.function->common.scope) {
|
||||
class_name = ptr->function_state.function->common.scope->name;
|
||||
@ -1791,10 +1879,18 @@ ZEND_FUNCTION(debug_print_backtrace)
|
||||
}
|
||||
zend_printf("#%-2d ", indent);
|
||||
if (class_name) {
|
||||
ZEND_PUTS(class_name);
|
||||
if (UG(unicode)) {
|
||||
zend_printf("%r(", class_name);
|
||||
} else {
|
||||
ZEND_PUTS(class_name);
|
||||
}
|
||||
ZEND_PUTS(call_type);
|
||||
}
|
||||
zend_printf("%s(", function_name?function_name:"main");
|
||||
if (function_name_string) {
|
||||
zend_printf("%s(", function_name?function_name:"main");
|
||||
} else {
|
||||
zend_printf("%r(", function_name);
|
||||
}
|
||||
if (arg_array) {
|
||||
debug_print_backtrace_args(arg_array TSRMLS_CC);
|
||||
zval_ptr_dtor(&arg_array);
|
||||
@ -1898,22 +1994,37 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last TSRML
|
||||
function_name = ptr->function_state.function->common.function_name;
|
||||
|
||||
if (function_name) {
|
||||
add_assoc_string_ex(stack_frame, "function", sizeof("function"), function_name, 1);
|
||||
if (UG(unicode)) {
|
||||
add_assoc_unicode_ex(stack_frame, "function", sizeof("function"), function_name, 1);
|
||||
} else {
|
||||
add_assoc_string_ex(stack_frame, "function", sizeof("function"), function_name, 1);
|
||||
}
|
||||
|
||||
if (ptr->object && Z_TYPE_P(ptr->object) == IS_OBJECT) {
|
||||
if (ptr->function_state.function->common.scope) {
|
||||
add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
|
||||
if (UG(unicode)) {
|
||||
add_assoc_unicode_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
|
||||
} else {
|
||||
add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
|
||||
}
|
||||
} else {
|
||||
zend_uint class_name_len;
|
||||
int dup;
|
||||
|
||||
dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
|
||||
add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, dup);
|
||||
|
||||
if (UG(unicode)) {
|
||||
add_assoc_unicode_ex(stack_frame, "class", sizeof("class"), class_name, dup);
|
||||
} else {
|
||||
add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, dup);
|
||||
}
|
||||
}
|
||||
add_assoc_string_ex(stack_frame, "type", sizeof("type"), "->", 1);
|
||||
} else if (ptr->function_state.function->common.scope) {
|
||||
add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
|
||||
if (UG(unicode)) {
|
||||
add_assoc_unicode_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
|
||||
} else {
|
||||
add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
|
||||
}
|
||||
add_assoc_string_ex(stack_frame, "type", sizeof("type"), "::", 1);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -237,7 +237,7 @@ typedef struct _zend_internal_function {
|
||||
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
|
||||
} zend_internal_function;
|
||||
|
||||
#define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? (function)->common.scope->name : "")
|
||||
#define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? (function)->common.scope->name : EMPTY_STR)
|
||||
|
||||
typedef union _zend_function {
|
||||
zend_uchar type; /* MUST be the first element of this struct! */
|
||||
@ -329,6 +329,10 @@ ZEND_API int zend_get_scanned_file_offset(TSRMLS_D);
|
||||
|
||||
ZEND_API char* zend_get_compiled_variable_name(zend_op_array *op_array, zend_uint var, int* name_len);
|
||||
|
||||
ZEND_API int zend_prepare_scanner_converters(const char *onetime_encoding, int run_time TSRMLS_DC);
|
||||
ZEND_API int32_t zend_convert_scanner_output(UChar **target, int32_t *target_len, const char *source, int32_t source_len, UErrorCode *status TSRMLS_DC);
|
||||
int zend_unicode_yyinput(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC);
|
||||
|
||||
#ifdef ZTS
|
||||
const char *zend_get_zendtext(TSRMLS_D);
|
||||
int zend_get_zendleng(TSRMLS_D);
|
||||
@ -352,7 +356,7 @@ void fetch_array_dim(znode *result, znode *parent, znode *dim TSRMLS_DC);
|
||||
void fetch_string_offset(znode *result, znode *parent, znode *offset TSRMLS_DC);
|
||||
void zend_do_fetch_static_member(znode *result, znode *class_znode TSRMLS_DC);
|
||||
void zend_do_print(znode *result, znode *arg TSRMLS_DC);
|
||||
void zend_do_echo(znode *arg TSRMLS_DC);
|
||||
void zend_do_echo(znode *arg, zend_bool inline_html TSRMLS_DC);
|
||||
typedef int (*unary_op_type)(zval *, zval *);
|
||||
ZEND_API unary_op_type get_unary_op(int opcode);
|
||||
ZEND_API void *get_binary_op(int opcode);
|
||||
@ -497,7 +501,9 @@ void zend_do_ticks(TSRMLS_D);
|
||||
|
||||
void zend_do_abstract_method(znode *function_name, znode *modifiers, znode *body TSRMLS_DC);
|
||||
|
||||
ZEND_API void function_add_ref(zend_function *function);
|
||||
ZEND_API void function_add_ref(zend_function *function TSRMLS_DC);
|
||||
|
||||
void zend_do_normalization(znode *result, znode *str TSRMLS_DC);
|
||||
|
||||
#define INITIAL_OP_ARRAY_SIZE 64
|
||||
|
||||
@ -523,6 +529,10 @@ void zend_class_add_ref(zend_class_entry **ce);
|
||||
ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, char *src1, int src1_length, char *src2, int src2_length, int internal);
|
||||
ZEND_API void zend_unmangle_property_name(char *mangled_property, char **prop_name, char **class_name);
|
||||
|
||||
ZEND_API void zend_u_mangle_property_name(char **dest, int *dest_length, zend_uchar type, char *src1, int src1_length, char *src2, int src2_length, int internal);
|
||||
ZEND_API void zend_u_unmangle_property_name(zend_uchar type, char *mangled_property, char **prop_name, char **class_name);
|
||||
|
||||
|
||||
#define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor
|
||||
#define ZEND_CLASS_DTOR (void (*)(void *)) destroy_zend_class
|
||||
|
||||
@ -539,7 +549,7 @@ void zend_do_mark_last_catch(znode *first_catch, znode *last_additional_catch TS
|
||||
ZEND_API zend_bool zend_is_compiling(TSRMLS_D);
|
||||
ZEND_API char *zend_make_compiled_string_description(char *name TSRMLS_DC);
|
||||
ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC);
|
||||
int zend_get_class_fetch_type(char *class_name, uint class_name_len);
|
||||
int zend_get_class_fetch_type(zend_uchar type, char *class_name, uint class_name_len);
|
||||
|
||||
typedef zend_bool (*zend_auto_global_callback)(char *name, uint name_len TSRMLS_DC);
|
||||
typedef struct _zend_auto_global {
|
||||
@ -552,6 +562,7 @@ typedef struct _zend_auto_global {
|
||||
void zend_auto_global_dtor(zend_auto_global *auto_global);
|
||||
ZEND_API int zend_register_auto_global(char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC);
|
||||
ZEND_API zend_bool zend_is_auto_global(char *name, uint name_len TSRMLS_DC);
|
||||
ZEND_API zend_bool zend_u_is_auto_global(zend_uchar type, void *name, uint name_len TSRMLS_DC);
|
||||
ZEND_API int zend_auto_global_disable_jit(char *varname, zend_uint varname_length TSRMLS_DC);
|
||||
|
||||
int zendlex(znode *zendlval TSRMLS_DC);
|
||||
|
@ -83,7 +83,7 @@ int zend_startup_constants(TSRMLS_D)
|
||||
{
|
||||
EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
|
||||
|
||||
if (zend_hash_init(EG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1)==FAILURE) {
|
||||
if (zend_u_hash_init(EG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1, UG(unicode))==FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
return SUCCESS;
|
||||
@ -108,6 +108,11 @@ void zend_register_standard_constants(TSRMLS_D)
|
||||
|
||||
REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
|
||||
|
||||
REGISTER_MAIN_LONG_CONSTANT("U_INVALID_STOP", ZEND_FROM_U_ERROR_STOP, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_MAIN_LONG_CONSTANT("U_INVALID_SKIP", ZEND_FROM_U_ERROR_SKIP, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_MAIN_LONG_CONSTANT("U_INVALID_SUBSTITUTE", ZEND_FROM_U_ERROR_SUBST, CONST_PERSISTENT | CONST_CS);
|
||||
REGISTER_MAIN_LONG_CONSTANT("U_INVALID_ESCAPE", ZEND_FROM_U_ERROR_ESCAPE, CONST_PERSISTENT | CONST_CS);
|
||||
|
||||
/* true/false constants */
|
||||
{
|
||||
zend_constant c;
|
||||
@ -215,13 +220,15 @@ ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC
|
||||
int retval = 1;
|
||||
char *lookup_name;
|
||||
char *colon;
|
||||
zend_uchar type = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
if ((colon = memchr(name, ':', name_len)) && colon[1] == ':') {
|
||||
if ((UG(unicode) && (colon = (char*)u_memchr((UChar*)name, ':', name_len)) && ((UChar*)colon)[1] == ':') ||
|
||||
(!UG(unicode) && (colon = memchr(name, ':', name_len)) && colon[1] == ':')) {
|
||||
/* class constant */
|
||||
zend_class_entry **ce = NULL, *scope;
|
||||
int class_name_len = colon-name;
|
||||
int class_name_len = UG(unicode)?((colon-name)/sizeof(UChar)):colon-name;
|
||||
int const_name_len = name_len - class_name_len - 2;
|
||||
char *constant_name = colon+2;
|
||||
char *constant_name = colon + (UG(unicode)?UBYTES(2):2);
|
||||
zval **ret_constant;
|
||||
char *class_name;
|
||||
|
||||
@ -231,16 +238,22 @@ ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC
|
||||
scope = CG(active_class_entry);
|
||||
}
|
||||
|
||||
class_name = estrndup(name, class_name_len);
|
||||
if (UG(unicode)) {
|
||||
class_name = (char*)eustrndup((UChar*)name, class_name_len);
|
||||
} else {
|
||||
class_name = estrndup(name, class_name_len);
|
||||
}
|
||||
|
||||
if (class_name_len == sizeof("self")-1 && strcmp(class_name, "self") == 0) {
|
||||
if (class_name_len == sizeof("self")-1 &&
|
||||
ZEND_U_EQUAL(type, class_name, class_name_len, "self", sizeof("self")-1)) {
|
||||
if (scope) {
|
||||
ce = &scope;
|
||||
} else {
|
||||
zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
|
||||
retval = 0;
|
||||
}
|
||||
} else if (class_name_len == sizeof("parent")-1 && strcmp(class_name, "parent") == 0) {
|
||||
} else if (class_name_len == sizeof("parent")-1 &&
|
||||
ZEND_U_EQUAL(type, class_name, class_name_len, "parent", sizeof("parent")-1)) {
|
||||
if (!scope) {
|
||||
zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
|
||||
} else if (!scope->parent) {
|
||||
@ -249,14 +262,14 @@ ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC
|
||||
ce = &scope->parent;
|
||||
}
|
||||
} else {
|
||||
if (zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC) != SUCCESS) {
|
||||
if (zend_u_lookup_class(type, class_name, class_name_len, &ce TSRMLS_CC) != SUCCESS) {
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
efree(class_name);
|
||||
|
||||
if (retval && ce) {
|
||||
if (zend_hash_find(&((*ce)->constants_table), constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) {
|
||||
if (zend_u_hash_find(&((*ce)->constants_table), type, constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) {
|
||||
retval = 0;
|
||||
}
|
||||
} else {
|
||||
@ -272,12 +285,13 @@ ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c) == FAILURE) {
|
||||
lookup_name = estrndup(name, name_len);
|
||||
zend_str_tolower(lookup_name, name_len);
|
||||
if (zend_u_hash_find(EG(zend_constants), type, name, name_len+1, (void **) &c) == FAILURE) {
|
||||
int lookup_name_len;
|
||||
|
||||
lookup_name = zend_u_str_case_fold(type, name, name_len, 1, &lookup_name_len);
|
||||
|
||||
if (zend_hash_find(EG(zend_constants), lookup_name, name_len+1, (void **) &c)==SUCCESS) {
|
||||
if ((c->flags & CONST_CS) && memcmp(c->name, name, name_len)!=0) {
|
||||
if (zend_u_hash_find(EG(zend_constants), type, lookup_name, lookup_name_len+1, (void **) &c)==SUCCESS) {
|
||||
if ((c->flags & CONST_CS) && memcmp(c->name, name, UG(unicode)?UBYTES(name_len):name_len)!=0) {
|
||||
retval=0;
|
||||
}
|
||||
} else {
|
||||
@ -297,9 +311,10 @@ ZEND_API int zend_get_constant(char *name, uint name_len, zval *result TSRMLS_DC
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
|
||||
ZEND_API int zend_u_register_constant(zend_uchar type, zend_constant *c TSRMLS_DC)
|
||||
{
|
||||
char *lowercase_name = NULL;
|
||||
int lookup_name_len;
|
||||
char *lookup_name = NULL;
|
||||
char *name;
|
||||
int ret = SUCCESS;
|
||||
|
||||
@ -309,14 +324,14 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
|
||||
|
||||
if (!(c->flags & CONST_CS)) {
|
||||
/* keep in mind that c->name_len already contains the '\0' */
|
||||
lowercase_name = estrndup(c->name, c->name_len);
|
||||
zend_str_tolower(lowercase_name, c->name_len);
|
||||
name = lowercase_name;
|
||||
name = lookup_name = zend_u_str_case_fold(type, c->name, c->name_len-1, 1, &lookup_name_len);
|
||||
lookup_name_len++;
|
||||
} else {
|
||||
lookup_name_len = c->name_len;
|
||||
name = c->name;
|
||||
}
|
||||
|
||||
if (zend_hash_add(EG(zend_constants), name, c->name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
|
||||
if (zend_u_hash_add(EG(zend_constants), type, name, lookup_name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
|
||||
zend_error(E_NOTICE,"Constant %s already defined", name);
|
||||
free(c->name);
|
||||
if (!(c->flags & CONST_PERSISTENT)) {
|
||||
@ -324,13 +339,16 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
|
||||
}
|
||||
ret = FAILURE;
|
||||
}
|
||||
if (lowercase_name) {
|
||||
efree(lowercase_name);
|
||||
if (lookup_name) {
|
||||
efree(lookup_name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
|
||||
{
|
||||
return zend_u_register_constant(IS_STRING, c TSRMLS_CC);
|
||||
}
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -60,6 +60,7 @@ ZEND_API void zend_register_double_constant(char *name, uint name_len, double dv
|
||||
ZEND_API void zend_register_string_constant(char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API void zend_register_stringl_constant(char *name, uint name_len, char *strval, uint strlen, int flags, int module_number TSRMLS_DC);
|
||||
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC);
|
||||
ZEND_API int zend_u_register_constant(zend_uchar type, zend_constant *c TSRMLS_DC);
|
||||
void zend_copy_constants(HashTable *target, HashTable *sourc);
|
||||
void copy_zend_constant(zend_constant *c);
|
||||
END_EXTERN_C()
|
||||
|
@ -86,7 +86,7 @@ static zend_object_value zend_default_exception_new_ex(zend_class_entry *class_t
|
||||
obj.value.obj.handlers = &default_exception_handlers;
|
||||
|
||||
ALLOC_HASHTABLE(object->properties);
|
||||
zend_hash_init(object->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(object->properties, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
zend_hash_copy(object->properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
|
||||
ALLOC_ZVAL(trace);
|
||||
@ -474,8 +474,8 @@ ZEND_METHOD(exception, __toString)
|
||||
_default_exception_get_entry(getThis(), "file", sizeof("file")-1, &file TSRMLS_CC);
|
||||
_default_exception_get_entry(getThis(), "line", sizeof("line")-1, &line TSRMLS_CC);
|
||||
|
||||
convert_to_string(&message);
|
||||
convert_to_string(&file);
|
||||
convert_to_text(&message);
|
||||
convert_to_text(&file);
|
||||
convert_to_long(&line);
|
||||
|
||||
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 0);
|
||||
@ -492,16 +492,16 @@ ZEND_METHOD(exception, __toString)
|
||||
|
||||
zend_call_function(&fci, NULL TSRMLS_CC);
|
||||
|
||||
if (Z_TYPE_P(trace) != IS_STRING) {
|
||||
if (Z_TYPE_P(trace) != IS_STRING && Z_TYPE_P(trace) != IS_UNICODE) {
|
||||
trace = NULL;
|
||||
}
|
||||
|
||||
if (Z_STRLEN(message) > 0) {
|
||||
len = zend_spprintf(&str, 0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s",
|
||||
Z_OBJCE_P(getThis())->name, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
|
||||
if (Z_UNILEN(message) > 0) {
|
||||
len = zend_spprintf(&str, 0, "exception '%v' with message '%R' in %s:%ld\nStack trace:\n%s",
|
||||
Z_OBJCE_P(getThis())->name, Z_TYPE(message), Z_UNIVAL(message), Z_STRVAL(file), Z_LVAL(line),
|
||||
(trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n");
|
||||
} else {
|
||||
len = zend_spprintf(&str, 0, "exception '%s' in %s:%ld\nStack trace:\n%s",
|
||||
len = zend_spprintf(&str, 0, "exception '%v' in %s:%ld\nStack trace:\n%s",
|
||||
Z_OBJCE_P(getThis())->name, Z_STRVAL(file), Z_LVAL(line),
|
||||
(trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n");
|
||||
}
|
||||
@ -670,7 +670,7 @@ ZEND_API void zend_exception_error(zval *exception TSRMLS_DC)
|
||||
zend_call_method_with_0_params(&exception, ce_exception, NULL, "__tostring", &str);
|
||||
if (!EG(exception)) {
|
||||
if (Z_TYPE_P(str) != IS_STRING) {
|
||||
zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name);
|
||||
zend_error(E_WARNING, "%v::__toString() must return a string", ce_exception->name);
|
||||
} else {
|
||||
zend_update_property_string(default_exception_ce, exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name : Z_STRVAL_P(str) TSRMLS_CC);
|
||||
}
|
||||
@ -686,7 +686,7 @@ ZEND_API void zend_exception_error(zval *exception TSRMLS_DC)
|
||||
file = NULL;
|
||||
line = NULL;
|
||||
}
|
||||
zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %s in exception handling during call to %s::__tostring()", Z_OBJCE_P(EG(exception))->name, ce_exception->name);
|
||||
zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %v in exception handling during call to %v::__tostring()", Z_OBJCE_P(EG(exception))->name, ce_exception->name);
|
||||
}
|
||||
|
||||
str = zend_read_property(default_exception_ce, exception, "string", sizeof("string")-1, 1 TSRMLS_CC);
|
||||
@ -695,7 +695,7 @@ ZEND_API void zend_exception_error(zval *exception TSRMLS_DC)
|
||||
|
||||
zend_error_va(E_ERROR, Z_STRVAL_P(file), Z_LVAL_P(line), "Uncaught %s\n thrown", Z_STRVAL_P(str));
|
||||
} else {
|
||||
zend_error(E_ERROR, "Uncaught exception '%s'", ce_exception->name);
|
||||
zend_error(E_ERROR, "Uncaught exception '%v'", ce_exception->name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -716,6 +716,12 @@ ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC)
|
||||
zend_throw_exception_internal(exception TSRMLS_CC);
|
||||
}
|
||||
|
||||
void init_exceptions(TSRMLS_D)
|
||||
{
|
||||
default_exception_ce = zend_get_named_class_entry("Exception", sizeof("Exception")-1 TSRMLS_CC);
|
||||
error_exception_ce = zend_get_named_class_entry("ErrorException", sizeof("ErrorException")-1 TSRMLS_CC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -48,6 +48,8 @@ extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
|
||||
/* show an exception using zend_error(E_ERROR,...) */
|
||||
ZEND_API void zend_exception_error(zval *exception TSRMLS_DC);
|
||||
|
||||
void init_exceptions(TSRMLS_D);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "zend_ini.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "zend_vm.h"
|
||||
#include "zend_unicode.h"
|
||||
|
||||
#define _CONST_CODE 0
|
||||
#define _TMP_CODE 1
|
||||
@ -148,12 +149,12 @@ ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data
|
||||
return execute_data_ptr->CVs[var];
|
||||
}
|
||||
|
||||
static inline void zend_get_cv_address(zend_compiled_variable *cv, zval ***ptr, temp_variable *Ts TSRMLS_DC)
|
||||
static inline void zend_get_cv_address(zend_uchar utype, zend_compiled_variable *cv, zval ***ptr, temp_variable *Ts TSRMLS_DC)
|
||||
{
|
||||
zval *new_zval = &EG(uninitialized_zval);
|
||||
zval *new_zval = &EG(uninitialized_zval);
|
||||
|
||||
new_zval->refcount++;
|
||||
zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &new_zval, sizeof(zval *), (void **)ptr);
|
||||
new_zval->refcount++;
|
||||
zend_u_hash_quick_update(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, &new_zval, sizeof(zval *), (void **)ptr);
|
||||
}
|
||||
|
||||
static inline zval *_get_zval_ptr_tmp(znode *node, temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
|
||||
@ -163,35 +164,53 @@ static inline zval *_get_zval_ptr_tmp(znode *node, temp_variable *Ts, zend_free_
|
||||
|
||||
static inline zval *_get_zval_ptr_var(znode *node, temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
|
||||
{
|
||||
zval *ptr = T(node->u.var).var.ptr;
|
||||
if (ptr) {
|
||||
PZVAL_UNLOCK(ptr, should_free);
|
||||
return ptr;
|
||||
if (T(node->u.var).var.ptr) {
|
||||
PZVAL_UNLOCK(T(node->u.var).var.ptr, should_free);
|
||||
return T(node->u.var).var.ptr;
|
||||
} else {
|
||||
temp_variable *T = &T(node->u.var);
|
||||
zval *str = T->str_offset.str;
|
||||
zval *ptr;
|
||||
|
||||
/* string offset */
|
||||
ALLOC_ZVAL(ptr);
|
||||
T->str_offset.ptr = ptr;
|
||||
should_free->var = ptr;
|
||||
|
||||
if (T->str_offset.str->type != IS_STRING
|
||||
|| ((int)T->str_offset.offset<0)
|
||||
|| (T->str_offset.str->value.str.len <= T->str_offset.offset)) {
|
||||
zend_error(E_NOTICE, "Uninitialized string offset: %d", T->str_offset.offset);
|
||||
ptr->value.str.val = STR_EMPTY_ALLOC();
|
||||
ptr->value.str.len = 0;
|
||||
} else {
|
||||
char c = str->value.str.val[T->str_offset.offset];
|
||||
/* T->str_offset.str here is always IS_STRING or IS_UNICODE */
|
||||
if (T->str_offset.str->type == IS_STRING || T->str_offset.str->type == IS_BINARY) {
|
||||
if (((int)T->str_offset.offset<0)
|
||||
|| (T->str_offset.str->value.str.len <= T->str_offset.offset)) {
|
||||
zend_error(E_NOTICE, "Uninitialized string offset: %d", T->str_offset.offset);
|
||||
ptr->value.str.val = STR_EMPTY_ALLOC();
|
||||
ptr->value.str.len = 0;
|
||||
} else {
|
||||
char c = str->value.str.val[T->str_offset.offset];
|
||||
|
||||
ptr->value.str.val = estrndup(&c, 1);
|
||||
ptr->value.str.len = 1;
|
||||
ptr->value.str.val = estrndup(&c, 1);
|
||||
ptr->value.str.len = 1;
|
||||
}
|
||||
ptr->type = T->str_offset.str->type;
|
||||
} else {
|
||||
if (((int)T->str_offset.offset<0)
|
||||
|| (Z_USTRCPLEN_P(T->str_offset.str) <= T->str_offset.offset)) {
|
||||
zend_error(E_NOTICE, "Uninitialized string offset: %d", T->str_offset.offset);
|
||||
ptr->value.ustr.val = USTR_MAKE("");
|
||||
ptr->value.ustr.len = 0;
|
||||
} else {
|
||||
UChar32 c = zend_get_codepoint_at(str->value.ustr.val, str->value.ustr.len, T->str_offset.offset);
|
||||
int32_t i = 0;
|
||||
|
||||
ptr->value.ustr.val = eumalloc(3); /* potentially 2 code units + null */
|
||||
U16_APPEND_UNSAFE(ptr->value.ustr.val, i, c);
|
||||
ptr->value.ustr.val[i] = 0;
|
||||
ptr->value.ustr.len = i;
|
||||
}
|
||||
ptr->type = IS_UNICODE;
|
||||
}
|
||||
PZVAL_UNLOCK_FREE(str);
|
||||
ptr->refcount=1;
|
||||
ptr->is_ref=1;
|
||||
ptr->type = IS_STRING;
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
@ -202,20 +221,22 @@ static inline zval *_get_zval_ptr_cv(znode *node, temp_variable *Ts, int type TS
|
||||
|
||||
if (!*ptr) {
|
||||
zend_compiled_variable *cv = &CV_DEF_OF(node->u.var);
|
||||
if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
|
||||
zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
if (zend_u_hash_quick_find(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
|
||||
switch (type) {
|
||||
case BP_VAR_R:
|
||||
case BP_VAR_UNSET:
|
||||
zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
|
||||
zend_error(E_NOTICE, "Undefined variable: %v", cv->name);
|
||||
/* break missing intentionally */
|
||||
case BP_VAR_IS:
|
||||
return &EG(uninitialized_zval);
|
||||
break;
|
||||
case BP_VAR_RW:
|
||||
zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
|
||||
zend_error(E_NOTICE, "Undefined variable: %v", cv->name);
|
||||
/* break missing intentionally */
|
||||
case BP_VAR_W:
|
||||
zend_get_cv_address(cv, ptr, Ts TSRMLS_CC);
|
||||
zend_get_cv_address(utype, cv, ptr, Ts TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -270,20 +291,22 @@ static inline zval **_get_zval_ptr_ptr_cv(znode *node, temp_variable *Ts, int ty
|
||||
|
||||
if (!*ptr) {
|
||||
zend_compiled_variable *cv = &CV_DEF_OF(node->u.var);
|
||||
if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
|
||||
zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
if (zend_u_hash_quick_find(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
|
||||
switch (type) {
|
||||
case BP_VAR_R:
|
||||
case BP_VAR_UNSET:
|
||||
zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
|
||||
zend_error(E_NOTICE, "Undefined variable: %v", cv->name);
|
||||
/* break missing intentionally */
|
||||
case BP_VAR_IS:
|
||||
return &EG(uninitialized_zval_ptr);
|
||||
break;
|
||||
case BP_VAR_RW:
|
||||
zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
|
||||
zend_error(E_NOTICE, "Undefined variable: %v", cv->name);
|
||||
/* break missing intentionally */
|
||||
case BP_VAR_W:
|
||||
zend_get_cv_address(cv, ptr, Ts TSRMLS_CC);
|
||||
zend_get_cv_address(utype, cv, ptr, Ts TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -435,7 +458,8 @@ static inline void make_real_object(zval **object_ptr TSRMLS_DC)
|
||||
/* this should modify object only if it's empty */
|
||||
if ((*object_ptr)->type == IS_NULL
|
||||
|| ((*object_ptr)->type == IS_BOOL && (*object_ptr)->value.lval==0)
|
||||
|| ((*object_ptr)->type == IS_STRING && (*object_ptr)->value.str.len == 0)) {
|
||||
|| (((*object_ptr)->type == IS_STRING && (*object_ptr)->type == IS_BINARY) && (*object_ptr)->value.str.len == 0)
|
||||
|| ((*object_ptr)->type == IS_UNICODE && (*object_ptr)->value.ustr.len == 0)) {
|
||||
if (!PZVAL_IS_REF(*object_ptr)) {
|
||||
SEPARATE_ZVAL(object_ptr);
|
||||
}
|
||||
@ -459,9 +483,9 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
|
||||
if (cur_arg_info->class_name) {
|
||||
if (!arg) {
|
||||
if(ptr && ptr->op_array) {
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must be an object of class %s, called in %s on line %d and defined", arg_num, cur_arg_info->class_name, ptr->op_array->filename, ptr->opline->lineno);
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must be an object of class %v, called in %s on line %d and defined", arg_num, cur_arg_info->class_name, ptr->op_array->filename, ptr->opline->lineno);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must be an object of class %s", arg_num, cur_arg_info->class_name);
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must be an object of class %v", arg_num, cur_arg_info->class_name);
|
||||
}
|
||||
}
|
||||
switch (Z_TYPE_P(arg)) {
|
||||
@ -475,7 +499,7 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
|
||||
}
|
||||
break;
|
||||
case IS_OBJECT: {
|
||||
zend_class_entry *ce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
|
||||
zend_class_entry *ce = zend_u_fetch_class(UG(unicode)?IS_UNICODE:IS_STRING, cur_arg_info->class_name, cur_arg_info->class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
|
||||
if (!instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
|
||||
char *error_msg;
|
||||
|
||||
@ -485,18 +509,18 @@ static inline void zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zv
|
||||
error_msg = "be an instance of";
|
||||
}
|
||||
if(ptr && ptr->op_array) {
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must %s %s, called in %s on line %d and defined", arg_num, error_msg, ce->name, ptr->op_array->filename, ptr->opline->lineno);
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must %s %v, called in %s on line %d and defined", arg_num, error_msg, ce->name, ptr->op_array->filename, ptr->opline->lineno);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must %s %s", arg_num, error_msg, ce->name);
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must %s %v", arg_num, error_msg, ce->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(ptr && ptr->op_array) {
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must be an object of class %s, called in %s on line %d and defined", arg_num, cur_arg_info->class_name, ptr->op_array->filename, ptr->opline->lineno);
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must be an object of class %v, called in %s on line %d and defined", arg_num, cur_arg_info->class_name, ptr->op_array->filename, ptr->opline->lineno);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must be an object of class %s", arg_num, cur_arg_info->class_name);
|
||||
zend_error_noreturn(E_ERROR, "Argument %d must be an object of class %v", arg_num, cur_arg_info->class_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -569,9 +593,9 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode
|
||||
value->refcount = 0;
|
||||
dup = zend_get_object_classname(orig_value, &class_name, &class_name_len TSRMLS_CC);
|
||||
if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", class_name);
|
||||
}
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%v' because of 'zend.ze1_compatibility_mode'", class_name);
|
||||
value->value.obj = Z_OBJ_HANDLER_P(orig_value, clone_obj)(orig_value TSRMLS_CC);
|
||||
if(!dup) {
|
||||
efree(class_name);
|
||||
@ -635,7 +659,12 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
|
||||
if (!variable_ptr_ptr) {
|
||||
temp_variable *T = &T(op1->u.var);
|
||||
|
||||
if (T->str_offset.str->type == IS_STRING) do {
|
||||
if (UG(unicode) && Z_TYPE_P(T->str_offset.str) == IS_STRING && value->type != IS_STRING) {
|
||||
convert_to_unicode(T->str_offset.str);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(T->str_offset.str) == IS_STRING ||
|
||||
Z_TYPE_P(T->str_offset.str) == IS_BINARY) do {
|
||||
zval tmp;
|
||||
zval *final_value = value;
|
||||
|
||||
@ -659,9 +688,9 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
|
||||
T->str_offset.str->value.str.len = T->str_offset.offset+1;
|
||||
}
|
||||
|
||||
if (value->type!=IS_STRING) {
|
||||
if (value->type!=IS_STRING && value->type!=IS_BINARY) {
|
||||
tmp = *value;
|
||||
if (op2->op_type & (IS_VAR|IS_CV)) {
|
||||
if (op2->op_type & (IS_VAR|IS_CV|IS_CONST)) {
|
||||
zval_copy_ctor(&tmp);
|
||||
}
|
||||
convert_to_string(&tmp);
|
||||
@ -686,6 +715,53 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
|
||||
T(result->u.var).var = &T->str_offset.str;
|
||||
*/
|
||||
} while (0);
|
||||
else if (T->str_offset.str->type == IS_UNICODE) do {
|
||||
zval tmp;
|
||||
zval *final_value = value;
|
||||
|
||||
if (((int)T->str_offset.offset < 0)) {
|
||||
zend_error(E_WARNING, "Illegal string offset: %d", T->str_offset.offset);
|
||||
break;
|
||||
}
|
||||
if (T->str_offset.offset >= T->str_offset.str->value.ustr.len) {
|
||||
zend_uint i;
|
||||
|
||||
if (T->str_offset.str->value.ustr.len==0) {
|
||||
USTR_FREE(T->str_offset.str->value.ustr.val);
|
||||
T->str_offset.str->value.ustr.val = eumalloc(T->str_offset.offset+1+1);
|
||||
} else {
|
||||
T->str_offset.str->value.ustr.val = eurealloc(T->str_offset.str->value.ustr.val, T->str_offset.offset+1+1);
|
||||
}
|
||||
for (i=T->str_offset.str->value.ustr.len; i<T->str_offset.offset; i++) {
|
||||
T->str_offset.str->value.ustr.val[i] = 0x20; /* ' ' */
|
||||
}
|
||||
T->str_offset.str->value.ustr.val[T->str_offset.offset+1] = 0;
|
||||
T->str_offset.str->value.ustr.len = T->str_offset.offset+1;
|
||||
}
|
||||
|
||||
if (value->type!=IS_UNICODE) {
|
||||
tmp = *value;
|
||||
if (op2->op_type & (IS_VAR|IS_CV|IS_CONST)) {
|
||||
zval_copy_ctor(&tmp);
|
||||
}
|
||||
convert_to_unicode(&tmp);
|
||||
final_value = &tmp;
|
||||
}
|
||||
|
||||
T->str_offset.str->value.ustr.val[T->str_offset.offset] = final_value->value.ustr.val[0];
|
||||
|
||||
if (op2->op_type == IS_TMP_VAR) {
|
||||
if (final_value == &T(op2->u.var).tmp_var) {
|
||||
/* we can safely free final_value here
|
||||
* because separation is done only
|
||||
* in case op2->op_type == IS_VAR */
|
||||
USTR_FREE(final_value->value.ustr.val);
|
||||
}
|
||||
}
|
||||
if (final_value == &tmp) {
|
||||
zval_dtor(final_value);
|
||||
}
|
||||
} while (0);
|
||||
/* zval_ptr_dtor(&T->str_offset.str); Nuke this line if it doesn't cause a leak */
|
||||
|
||||
/* T(result->u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr); */
|
||||
@ -727,7 +803,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
|
||||
dup = zend_get_object_classname(value, &class_name, &class_name_len TSRMLS_CC);
|
||||
|
||||
if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", class_name);
|
||||
} else if (PZVAL_IS_REF(variable_ptr)) {
|
||||
if (variable_ptr != value) {
|
||||
zend_uint refcount = variable_ptr->refcount;
|
||||
@ -740,7 +816,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
|
||||
*variable_ptr = *value;
|
||||
variable_ptr->refcount = refcount;
|
||||
variable_ptr->is_ref = 1;
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%v' because of 'zend.ze1_compatibility_mode'", class_name);
|
||||
variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
|
||||
if (type != IS_TMP_VAR) {
|
||||
value->refcount--;
|
||||
@ -759,7 +835,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
|
||||
}
|
||||
*variable_ptr = *value;
|
||||
INIT_PZVAL(variable_ptr);
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%v' because of 'zend.ze1_compatibility_mode'", class_name);
|
||||
variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
|
||||
zval_ptr_dtor(&value);
|
||||
}
|
||||
@ -867,14 +943,14 @@ static inline void zend_receive(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
|
||||
dup = zend_get_object_classname(value, &class_name, &class_name_len TSRMLS_CC);
|
||||
|
||||
if (Z_OBJ_HANDLER_P(value, clone_obj) == NULL) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", class_name);
|
||||
} else {
|
||||
variable_ptr->refcount--;
|
||||
ALLOC_ZVAL(variable_ptr);
|
||||
*variable_ptr_ptr = variable_ptr;
|
||||
*variable_ptr = *value;
|
||||
INIT_PZVAL(variable_ptr);
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%v' because of 'zend.ze1_compatibility_mode'", class_name);
|
||||
variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
|
||||
}
|
||||
if (!dup) {
|
||||
@ -925,7 +1001,7 @@ static inline HashTable *zend_get_target_symbol_table(zend_op *opline, temp_vari
|
||||
case ZEND_FETCH_STATIC:
|
||||
if (!EG(active_op_array)->static_variables) {
|
||||
ALLOC_HASHTABLE(EG(active_op_array)->static_variables);
|
||||
zend_hash_init(EG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(EG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
}
|
||||
return EG(active_op_array)->static_variables;
|
||||
break;
|
||||
@ -939,39 +1015,61 @@ static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, zval *dim
|
||||
zval **retval;
|
||||
char *offset_key;
|
||||
int offset_key_length;
|
||||
zend_uchar ztype = dim->type;
|
||||
int free_offset = 0;
|
||||
|
||||
switch (dim->type) {
|
||||
switch (ztype) {
|
||||
case IS_NULL:
|
||||
ztype = IS_STRING;
|
||||
offset_key = "";
|
||||
offset_key_length = 0;
|
||||
offset_key_length = 1;
|
||||
goto fetch_string_dim;
|
||||
case IS_STRING:
|
||||
case IS_BINARY:
|
||||
case IS_UNICODE:
|
||||
|
||||
offset_key = dim->value.str.val;
|
||||
offset_key_length = dim->value.str.len;
|
||||
offset_key = Z_UNIVAL_P(dim);
|
||||
offset_key_length = Z_UNILEN_P(dim)+1;
|
||||
|
||||
fetch_string_dim:
|
||||
if (zend_symtable_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) {
|
||||
if (UG(unicode) && ht == &EG(symbol_table) && ztype == IS_UNICODE) {
|
||||
/* Identifier normalization */
|
||||
UChar *norm;
|
||||
int32_t norm_len;
|
||||
|
||||
if (!zend_normalize_identifier(&norm, &norm_len,
|
||||
(UChar*)offset_key, offset_key_length, 0)) {
|
||||
zend_error(E_WARNING, "Could not normalize identifier: %r", offset_key);
|
||||
} else if ((char*)norm != offset_key) {
|
||||
offset_key = (char*)norm;
|
||||
offset_key_length = norm_len;
|
||||
free_offset = 1;
|
||||
}
|
||||
}
|
||||
if (zend_u_symtable_find(ht, ztype, offset_key, offset_key_length, (void **) &retval) == FAILURE) {
|
||||
switch (type) {
|
||||
case BP_VAR_R:
|
||||
zend_error(E_NOTICE, "Undefined index: %s", offset_key);
|
||||
zend_error(E_NOTICE, "Undefined index: %R", ztype, offset_key);
|
||||
/* break missing intentionally */
|
||||
case BP_VAR_UNSET:
|
||||
case BP_VAR_IS:
|
||||
retval = &EG(uninitialized_zval_ptr);
|
||||
break;
|
||||
case BP_VAR_RW:
|
||||
zend_error(E_NOTICE,"Undefined index: %s", offset_key);
|
||||
zend_error(E_NOTICE,"Undefined index: %R", ztype, offset_key);
|
||||
/* break missing intentionally */
|
||||
case BP_VAR_W: {
|
||||
zval *new_zval = &EG(uninitialized_zval);
|
||||
|
||||
new_zval->refcount++;
|
||||
zend_symtable_update(ht, offset_key, offset_key_length+1, &new_zval, sizeof(zval *), (void **) &retval);
|
||||
zend_u_symtable_update(ht, ztype, offset_key, offset_key_length, &new_zval, sizeof(zval *), (void **) &retval);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (free_offset) {
|
||||
efree(offset_key);
|
||||
}
|
||||
break;
|
||||
case IS_RESOURCE:
|
||||
zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", dim->value.lval, dim->value.lval);
|
||||
@ -1049,7 +1147,8 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
|
||||
|
||||
if (container->type==IS_NULL
|
||||
|| (container->type==IS_BOOL && container->value.lval==0)
|
||||
|| (container->type==IS_STRING && container->value.str.len==0)) {
|
||||
|| ((container->type==IS_STRING || container->type==IS_BINARY) && container->value.str.len==0)
|
||||
|| (container->type==IS_UNICODE && container->value.ustr.len==0)) {
|
||||
switch (type) {
|
||||
case BP_VAR_RW:
|
||||
case BP_VAR_W:
|
||||
@ -1098,6 +1197,8 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_UNICODE:
|
||||
case IS_BINARY:
|
||||
case IS_STRING: {
|
||||
zval tmp;
|
||||
|
||||
@ -1220,7 +1321,8 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
|
||||
/* this should modify object only if it's empty */
|
||||
if (container->type == IS_NULL
|
||||
|| (container->type == IS_BOOL && container->value.lval==0)
|
||||
|| (container->type == IS_STRING && container->value.str.len == 0)) {
|
||||
|| ((container->type==IS_STRING || container->type==IS_BINARY) && container->value.str.len==0)
|
||||
|| (container->type==IS_UNICODE && container->value.ustr.len==0)) {
|
||||
switch (type) {
|
||||
case BP_VAR_RW:
|
||||
case BP_VAR_W:
|
||||
|
@ -65,8 +65,11 @@ static inline void safe_free_zval_ptr_rel(zval *p ZEND_FILE_LINE_DC ZEND_FILE_LI
|
||||
}
|
||||
}
|
||||
ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
|
||||
ZEND_API int zend_u_lookup_class(zend_uchar type, void *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
|
||||
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
|
||||
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
|
||||
ZEND_API int zend_u_eval_string(zend_uchar type, void *str, zval *retval_ptr, char *string_name TSRMLS_DC);
|
||||
ZEND_API int zend_u_eval_string_ex(zend_uchar type, void *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
|
||||
|
||||
static inline int i_zend_is_true(zval *op)
|
||||
{
|
||||
@ -85,6 +88,7 @@ static inline int i_zend_is_true(zval *op)
|
||||
result = (op->value.dval ? 1 : 0);
|
||||
break;
|
||||
case IS_STRING:
|
||||
case IS_BINARY:
|
||||
if (op->value.str.len == 0
|
||||
|| (op->value.str.len==1 && op->value.str.val[0]=='0')) {
|
||||
result = 0;
|
||||
@ -92,6 +96,14 @@ static inline int i_zend_is_true(zval *op)
|
||||
result = 1;
|
||||
}
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
if (op->value.ustr.len == 0
|
||||
|| (op->value.ustr.len==1 && op->value.ustr.val[0]=='0')) {
|
||||
result = 0;
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
result = (zend_hash_num_elements(op->value.ht)?1:0);
|
||||
break;
|
||||
@ -155,6 +167,7 @@ ZEND_API void zend_set_timeout(long seconds);
|
||||
ZEND_API void zend_unset_timeout(TSRMLS_D);
|
||||
ZEND_API void zend_timeout(int dummy);
|
||||
ZEND_API zend_class_entry *zend_fetch_class(char *class_name, uint class_name_len, int fetch_type TSRMLS_DC);
|
||||
ZEND_API zend_class_entry *zend_u_fetch_class(zend_uchar type, void *class_name, uint class_name_len, int fetch_type TSRMLS_DC);
|
||||
void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
@ -172,10 +185,12 @@ void zend_shutdown_timeout_thread();
|
||||
/* The following tries to resolve the classname of a zval of type object.
|
||||
* Since it is slow it should be only used in error messages.
|
||||
*/
|
||||
#define Z_OBJ_CLASS_NAME_P(zval) ((zval) && (zval)->type == IS_OBJECT && Z_OBJ_HT_P(zval)->get_class_entry != NULL && Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC) ? Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC)->name : "")
|
||||
#define Z_OBJ_CLASS_NAME_P(zval) ((zval) && (zval)->type == IS_OBJECT && Z_OBJ_HT_P(zval)->get_class_entry != NULL && Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC) ? Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC)->name : EMPTY_STR)
|
||||
|
||||
ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data_ptr, zend_uint var);
|
||||
|
||||
void init_unicode_strings();
|
||||
|
||||
#define ZEND_USER_OPCODE_CONTINUE 0 /* execute next opcode */
|
||||
#define ZEND_USER_OPCODE_RETURN 1 /* exit from executor (return from function) */
|
||||
#define ZEND_USER_OPCODE_DISPATCH 2 /* call original opcode handler */
|
||||
|
@ -50,6 +50,16 @@ static DWORD timeout_thread_id;
|
||||
static int timeout_thread_initialized=0;
|
||||
#endif
|
||||
|
||||
static UChar u_main[sizeof("main")];
|
||||
static UChar u_return[sizeof("return ")];
|
||||
static UChar u_semicolon[sizeof(" ;")];
|
||||
|
||||
void init_unicode_strings() {
|
||||
u_charsToUChars("main", u_main, sizeof("main"));
|
||||
u_charsToUChars("return ", u_return, sizeof("return "));
|
||||
u_charsToUChars(" ;", u_semicolon, sizeof(" ;"));
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
static void (*original_sigsegv_handler)(int);
|
||||
static void zend_handle_sigsegv(int dummy)
|
||||
@ -143,7 +153,7 @@ void init_executor(TSRMLS_D)
|
||||
zend_ptr_stack_init(&EG(argument_stack));
|
||||
zend_ptr_stack_push(&EG(argument_stack), (void *) NULL);
|
||||
|
||||
zend_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
{
|
||||
zval *globals;
|
||||
|
||||
@ -303,7 +313,7 @@ ZEND_API char *get_active_class_name(char **space TSRMLS_DC)
|
||||
if (space) {
|
||||
*space = "";
|
||||
}
|
||||
return "";
|
||||
return EMPTY_STR;
|
||||
}
|
||||
switch (EG(function_state_ptr)->function->type) {
|
||||
case ZEND_USER_FUNCTION:
|
||||
@ -314,13 +324,13 @@ ZEND_API char *get_active_class_name(char **space TSRMLS_DC)
|
||||
if (space) {
|
||||
*space = ce ? "::" : "";
|
||||
}
|
||||
return ce ? ce->name : "";
|
||||
return ce ? ce->name : EMPTY_STR;
|
||||
}
|
||||
default:
|
||||
if (space) {
|
||||
*space = "";
|
||||
}
|
||||
return "";
|
||||
return EMPTY_STR;
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,6 +346,8 @@ ZEND_API char *get_active_function_name(TSRMLS_D)
|
||||
|
||||
if (function_name) {
|
||||
return function_name;
|
||||
} else if (UG(unicode)) {
|
||||
return (char*) u_main;
|
||||
} else {
|
||||
return "main";
|
||||
}
|
||||
@ -429,11 +441,11 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
|
||||
refcount = p->refcount;
|
||||
is_ref = p->is_ref;
|
||||
|
||||
if (!zend_get_constant(p->value.str.val, p->value.str.len, &const_value TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
|
||||
p->value.str.val,
|
||||
p->value.str.val);
|
||||
p->type = IS_STRING;
|
||||
if (!zend_get_constant(Z_UNIVAL_P(p), Z_UNILEN_P(p), &const_value TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %v - assumed '%v'",
|
||||
Z_UNIVAL_P(p),
|
||||
Z_UNIVAL_P(p));
|
||||
p->type = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
if (!inline_change) {
|
||||
zval_copy_ctor(p);
|
||||
}
|
||||
@ -464,7 +476,7 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
|
||||
continue;
|
||||
}
|
||||
Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX;
|
||||
if (zend_hash_get_current_key_ex(p->value.ht, &str_index, &str_index_len, &num_index, 0, NULL)!=HASH_KEY_IS_STRING) {
|
||||
if (zend_hash_get_current_key_ex(p->value.ht, &str_index, &str_index_len, &num_index, 0, NULL) != (UG(unicode)?HASH_KEY_IS_UNICODE:HASH_KEY_IS_STRING)) {
|
||||
zend_hash_move_forward(p->value.ht);
|
||||
continue;
|
||||
}
|
||||
@ -474,13 +486,25 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (const_value.type == IS_STRING && const_value.value.str.len == str_index_len-1 &&
|
||||
if (UG(unicode)) {
|
||||
if (const_value.type == IS_UNICODE &&
|
||||
const_value.value.ustr.len == str_index_len-1 &&
|
||||
!u_strncmp(Z_USTRVAL(const_value), (UChar*)str_index, str_index_len)) {
|
||||
/* constant value is the same as its name */
|
||||
zval_dtor(&const_value);
|
||||
zend_hash_move_forward(p->value.ht);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (const_value.type == IS_STRING &&
|
||||
const_value.value.str.len == str_index_len-1 &&
|
||||
!strncmp(const_value.value.str.val, str_index, str_index_len)) {
|
||||
/* constant value is the same as its name */
|
||||
zval_dtor(&const_value);
|
||||
zend_hash_move_forward(p->value.ht);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ALLOC_ZVAL(new_val);
|
||||
*new_val = **element;
|
||||
@ -498,13 +522,27 @@ ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC)
|
||||
long lval;
|
||||
double dval;
|
||||
|
||||
if (is_numeric_string(const_value.value.str.val, const_value.value.str.len, &lval, &dval, 0) == IS_LONG) {
|
||||
if (is_numeric_string(Z_STRVAL(const_value), Z_STRLEN(const_value), &lval, &dval, 0) == IS_LONG) {
|
||||
zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_LONG, NULL, 0, lval);
|
||||
} else {
|
||||
zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_STRING, const_value.value.str.val, const_value.value.str.len+1, 0);
|
||||
zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_STRING, Z_STRVAL(const_value), Z_STRLEN(const_value)+1, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_UNICODE: {
|
||||
long lval;
|
||||
double dval;
|
||||
|
||||
if (is_numeric_unicode(Z_USTRVAL(const_value), Z_USTRLEN(const_value), &lval, &dval, 0) == IS_LONG) {
|
||||
zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_LONG, NULL, 0, lval);
|
||||
} else {
|
||||
zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_UNICODE, Z_USTRVAL(const_value), Z_USTRLEN(const_value)+1, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_BINARY:
|
||||
zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_BINARY, Z_STRVAL(const_value), Z_STRLEN(const_value)+1, 0);
|
||||
break;
|
||||
case IS_BOOL:
|
||||
case IS_LONG:
|
||||
zend_hash_update_current_key(p->value.ht, HASH_KEY_IS_LONG, NULL, 0, const_value.value.lval);
|
||||
@ -587,6 +625,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
zval *method_name;
|
||||
zval *params_array;
|
||||
int call_via_handler = 0;
|
||||
char *old_func_name = NULL;
|
||||
|
||||
if (EG(exception)) {
|
||||
return FAILURE; /* we would result in an instable executor otherwise */
|
||||
@ -649,18 +688,23 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
calling_scope = Z_OBJCE_PP(fci->object_pp);
|
||||
fci->function_table = &calling_scope->function_table;
|
||||
EX(object) = *fci->object_pp;
|
||||
} else if (Z_TYPE_PP(fci->object_pp) == IS_STRING) {
|
||||
} else if (Z_TYPE_PP(fci->object_pp) == IS_STRING ||
|
||||
Z_TYPE_PP(fci->object_pp) == IS_UNICODE) {
|
||||
zend_class_entry **ce;
|
||||
int found = FAILURE;
|
||||
|
||||
if (EG(active_op_array) && strcmp(Z_STRVAL_PP(fci->object_pp), "self") == 0) {
|
||||
if (EG(active_op_array) &&
|
||||
Z_UNILEN_PP(fci->object_pp) == sizeof("self")-1 &&
|
||||
ZEND_U_EQUAL(Z_TYPE_PP(fci->object_pp), Z_UNIVAL_PP(fci->object_pp), Z_UNILEN_PP(fci->object_pp), "self", sizeof("self")-1)) {
|
||||
if (!EG(active_op_array)->scope) {
|
||||
zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
|
||||
}
|
||||
ce = &(EG(active_op_array)->scope);
|
||||
found = (*ce != NULL?SUCCESS:FAILURE);
|
||||
fci->object_pp = EG(This)?&EG(This):NULL;
|
||||
} else if (strcmp(Z_STRVAL_PP(fci->object_pp), "parent") == 0 && EG(active_op_array)) {
|
||||
} else if (EG(active_op_array) &&
|
||||
Z_UNILEN_PP(fci->object_pp) == sizeof("parent")-1 &&
|
||||
ZEND_U_EQUAL(Z_TYPE_PP(fci->object_pp), Z_UNIVAL_PP(fci->object_pp), Z_UNILEN_PP(fci->object_pp), "parent", sizeof("parent")-1)) {
|
||||
|
||||
if (!EG(active_op_array)->scope) {
|
||||
zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
|
||||
@ -675,9 +719,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
zend_class_entry *scope;
|
||||
scope = EG(active_op_array) ? EG(active_op_array)->scope : NULL;
|
||||
|
||||
found = zend_lookup_class(Z_STRVAL_PP(fci->object_pp), Z_STRLEN_PP(fci->object_pp), &ce TSRMLS_CC);
|
||||
found = zend_u_lookup_class(Z_TYPE_PP(fci->object_pp), Z_UNIVAL_PP(fci->object_pp), Z_UNILEN_PP(fci->object_pp), &ce TSRMLS_CC);
|
||||
if (found == FAILURE) {
|
||||
zend_error(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(fci->object_pp));
|
||||
zend_error(E_ERROR, "Class '%R' not found", Z_TYPE_PP(fci->object_pp), Z_UNIVAL_PP(fci->object_pp));
|
||||
}
|
||||
if (scope && EG(This) &&
|
||||
instanceof_function(Z_OBJCE_P(EG(This)), scope TSRMLS_CC) &&
|
||||
@ -702,16 +746,24 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
}
|
||||
}
|
||||
|
||||
if (fci->function_name->type!=IS_STRING) {
|
||||
if (fci->function_name->type != IS_STRING &&
|
||||
fci->function_name->type != IS_UNICODE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (UG(unicode) && fci->function_name->type == IS_STRING) {
|
||||
old_func_name = Z_STRVAL_P(fci->function_name);
|
||||
|
||||
Z_STRVAL_P(fci->function_name) = estrndup(Z_STRVAL_P(fci->function_name), Z_STRLEN_P(fci->function_name));
|
||||
convert_to_unicode(fci->function_name);
|
||||
}
|
||||
|
||||
if (fci->object_pp) {
|
||||
if (Z_OBJ_HT_PP(fci->object_pp)->get_method == NULL) {
|
||||
zend_error(E_ERROR, "Object does not support method calls");
|
||||
}
|
||||
EX(function_state).function =
|
||||
Z_OBJ_HT_PP(fci->object_pp)->get_method(fci->object_pp, Z_STRVAL_P(fci->function_name), Z_STRLEN_P(fci->function_name) TSRMLS_CC);
|
||||
Z_OBJ_HT_PP(fci->object_pp)->get_method(fci->object_pp, Z_UNIVAL_P(fci->function_name), Z_UNILEN_P(fci->function_name) TSRMLS_CC);
|
||||
if (EX(function_state).function && calling_scope != EX(function_state).function->common.scope) {
|
||||
char *function_name_lc = zend_str_tolower_dup(Z_STRVAL_P(fci->function_name), Z_STRLEN_P(fci->function_name));
|
||||
if (zend_hash_find(&calling_scope->function_table, function_name_lc, fci->function_name->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
|
||||
@ -721,18 +773,20 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
efree(function_name_lc);
|
||||
}
|
||||
} else if (calling_scope) {
|
||||
char *function_name_lc = zend_str_tolower_dup(Z_STRVAL_P(fci->function_name), Z_STRLEN_P(fci->function_name));
|
||||
unsigned int lcname_len;
|
||||
char *lcname = zend_u_str_case_fold(Z_TYPE_P(fci->function_name), Z_UNIVAL_P(fci->function_name), Z_UNILEN_P(fci->function_name), 1, &lcname_len);
|
||||
|
||||
EX(function_state).function =
|
||||
zend_std_get_static_method(calling_scope, function_name_lc, Z_STRLEN_P(fci->function_name) TSRMLS_CC);
|
||||
efree(function_name_lc);
|
||||
zend_std_get_static_method(calling_scope, lcname, lcname_len TSRMLS_CC);
|
||||
efree(lcname);
|
||||
} else {
|
||||
char *function_name_lc = zend_str_tolower_dup(Z_STRVAL_P(fci->function_name), Z_STRLEN_P(fci->function_name));
|
||||
unsigned int lcname_len;
|
||||
char *lcname = zend_u_str_case_fold(Z_TYPE_P(fci->function_name), Z_UNIVAL_P(fci->function_name), Z_UNILEN_P(fci->function_name), 1, &lcname_len);
|
||||
|
||||
if (zend_hash_find(fci->function_table, function_name_lc, fci->function_name->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
|
||||
if (zend_u_hash_find(fci->function_table, Z_TYPE_P(fci->function_name), lcname, lcname_len+1, (void **) &EX(function_state).function)==FAILURE) {
|
||||
EX(function_state).function = NULL;
|
||||
}
|
||||
efree(function_name_lc);
|
||||
efree(lcname);
|
||||
}
|
||||
|
||||
if (EX(function_state).function == NULL) {
|
||||
@ -846,7 +900,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
} else {
|
||||
severity = E_ERROR;
|
||||
}
|
||||
zend_error(severity, "Non-static method %s::%s() cannot be called statically", calling_scope->name, EX(function_state).function->common.function_name);
|
||||
zend_error(severity, "Non-static method %v::%v() cannot be called statically", calling_scope->name, EX(function_state).function->common.function_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -860,7 +914,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
EG(active_symbol_table) = fci->symbol_table;
|
||||
} else {
|
||||
ALLOC_HASHTABLE(EG(active_symbol_table));
|
||||
zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
}
|
||||
|
||||
original_return_value = EG(return_value_ptr_ptr);
|
||||
@ -902,17 +956,23 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
if (EG(exception)) {
|
||||
zend_throw_exception_internal(NULL TSRMLS_CC);
|
||||
}
|
||||
if (old_func_name) {
|
||||
efree(Z_STRVAL_P(fci->function_name));
|
||||
Z_TYPE_P(fci->function_name) = IS_STRING;
|
||||
Z_STRVAL_P(fci->function_name) = old_func_name;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC)
|
||||
ZEND_API int zend_u_lookup_class(zend_uchar type, void *name, int name_length, zend_class_entry ***ce TSRMLS_DC)
|
||||
{
|
||||
zval **args[1];
|
||||
zval autoload_function;
|
||||
zval *class_name_ptr;
|
||||
zval *retval_ptr;
|
||||
int retval;
|
||||
unsigned int lc_name_len;
|
||||
char *lc_name;
|
||||
zval *exception;
|
||||
char dummy = 1;
|
||||
@ -923,11 +983,10 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
lc_name = do_alloca(name_length + 1);
|
||||
zend_str_tolower_copy(lc_name, name, name_length);
|
||||
lc_name = zend_u_str_case_fold(type, name, name_length, 1, &lc_name_len);
|
||||
|
||||
if (zend_hash_find(EG(class_table), lc_name, name_length+1, (void **) ce) == SUCCESS) {
|
||||
free_alloca(lc_name);
|
||||
if (zend_u_hash_find(EG(class_table), type, lc_name, lc_name_len+1, (void **) ce) == SUCCESS) {
|
||||
efree(lc_name);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -935,17 +994,17 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***
|
||||
* (doesn't impact fuctionality of __autoload()
|
||||
*/
|
||||
if (zend_is_compiling(TSRMLS_C)) {
|
||||
free_alloca(lc_name);
|
||||
efree(lc_name);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (EG(in_autoload) == NULL) {
|
||||
ALLOC_HASHTABLE(EG(in_autoload));
|
||||
zend_hash_init(EG(in_autoload), 0, NULL, NULL, 0);
|
||||
zend_u_hash_init(EG(in_autoload), 0, NULL, NULL, 0, UG(unicode));
|
||||
}
|
||||
|
||||
if (zend_hash_add(EG(in_autoload), lc_name, name_length+1, (void**)&dummy, sizeof(char), NULL) == FAILURE) {
|
||||
free_alloca(lc_name);
|
||||
if (zend_u_hash_add(EG(in_autoload), type, lc_name, lc_name_len+1, (void**)&dummy, sizeof(char), NULL) == FAILURE) {
|
||||
efree(lc_name);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
@ -953,7 +1012,11 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***
|
||||
|
||||
ALLOC_ZVAL(class_name_ptr);
|
||||
INIT_PZVAL(class_name_ptr);
|
||||
ZVAL_STRINGL(class_name_ptr, name, name_length, 1);
|
||||
if (type == IS_UNICODE) {
|
||||
ZVAL_UNICODEL(class_name_ptr, name, name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(class_name_ptr, name, name_length, 1);
|
||||
}
|
||||
|
||||
args[0] = &class_name_ptr;
|
||||
|
||||
@ -979,17 +1042,17 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***
|
||||
|
||||
zval_ptr_dtor(&class_name_ptr);
|
||||
|
||||
zend_hash_del(EG(in_autoload), lc_name, name_length+1);
|
||||
zend_u_hash_del(EG(in_autoload), type, lc_name, lc_name_len+1);
|
||||
|
||||
if (retval == FAILURE) {
|
||||
EG(exception) = exception;
|
||||
free_alloca(lc_name);
|
||||
efree(lc_name);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (EG(exception) && exception) {
|
||||
free_alloca(lc_name);
|
||||
zend_error(E_ERROR, "Function %s(%s) threw an exception of type '%s'", ZEND_AUTOLOAD_FUNC_NAME, name, Z_OBJCE_P(EG(exception))->name);
|
||||
efree(lc_name);
|
||||
zend_error(E_ERROR, "Function %s(%R) threw an exception of type '%v'", ZEND_AUTOLOAD_FUNC_NAME, type, name, Z_OBJCE_P(EG(exception))->name);
|
||||
return FAILURE;
|
||||
}
|
||||
if (!EG(exception)) {
|
||||
@ -997,12 +1060,17 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***
|
||||
zval_ptr_dtor(&retval_ptr);
|
||||
}
|
||||
|
||||
retval = zend_hash_find(EG(class_table), lc_name, name_length + 1, (void **) ce);
|
||||
free_alloca(lc_name);
|
||||
retval = zend_u_hash_find(EG(class_table), type, lc_name, lc_name_len + 1, (void **) ce);
|
||||
efree(lc_name);
|
||||
return retval;
|
||||
}
|
||||
|
||||
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
|
||||
ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC)
|
||||
{
|
||||
return zend_u_lookup_class(IS_STRING, name, name_length, ce TSRMLS_CC);
|
||||
}
|
||||
|
||||
ZEND_API int zend_u_eval_string(zend_uchar type, void *string, zval *retval_ptr, char *string_name TSRMLS_DC)
|
||||
{
|
||||
zval pv;
|
||||
zend_op_array *new_op_array;
|
||||
@ -1011,17 +1079,34 @@ ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSR
|
||||
zend_uchar original_handle_op_arrays;
|
||||
int retval;
|
||||
|
||||
if (retval_ptr) {
|
||||
pv.value.str.len = strlen(str)+sizeof("return ;")-1;
|
||||
pv.value.str.val = emalloc(pv.value.str.len+1);
|
||||
strcpy(pv.value.str.val, "return ");
|
||||
strcat(pv.value.str.val, str);
|
||||
strcat(pv.value.str.val, " ;");
|
||||
if (type == IS_UNICODE) {
|
||||
UChar *str = (UChar*)string;
|
||||
|
||||
if (retval_ptr) {
|
||||
pv.value.ustr.len = u_strlen(str)+sizeof("return ;")-1;
|
||||
pv.value.ustr.val = eumalloc(pv.value.ustr.len+1);
|
||||
u_strcpy(pv.value.ustr.val, u_return);
|
||||
u_strcat(pv.value.ustr.val, str);
|
||||
u_strcat(pv.value.ustr.val, u_semicolon);
|
||||
} else {
|
||||
pv.value.ustr.len = u_strlen(str);
|
||||
pv.value.ustr.val = eustrndup(str, pv.value.str.len);
|
||||
}
|
||||
} else {
|
||||
pv.value.str.len = strlen(str);
|
||||
pv.value.str.val = estrndup(str, pv.value.str.len);
|
||||
char *str = (char*)string;
|
||||
|
||||
if (retval_ptr) {
|
||||
pv.value.str.len = strlen(str)+sizeof("return ;")-1;
|
||||
pv.value.str.val = emalloc(pv.value.str.len+1);
|
||||
strcpy(pv.value.str.val, "return ");
|
||||
strcat(pv.value.str.val, str);
|
||||
strcat(pv.value.str.val, " ;");
|
||||
} else {
|
||||
pv.value.str.len = strlen(str);
|
||||
pv.value.str.val = estrndup(str, pv.value.str.len);
|
||||
}
|
||||
}
|
||||
pv.type = IS_STRING;
|
||||
pv.type = type;
|
||||
|
||||
/*printf("Evaluating '%s'\n", pv.value.str.val);*/
|
||||
|
||||
@ -1068,8 +1153,12 @@ ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSR
|
||||
return retval;
|
||||
}
|
||||
|
||||
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
|
||||
{
|
||||
return zend_u_eval_string(IS_STRING, str, retval_ptr, string_name TSRMLS_CC);
|
||||
}
|
||||
|
||||
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
|
||||
ZEND_API int zend_u_eval_string_ex(zend_uchar type, void *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
|
||||
{
|
||||
int result;
|
||||
|
||||
@ -1081,6 +1170,11 @@ ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name,
|
||||
return result;
|
||||
}
|
||||
|
||||
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC)
|
||||
{
|
||||
return zend_u_eval_string_ex(IS_STRING, str, retval_ptr, string_name, handle_exceptions TSRMLS_CC);
|
||||
}
|
||||
|
||||
|
||||
void execute_new_code(TSRMLS_D)
|
||||
{
|
||||
@ -1324,7 +1418,7 @@ void zend_unset_timeout(TSRMLS_D)
|
||||
}
|
||||
|
||||
|
||||
zend_class_entry *zend_fetch_class(char *class_name, uint class_name_len, int fetch_type TSRMLS_DC)
|
||||
ZEND_API zend_class_entry *zend_u_fetch_class(zend_uchar type, void *class_name, uint class_name_len, int fetch_type TSRMLS_DC)
|
||||
{
|
||||
zend_class_entry **pce;
|
||||
|
||||
@ -1344,7 +1438,7 @@ check_fetch_type:
|
||||
}
|
||||
return EG(scope)->parent;
|
||||
case ZEND_FETCH_CLASS_AUTO: {
|
||||
fetch_type = zend_get_class_fetch_type(class_name, class_name_len);
|
||||
fetch_type = zend_get_class_fetch_type(type, class_name, class_name_len);
|
||||
if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) {
|
||||
goto check_fetch_type;
|
||||
}
|
||||
@ -1352,24 +1446,28 @@ check_fetch_type:
|
||||
break;
|
||||
}
|
||||
|
||||
if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) {
|
||||
if (zend_u_lookup_class(type, class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) {
|
||||
if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
|
||||
zend_error(E_ERROR, "Interface '%s' not found", class_name);
|
||||
zend_error(E_ERROR, "Interface '%R' not found", type, class_name);
|
||||
} else {
|
||||
zend_error(E_ERROR, "Class '%s' not found", class_name);
|
||||
zend_error(E_ERROR, "Class '%R' not found", type, class_name);
|
||||
}
|
||||
}
|
||||
return *pce;
|
||||
}
|
||||
|
||||
zend_class_entry *zend_fetch_class(char *class_name, uint class_name_len, int fetch_type TSRMLS_DC)
|
||||
{
|
||||
return zend_u_fetch_class(IS_STRING, class_name, class_name_len, fetch_type TSRMLS_CC);
|
||||
}
|
||||
|
||||
|
||||
#define MAX_ABSTRACT_INFO_CNT 3
|
||||
#define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
|
||||
#define MAX_ABSTRACT_INFO_FMT "%v%s%v%s"
|
||||
#define DISPLAY_ABSTRACT_FN(idx) \
|
||||
ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \
|
||||
ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : EMPTY_STR, \
|
||||
ai.afn[idx] ? "::" : "", \
|
||||
ai.afn[idx] ? ai.afn[idx]->common.function_name : "", \
|
||||
ai.afn[idx] ? ai.afn[idx]->common.function_name : EMPTY_STR, \
|
||||
ai.afn[idx] && ai.afn[idx+1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "")
|
||||
|
||||
typedef struct _zend_abstract_info {
|
||||
@ -1400,7 +1498,7 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC)
|
||||
zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_abstract_class_function, &ai TSRMLS_CC);
|
||||
|
||||
if (ai.cnt) {
|
||||
zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
|
||||
zend_error(E_ERROR, "Class %v contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
|
||||
ce->name, ai.cnt,
|
||||
ai.cnt > 1 ? "s" : "",
|
||||
DISPLAY_ABSTRACT_FN(0),
|
||||
@ -1425,30 +1523,35 @@ ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC)
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC)
|
||||
ZEND_API int zend_u_delete_global_variable(zend_uchar type, void *name, int name_len TSRMLS_DC)
|
||||
{
|
||||
zend_execute_data *ex;
|
||||
ulong hash_value = zend_inline_hash_func(name, name_len+1);
|
||||
ulong hash_value = zend_u_inline_hash_func(type, name, name_len+1);
|
||||
|
||||
if (zend_hash_quick_exists(&EG(symbol_table), name, name_len+1, hash_value)) {
|
||||
if (zend_u_hash_quick_exists(&EG(symbol_table), type, name, name_len+1, hash_value)) {
|
||||
for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
|
||||
if (ex->symbol_table == &EG(symbol_table)) {
|
||||
int i;
|
||||
for (i = 0; i < ex->op_array->last_var; i++) {
|
||||
if (ex->op_array->vars[i].hash_value == hash_value &&
|
||||
ex->op_array->vars[i].name_len == name_len &&
|
||||
!memcmp(ex->op_array->vars[i].name, name, name_len)) {
|
||||
!memcmp(ex->op_array->vars[i].name, name, type==IS_UNICODE?UBYTES(name_len):name_len)) {
|
||||
ex->CVs[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return zend_hash_del(&EG(symbol_table), name, name_len+1);
|
||||
return zend_u_hash_del(&EG(symbol_table), type, name, name_len+1);
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC)
|
||||
{
|
||||
return zend_u_delete_global_variable(IS_STRING, name, name_len TSRMLS_CC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -5,7 +5,7 @@
|
||||
| Copyright (c) 1998-2005 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
@ -36,9 +36,8 @@
|
||||
#include "zend_objects_API.h"
|
||||
#include "zend_modules.h"
|
||||
|
||||
#ifdef ZEND_MULTIBYTE
|
||||
#include "zend_multibyte.h"
|
||||
#endif /* ZEND_MULTIBYTE */
|
||||
#include <unicode/ucnv.h>
|
||||
#include <unicode/ucol.h>
|
||||
|
||||
/* Define ZTS if you want a thread-safe Zend */
|
||||
/*#undef ZTS*/
|
||||
@ -132,17 +131,16 @@ struct _zend_compiler_globals {
|
||||
char *doc_comment;
|
||||
zend_uint doc_comment_len;
|
||||
|
||||
#ifdef ZEND_MULTIBYTE
|
||||
zend_encoding **script_encoding_list;
|
||||
int script_encoding_list_size;
|
||||
zend_uchar literal_type;
|
||||
|
||||
zend_encoding *internal_encoding;
|
||||
|
||||
/* multibyte utility functions */
|
||||
zend_encoding_detector encoding_detector;
|
||||
zend_encoding_converter encoding_converter;
|
||||
zend_encoding_oddlen encoding_oddlen;
|
||||
#endif /* ZEND_MULTIBYTE */
|
||||
#ifdef ZTS
|
||||
HashTable *global_function_table;
|
||||
HashTable *global_class_table;
|
||||
HashTable *global_auto_globals_table;
|
||||
HashTable *global_u_function_table;
|
||||
HashTable *global_u_class_table;
|
||||
HashTable *global_u_auto_globals_table;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -232,6 +230,11 @@ struct _zend_executor_globals {
|
||||
|
||||
zend_property_info std_property_info;
|
||||
|
||||
#ifdef ZTS
|
||||
HashTable *global_constants_table;
|
||||
HashTable *global_u_constants_table;
|
||||
#endif
|
||||
|
||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||
};
|
||||
|
||||
@ -286,21 +289,31 @@ struct _zend_scanner_globals {
|
||||
int yy_start_stack_depth;
|
||||
int *yy_start_stack;
|
||||
|
||||
#ifdef ZEND_MULTIBYTE
|
||||
/* original (unfiltered) script */
|
||||
char *script_org;
|
||||
int script_org_size;
|
||||
UConverter *input_conv; /* converter for flex input */
|
||||
UConverter *output_conv; /* converter for data from flex output */
|
||||
zend_bool encoding_checked;
|
||||
char* rest_str;
|
||||
int rest_len;
|
||||
};
|
||||
|
||||
/* filtered script */
|
||||
char *script_filtered;
|
||||
int script_filtered_size;
|
||||
struct _zend_unicode_globals {
|
||||
zend_bool unicode; /* indicates whether full Unicode mode is enabled */
|
||||
|
||||
/* input/ouput filters */
|
||||
zend_encoding_filter input_filter;
|
||||
zend_encoding_filter output_filter;
|
||||
zend_encoding *script_encoding;
|
||||
zend_encoding *internal_encoding;
|
||||
#endif /* ZEND_MULTIBYTE */
|
||||
UConverter *fallback_encoding_conv; /* converter for default encoding for IS_STRING type */
|
||||
UConverter *runtime_encoding_conv; /* runtime encoding converter */
|
||||
UConverter *output_encoding_conv; /* output layer converter */
|
||||
UConverter *script_encoding_conv; /* default script encoding converter */
|
||||
UConverter *http_input_encoding_conv;/* http input encoding converter */
|
||||
UConverter *utf8_conv; /* all-purpose UTF-8 converter */
|
||||
|
||||
uint8_t from_u_error_mode;
|
||||
UChar subst_char[3];
|
||||
uint8_t subst_char_len;
|
||||
|
||||
char *default_locale;
|
||||
UCollator *default_collator;
|
||||
|
||||
HashTable flex_compatible;
|
||||
};
|
||||
|
||||
#endif /* ZEND_GLOBALS_H */
|
||||
|
@ -26,6 +26,7 @@ typedef struct _zend_compiler_globals zend_compiler_globals;
|
||||
typedef struct _zend_executor_globals zend_executor_globals;
|
||||
typedef struct _zend_alloc_globals zend_alloc_globals;
|
||||
typedef struct _zend_scanner_globals zend_scanner_globals;
|
||||
typedef struct _zend_unicode_globals zend_unicode_globals;
|
||||
|
||||
/* Compiler */
|
||||
#ifdef ZTS
|
||||
@ -78,6 +79,16 @@ extern ZEND_API zend_scanner_globals ini_scanner_globals;
|
||||
#endif
|
||||
|
||||
|
||||
/* Unicode */
|
||||
#ifdef ZTS
|
||||
# define UG(v) TSRMG(unicode_globals_id, zend_unicode_globals *, v)
|
||||
extern ZEND_API ts_rsrc_id unicode_globals_id;
|
||||
#else
|
||||
# define UG(v) (unicode_globals.v)
|
||||
extern ZEND_API zend_unicode_globals unicode_globals;
|
||||
#endif
|
||||
|
||||
|
||||
/* For limited downwards source compatibility */
|
||||
#define CLS_FETCH()
|
||||
#define ELS_FETCH()
|
||||
|
667
Zend/zend_hash.c
667
Zend/zend_hash.c
File diff suppressed because it is too large
Load Diff
120
Zend/zend_hash.h
120
Zend/zend_hash.h
@ -28,6 +28,8 @@
|
||||
#define HASH_KEY_IS_STRING 1
|
||||
#define HASH_KEY_IS_LONG 2
|
||||
#define HASH_KEY_NON_EXISTANT 3
|
||||
#define HASH_KEY_IS_BINARY 4
|
||||
#define HASH_KEY_IS_UNICODE 5
|
||||
|
||||
#define HASH_UPDATE (1<<0)
|
||||
#define HASH_ADD (1<<1)
|
||||
@ -36,6 +38,10 @@
|
||||
#define HASH_DEL_KEY 0
|
||||
#define HASH_DEL_INDEX 1
|
||||
|
||||
#define REAL_KEY_SIZE(type, nKeyLength) \
|
||||
((type == IS_UNICODE)?UBYTES(nKeyLength):nKeyLength)
|
||||
|
||||
|
||||
typedef ulong (*hash_func_t)(char *arKey, uint nKeyLength);
|
||||
typedef int (*compare_func_t)(const void *, const void * TSRMLS_DC);
|
||||
typedef void (*sort_func_t)(void *, size_t, register size_t, compare_func_t TSRMLS_DC);
|
||||
@ -45,6 +51,14 @@ typedef void (*copy_ctor_param_func_t)(void *pElement, void *pParam);
|
||||
|
||||
struct _hashtable;
|
||||
|
||||
typedef struct _key {
|
||||
zend_uchar type;
|
||||
union {
|
||||
char string[1]; /* Must be last element */
|
||||
UChar unicode[1]; /* Must be last element */
|
||||
} u;
|
||||
} HashKey;
|
||||
|
||||
typedef struct bucket {
|
||||
ulong h; /* Used for numeric indexing */
|
||||
uint nKeyLength;
|
||||
@ -54,7 +68,7 @@ typedef struct bucket {
|
||||
struct bucket *pListLast;
|
||||
struct bucket *pNext;
|
||||
struct bucket *pLast;
|
||||
char arKey[1]; /* Must be last element */
|
||||
HashKey key; /* Must be last element */
|
||||
} Bucket;
|
||||
|
||||
typedef struct _hashtable {
|
||||
@ -68,6 +82,7 @@ typedef struct _hashtable {
|
||||
Bucket **arBuckets;
|
||||
dtor_func_t pDestructor;
|
||||
zend_bool persistent;
|
||||
zend_bool unicode;
|
||||
unsigned char nApplyCount;
|
||||
zend_bool bApplyProtection;
|
||||
#if ZEND_DEBUG
|
||||
@ -77,9 +92,13 @@ typedef struct _hashtable {
|
||||
|
||||
|
||||
typedef struct _zend_hash_key {
|
||||
char *arKey;
|
||||
uint nKeyLength;
|
||||
ulong h;
|
||||
uint nKeyLength;
|
||||
zend_uchar type;
|
||||
union {
|
||||
char *string;
|
||||
UChar *unicode;
|
||||
} u;
|
||||
} zend_hash_key;
|
||||
|
||||
|
||||
@ -91,24 +110,38 @@ BEGIN_EXTERN_C()
|
||||
|
||||
/* startup/shutdown */
|
||||
ZEND_API int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _zend_u_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool unicode ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _zend_hash_init_ex(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _zend_u_hash_init_ex(HashTable *ht, uint nSize, hash_func_t pHashFunction, dtor_func_t pDestructor, zend_bool persistent, zend_bool unicode, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
|
||||
ZEND_API void zend_hash_destroy(HashTable *ht);
|
||||
ZEND_API void zend_hash_clean(HashTable *ht);
|
||||
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) _zend_hash_init((ht), (nSize), (pHashFunction), (pDestructor), (persistent) ZEND_FILE_LINE_CC)
|
||||
#define zend_u_hash_init(ht, nSize, pHashFunction, pDestructor, persistent, unicode) _zend_u_hash_init((ht), (nSize), (pHashFunction), (pDestructor), (persistent), (unicode) ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) _zend_hash_init_ex((ht), (nSize), (pHashFunction), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC)
|
||||
#define zend_u_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, unicode, bApplyProtection) _zend_u_hash_init_ex((ht), (nSize), (pHashFunction), (pDestructor), (persistent), (unicode), (bApplyProtection) ZEND_FILE_LINE_CC)
|
||||
|
||||
/* additions/updates/changes */
|
||||
ZEND_API int _zend_hash_add_or_update(HashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _zend_u_hash_add_or_update(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
|
||||
#define zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
|
||||
_zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
|
||||
#define zend_u_hash_update(ht, type, arKey, nKeyLength, pData, nDataSize, pDest) \
|
||||
_zend_u_hash_add_or_update(ht, type, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
|
||||
_zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
|
||||
#define zend_u_hash_add(ht, type, arKey, nKeyLength, pData, nDataSize, pDest) \
|
||||
_zend_u_hash_add_or_update(ht, type, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
|
||||
|
||||
ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
|
||||
ZEND_API int _zend_u_hash_quick_add_or_update(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
|
||||
#define zend_hash_quick_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
|
||||
_zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
|
||||
#define zend_u_hash_quick_update(ht, type, arKey, nKeyLength, h, pData, nDataSize, pDest) \
|
||||
_zend_u_hash_quick_add_or_update(ht, type, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
|
||||
#define zend_hash_quick_add(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
|
||||
_zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
|
||||
#define zend_u_hash_quick_add(ht, type, arKey, nKeyLength, h, pData, nDataSize, pDest) \
|
||||
_zend_u_hash_quick_add_or_update(ht, type, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
|
||||
|
||||
ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
|
||||
#define zend_hash_index_update(ht, h, pData, nDataSize, pDest) \
|
||||
@ -117,6 +150,7 @@ ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void
|
||||
_zend_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
|
||||
|
||||
ZEND_API int zend_hash_add_empty_element(HashTable *ht, char *arKey, uint nKeyLength);
|
||||
ZEND_API int zend_u_hash_add_empty_element(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength);
|
||||
|
||||
|
||||
#define ZEND_HASH_APPLY_KEEP 0
|
||||
@ -145,21 +179,29 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSR
|
||||
|
||||
/* Deletes */
|
||||
ZEND_API int zend_hash_del_key_or_index(HashTable *ht, char *arKey, uint nKeyLength, ulong h, int flag);
|
||||
ZEND_API int zend_u_hash_del_key_or_index(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength, ulong h, int flag);
|
||||
#define zend_hash_del(ht, arKey, nKeyLength) \
|
||||
zend_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
|
||||
#define zend_u_hash_del(ht, type, arKey, nKeyLength) \
|
||||
zend_u_hash_del_key_or_index(ht, type, arKey, nKeyLength, 0, HASH_DEL_KEY)
|
||||
#define zend_hash_index_del(ht, h) \
|
||||
zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)
|
||||
|
||||
ZEND_API ulong zend_get_hash_value(char *arKey, uint nKeyLength);
|
||||
ZEND_API ulong zend_u_get_hash_value(zend_uchar type, char *arKey, uint nKeyLength);
|
||||
|
||||
/* Data retreival */
|
||||
ZEND_API int zend_hash_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData);
|
||||
ZEND_API int zend_u_hash_find(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength, void **pData);
|
||||
ZEND_API int zend_hash_quick_find(HashTable *ht, char *arKey, uint nKeyLength, ulong h, void **pData);
|
||||
ZEND_API int zend_u_hash_quick_find(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength, ulong h, void **pData);
|
||||
ZEND_API int zend_hash_index_find(HashTable *ht, ulong h, void **pData);
|
||||
|
||||
/* Misc */
|
||||
ZEND_API int zend_hash_exists(HashTable *ht, char *arKey, uint nKeyLength);
|
||||
ZEND_API int zend_u_hash_exists(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength);
|
||||
ZEND_API int zend_hash_quick_exists(HashTable *ht, char *arKey, uint nKeyLength, ulong h);
|
||||
ZEND_API int zend_u_hash_quick_exists(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength, ulong h);
|
||||
ZEND_API int zend_hash_index_exists(HashTable *ht, ulong h);
|
||||
ZEND_API ulong zend_hash_next_free_element(HashTable *ht);
|
||||
|
||||
@ -272,8 +314,11 @@ EMPTY_SWITCH_DEFAULT_CASE()
|
||||
return hash;
|
||||
}
|
||||
|
||||
#define zend_u_inline_hash_func(type, arKey, nKeyLength) \
|
||||
zend_inline_hash_func(arKey, REAL_KEY_SIZE(type, nKeyLength))
|
||||
|
||||
ZEND_API ulong zend_hash_func(char *arKey, uint nKeyLength);
|
||||
ZEND_API ulong zend_u_hash_func(zend_uchar type, char *arKey, uint nKeyLength);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* debug */
|
||||
@ -290,68 +335,15 @@ END_EXTERN_C()
|
||||
zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
|
||||
|
||||
|
||||
#define HANDLE_NUMERIC(key, length, func) { \
|
||||
register char *tmp=key; \
|
||||
\
|
||||
if (*tmp=='-') { \
|
||||
tmp++; \
|
||||
} \
|
||||
if ((*tmp>='0' && *tmp<='9')) do { /* possibly a numeric index */ \
|
||||
char *end=key+length-1; \
|
||||
long idx; \
|
||||
\
|
||||
if (*tmp++=='0' && length>2) { /* don't accept numbers with leading zeros */ \
|
||||
break; \
|
||||
} \
|
||||
while (tmp<end) { \
|
||||
if (!(*tmp>='0' && *tmp<='9')) { \
|
||||
break; \
|
||||
} \
|
||||
tmp++; \
|
||||
} \
|
||||
if (tmp==end && *tmp=='\0') { /* a numeric index */ \
|
||||
if (*key=='-') { \
|
||||
idx = strtol(key, NULL, 10); \
|
||||
if (idx!=LONG_MIN) { \
|
||||
return func; \
|
||||
} \
|
||||
} else { \
|
||||
idx = strtol(key, NULL, 10); \
|
||||
if (idx!=LONG_MAX) { \
|
||||
return func; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0); \
|
||||
}
|
||||
ZEND_API int zend_symtable_update(HashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest);
|
||||
ZEND_API int zend_symtable_del(HashTable *ht, char *arKey, uint nKeyLength);
|
||||
ZEND_API int zend_symtable_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData);
|
||||
ZEND_API int zend_symtable_exists(HashTable *ht, char *arKey, uint nKeyLength);
|
||||
|
||||
|
||||
static inline int zend_symtable_update(HashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest) \
|
||||
{
|
||||
HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_update(ht, idx, pData, nDataSize, pDest));
|
||||
return zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest);
|
||||
}
|
||||
|
||||
|
||||
static inline int zend_symtable_del(HashTable *ht, char *arKey, uint nKeyLength)
|
||||
{
|
||||
HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_del(ht, idx))
|
||||
return zend_hash_del(ht, arKey, nKeyLength);
|
||||
}
|
||||
|
||||
|
||||
static inline int zend_symtable_find(HashTable *ht, char *arKey, uint nKeyLength, void **pData)
|
||||
{
|
||||
HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_find(ht, idx, pData));
|
||||
return zend_hash_find(ht, arKey, nKeyLength, pData);
|
||||
}
|
||||
|
||||
|
||||
static inline int zend_symtable_exists(HashTable *ht, char *arKey, uint nKeyLength)
|
||||
{
|
||||
HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx));
|
||||
return zend_hash_exists(ht, arKey, nKeyLength);
|
||||
}
|
||||
ZEND_API int zend_u_symtable_update(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest);
|
||||
ZEND_API int zend_u_symtable_del(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength);
|
||||
ZEND_API int zend_u_symtable_find(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength, void **pData);
|
||||
ZEND_API int zend_u_symtable_exists(HashTable *ht, zend_uchar type, void *arKey, uint nKeyLength);
|
||||
|
||||
#endif /* ZEND_HASH_H */
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "zend_highlight.h"
|
||||
#include "zend_ptr_stack.h"
|
||||
#include "zend_globals.h"
|
||||
#include "zend_operators.h"
|
||||
|
||||
ZEND_API void zend_html_putc(char c)
|
||||
{
|
||||
@ -96,6 +97,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
char *next_color;
|
||||
int in_string=0, post_heredoc = 0;
|
||||
|
||||
CG(literal_type) = IS_STRING;
|
||||
zend_printf("<code>");
|
||||
zend_printf("<span style=\"color: %s\">\n", last_color);
|
||||
/* highlight stuff coming back from zendlex() */
|
||||
@ -119,7 +121,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
case T_CONSTANT_ENCAPSED_STRING:
|
||||
next_color = syntax_highlighter_ini->highlight_string;
|
||||
break;
|
||||
case '"':
|
||||
case '"':
|
||||
next_color = syntax_highlighter_ini->highlight_string;
|
||||
in_string = !in_string;
|
||||
break;
|
||||
@ -162,7 +164,9 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
break;
|
||||
}
|
||||
|
||||
if (token.type == IS_STRING) {
|
||||
if (token.type == IS_STRING ||
|
||||
token.type == IS_BINARY ||
|
||||
token.type == IS_UNICODE) {
|
||||
switch (token_type) {
|
||||
case T_OPEN_TAG:
|
||||
case T_OPEN_TAG_WITH_ECHO:
|
||||
@ -172,11 +176,11 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
case T_DOC_COMMENT:
|
||||
break;
|
||||
default:
|
||||
efree(token.value.str.val);
|
||||
efree(Z_UNIVAL(token));
|
||||
break;
|
||||
}
|
||||
} else if (token_type == T_END_HEREDOC) {
|
||||
efree(token.value.str.val);
|
||||
efree(Z_UNIVAL(token));
|
||||
}
|
||||
token.type = 0;
|
||||
}
|
||||
@ -195,6 +199,7 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
int token_type;
|
||||
int prev_space = 0;
|
||||
|
||||
CG(literal_type) = IS_STRING;
|
||||
token.type = 0;
|
||||
while ((token_type=lex_scan(&token TSRMLS_CC))) {
|
||||
switch (token_type) {
|
||||
@ -218,7 +223,7 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
if (ptr[LANG_SCNG(yy_leng) - 1] == ';') {
|
||||
lex_scan(&token TSRMLS_CC);
|
||||
}
|
||||
efree(token.value.str.val);
|
||||
efree(Z_UNIVAL(token));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -227,7 +232,9 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
break;
|
||||
}
|
||||
|
||||
if (token.type == IS_STRING) {
|
||||
if (token.type == IS_STRING ||
|
||||
token.type == IS_BINARY ||
|
||||
token.type == IS_UNICODE) {
|
||||
switch (token_type) {
|
||||
case T_OPEN_TAG:
|
||||
case T_OPEN_TAG_WITH_ECHO:
|
||||
@ -238,7 +245,7 @@ ZEND_API void zend_strip(TSRMLS_D)
|
||||
break;
|
||||
|
||||
default:
|
||||
efree(token.value.str.val);
|
||||
efree(Z_UNIVAL(token));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,8 @@ static int ini_key_compare(const void *a, const void *b TSRMLS_DC)
|
||||
} else if (s->nKeyLength==0) { /* s is numeric, f is not */
|
||||
return 1;
|
||||
} else { /* both strings */
|
||||
return zend_binary_strcasecmp(f->arKey, f->nKeyLength, s->arKey, s->nKeyLength);
|
||||
/*FIXME: unicode hash*/
|
||||
return zend_binary_strcasecmp(f->key.u.string, f->nKeyLength, s->key.u.string, s->nKeyLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,10 @@ ZEND_API ts_rsrc_id ini_scanner_globals_id;
|
||||
ZEND_API zend_scanner_globals ini_scanner_globals;
|
||||
#endif
|
||||
|
||||
# define YY_INPUT(buf, result, max_size) \
|
||||
if ( ((result = zend_stream_read(yyin, buf, max_size TSRMLS_CC)) == 0) \
|
||||
&& zend_stream_ferror( yyin TSRMLS_CC) ) \
|
||||
YY_FATAL_ERROR( "input in flex scanner failed" );
|
||||
|
||||
static char *ini_filename;
|
||||
|
||||
|
@ -74,7 +74,7 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
|
||||
if (!fn_proxy || !*fn_proxy) {
|
||||
if (zend_hash_find(function_table, function_name, function_name_len+1, (void **) &fcic.function_handler) == FAILURE) {
|
||||
/* error at c-level */
|
||||
zend_error(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
|
||||
zend_error(E_CORE_ERROR, "Couldn't find implementation for method %v%s%s", obj_ce ? obj_ce->name : EMPTY_STR, obj_ce ? "::" : "", function_name);
|
||||
}
|
||||
if (fn_proxy) {
|
||||
*fn_proxy = fcic.function_handler;
|
||||
@ -91,7 +91,7 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
|
||||
if (!obj_ce) {
|
||||
obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
|
||||
}
|
||||
zend_error(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
|
||||
zend_error(E_CORE_ERROR, "Couldn't execute method %v%s%s", obj_ce ? obj_ce->name : EMPTY_STR, obj_ce ? "::" : "", function_name);
|
||||
}
|
||||
if (!retval_ptr_ptr) {
|
||||
if (retval) {
|
||||
@ -195,24 +195,36 @@ static int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_
|
||||
*int_key = 0;
|
||||
if (!EG(exception))
|
||||
{
|
||||
zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name);
|
||||
zend_error(E_WARNING, "Nothing returned from %v::key()", iter->ce->name);
|
||||
}
|
||||
return HASH_KEY_IS_LONG;
|
||||
}
|
||||
switch (retval->type) {
|
||||
default:
|
||||
zend_error(E_WARNING, "Illegal type returned from %s::key()", iter->ce->name);
|
||||
zend_error(E_WARNING, "Illegal type returned from %v::key()", iter->ce->name);
|
||||
case IS_NULL:
|
||||
*int_key = 0;
|
||||
zval_ptr_dtor(&retval);
|
||||
return HASH_KEY_IS_LONG;
|
||||
|
||||
case IS_STRING:
|
||||
*str_key = estrndup(retval->value.str.val, retval->value.str.len);
|
||||
*str_key = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
|
||||
*str_key_len = retval->value.str.len+1;
|
||||
zval_ptr_dtor(&retval);
|
||||
return HASH_KEY_IS_STRING;
|
||||
|
||||
case IS_BINARY:
|
||||
*str_key = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
|
||||
*str_key_len = retval->value.str.len+1;
|
||||
zval_ptr_dtor(&retval);
|
||||
return HASH_KEY_IS_BINARY;
|
||||
|
||||
case IS_UNICODE:
|
||||
*str_key = (char*)eustrndup(Z_USTRVAL_P(retval), Z_USTRLEN_P(retval));
|
||||
*str_key_len = retval->value.str.len+1;
|
||||
zval_ptr_dtor(&retval);
|
||||
return HASH_KEY_IS_UNICODE;
|
||||
|
||||
case IS_DOUBLE:
|
||||
case IS_RESOURCE:
|
||||
case IS_BOOL:
|
||||
@ -286,7 +298,7 @@ static zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce,
|
||||
if (!ce || !ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && iterator == object)) {
|
||||
if (!EG(exception))
|
||||
{
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Objects returned by %s::getIterator() must be traversable or implement interface Iterator", ce->name);
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Objects returned by %v::getIterator() must be traversable or implement interface Iterator", ce->name);
|
||||
}
|
||||
if (iterator)
|
||||
{
|
||||
@ -314,7 +326,7 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
zend_error(E_CORE_ERROR, "Class %s must implement interface %s as part of either %s or %s",
|
||||
zend_error(E_CORE_ERROR, "Class %v must implement interface %v as part of either %v or %v",
|
||||
class_type->name,
|
||||
zend_ce_traversable->name,
|
||||
zend_ce_iterator->name,
|
||||
@ -550,6 +562,14 @@ ZEND_API void zend_register_interfaces(TSRMLS_D)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void init_interfaces(TSRMLS_D)
|
||||
{
|
||||
zend_ce_traversable = zend_get_named_class_entry("Traversable", sizeof("Traversable")-1 TSRMLS_CC);
|
||||
zend_ce_aggregate = zend_get_named_class_entry("IteratorAggregate", sizeof("IteratorAggregate")-1 TSRMLS_CC);
|
||||
zend_ce_iterator = zend_get_named_class_entry("Iterator", sizeof("Iterator")-1 TSRMLS_CC);
|
||||
zend_ce_arrayaccess = zend_get_named_class_entry("ArrayAccess", sizeof("ArrayAccess")-1 TSRMLS_CC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -51,6 +51,8 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
|
||||
|
||||
ZEND_API void zend_register_interfaces(TSRMLS_D);
|
||||
|
||||
void init_interfaces(TSRMLS_D);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif /* ZEND_INTERFACES_H */
|
||||
|
@ -71,7 +71,7 @@
|
||||
%left '*' '/' '%'
|
||||
%right '!'
|
||||
%nonassoc T_INSTANCEOF
|
||||
%right '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
|
||||
%right '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_UNICODE_CAST T_BINARY_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
|
||||
%right '['
|
||||
%nonassoc T_NEW T_CLONE
|
||||
%token T_EXIT
|
||||
@ -145,6 +145,8 @@
|
||||
%token T_DOLLAR_OPEN_CURLY_BRACES
|
||||
%token T_CURLY_OPEN
|
||||
%token T_PAAMAYIM_NEKUDOTAYIM
|
||||
%token T_BINARY_DOUBLE
|
||||
%token T_BINARY_HEREDOC
|
||||
|
||||
%% /* Rules */
|
||||
|
||||
@ -210,7 +212,7 @@ unticked_statement:
|
||||
| T_GLOBAL global_var_list ';'
|
||||
| T_STATIC static_var_list ';'
|
||||
| T_ECHO echo_expr_list ';'
|
||||
| T_INLINE_HTML { zend_do_echo(&$1 TSRMLS_CC); }
|
||||
| T_INLINE_HTML { zend_do_echo(&$1, 1 TSRMLS_CC); }
|
||||
| expr ';' { zend_do_free(&$1 TSRMLS_CC); }
|
||||
| T_USE use_filename ';' { zend_error(E_COMPILE_ERROR,"use: Not yet supported. Please use include_once() or require_once()"); zval_dtor(&$2.u.constant); }
|
||||
| T_UNSET '(' unset_variables ')' ';'
|
||||
@ -466,8 +468,8 @@ global_var_list:
|
||||
|
||||
global_var:
|
||||
T_VARIABLE { $$ = $1; }
|
||||
| '$' r_variable { $$ = $2; }
|
||||
| '$' '{' expr '}' { $$ = $3; }
|
||||
| '$' r_variable { zend_do_normalization(&$$, &$2 TSRMLS_CC); }
|
||||
| '$' '{' expr '}' { zend_do_normalization(&$$, &$3 TSRMLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
@ -536,8 +538,8 @@ class_constant_declaration:
|
||||
;
|
||||
|
||||
echo_expr_list:
|
||||
echo_expr_list ',' expr { zend_do_echo(&$3 TSRMLS_CC); }
|
||||
| expr { zend_do_echo(&$1 TSRMLS_CC); }
|
||||
echo_expr_list ',' expr { zend_do_echo(&$3, 0 TSRMLS_CC); }
|
||||
| expr { zend_do_echo(&$1, 0 TSRMLS_CC); }
|
||||
;
|
||||
|
||||
|
||||
@ -610,6 +612,8 @@ expr_without_variable:
|
||||
| T_INT_CAST expr { zend_do_cast(&$$, &$2, IS_LONG TSRMLS_CC); }
|
||||
| T_DOUBLE_CAST expr { zend_do_cast(&$$, &$2, IS_DOUBLE TSRMLS_CC); }
|
||||
| T_STRING_CAST expr { zend_do_cast(&$$, &$2, IS_STRING TSRMLS_CC); }
|
||||
| T_UNICODE_CAST expr { zend_do_cast(&$$, &$2, IS_UNICODE TSRMLS_CC); }
|
||||
| T_BINARY_CAST expr { zend_do_cast(&$$, &$2, UG(unicode)?IS_BINARY:IS_STRING TSRMLS_CC); }
|
||||
| T_ARRAY_CAST expr { zend_do_cast(&$$, &$2, IS_ARRAY TSRMLS_CC); }
|
||||
| T_OBJECT_CAST expr { zend_do_cast(&$$, &$2, IS_OBJECT TSRMLS_CC); }
|
||||
| T_BOOL_CAST expr { zend_do_cast(&$$, &$2, IS_BOOL TSRMLS_CC); }
|
||||
@ -618,7 +622,7 @@ expr_without_variable:
|
||||
| '@' { zend_do_begin_silence(&$1 TSRMLS_CC); } expr { zend_do_end_silence(&$1 TSRMLS_CC); $$ = $3; }
|
||||
| scalar { $$ = $1; }
|
||||
| T_ARRAY '(' array_pair_list ')' { $$ = $3; }
|
||||
| '`' encaps_list '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
|
||||
| '`' encaps_list '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
|
||||
| T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); }
|
||||
;
|
||||
|
||||
@ -708,9 +712,10 @@ scalar:
|
||||
| T_STRING_VARNAME { $$ = $1; }
|
||||
| class_constant { $$ = $1; }
|
||||
| common_scalar { $$ = $1; }
|
||||
| '"' encaps_list '"' { $$ = $2; }
|
||||
| '\'' encaps_list '\'' { $$ = $2; }
|
||||
| T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; zend_do_end_heredoc(TSRMLS_C); }
|
||||
| '"' { CG(literal_type) = UG(unicode)?IS_UNICODE:IS_STRING; } encaps_list '"' { $$ = $3; }
|
||||
| T_START_HEREDOC { CG(literal_type) = UG(unicode)?IS_UNICODE:IS_STRING; } encaps_list T_END_HEREDOC { $$ = $3; zend_do_end_heredoc(TSRMLS_C); }
|
||||
| T_BINARY_DOUBLE { CG(literal_type) = UG(unicode)?IS_BINARY:IS_STRING; } encaps_list '"' { $$ = $3; }
|
||||
| T_BINARY_HEREDOC { CG(literal_type) = UG(unicode)?IS_BINARY:IS_STRING; } encaps_list T_END_HEREDOC { $$ = $3; zend_do_end_heredoc(TSRMLS_C); }
|
||||
;
|
||||
|
||||
|
||||
@ -808,7 +813,7 @@ reference_variable:
|
||||
|
||||
compound_variable:
|
||||
T_VARIABLE { $$ = $1; }
|
||||
| '$' '{' expr '}' { $$ = $3; }
|
||||
| '$' '{' expr '}' { zend_do_normalization(&$$, &$3 TSRMLS_CC); }
|
||||
;
|
||||
|
||||
dim_offset:
|
||||
@ -830,7 +835,7 @@ object_dim_list:
|
||||
|
||||
variable_name:
|
||||
T_STRING { $$ = $1; }
|
||||
| '{' expr '}' { $$ = $2; }
|
||||
| '{' expr '}' { zend_do_normalization(&$$, &$2 TSRMLS_CC); }
|
||||
;
|
||||
|
||||
simple_indirect_reference:
|
||||
|
@ -29,21 +29,11 @@ typedef struct _zend_lex_state {
|
||||
uint lineno;
|
||||
char *filename;
|
||||
|
||||
#ifdef ZEND_MULTIBYTE
|
||||
/* original (unfiltered) script */
|
||||
char *script_org;
|
||||
int script_org_size;
|
||||
|
||||
/* filtered script */
|
||||
char *script_filtered;
|
||||
int script_filtered_size;
|
||||
|
||||
/* input/ouput filters */
|
||||
zend_encoding_filter input_filter;
|
||||
zend_encoding_filter output_filter;
|
||||
zend_encoding *script_encoding;
|
||||
zend_encoding *internal_encoding;
|
||||
#endif /* ZEND_MULTIBYTE */
|
||||
UConverter *input_conv; /* converter for flex input */
|
||||
UConverter *output_conv; /* converter for data from flex output */
|
||||
zend_bool encoding_checked;
|
||||
char* rest_str;
|
||||
int rest_len;
|
||||
} zend_lex_state;
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -474,7 +474,7 @@ zend_encoding *zend_encoding_table[] = {
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
ZEND_API int zend_multibyte_set_script_encoding(char *encoding_list, int encoding_list_size TSRMLS_DC)
|
||||
{
|
||||
if (CG(script_encoding_list)) {
|
||||
@ -491,11 +491,14 @@ ZEND_API int zend_multibyte_set_script_encoding(char *encoding_list, int encodin
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ZEND_API int zend_multibyte_set_internal_encoding(char *encoding_name, int encoding_name_size TSRMLS_DC)
|
||||
{
|
||||
CG(internal_encoding) = zend_multibyte_fetch_encoding(encoding_name);
|
||||
//CG(internal_encoding) = zend_multibyte_fetch_encoding(encoding_name);
|
||||
//CG(internal_encoding) = zend_multibyte_fetch_encoding(ZEND_INTERNAL_ENCODING);
|
||||
/* set this to NULL so that input filtering is done only when really necessary */
|
||||
CG(internal_encoding) = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -523,17 +526,19 @@ ZEND_API int zend_multibyte_set_filter(zend_encoding *onetime_encoding TSRMLS_DC
|
||||
|
||||
if (!LANG_SCNG(internal_encoding) || LANG_SCNG(script_encoding) == LANG_SCNG(internal_encoding)) {
|
||||
/* if encoding specfic filters exist, use them */
|
||||
/*
|
||||
if (LANG_SCNG(script_encoding)->input_filter && LANG_SCNG(script_encoding)->output_filter) {
|
||||
LANG_SCNG(input_filter) = LANG_SCNG(script_encoding)->input_filter;
|
||||
LANG_SCNG(output_filter) = LANG_SCNG(script_encoding)->output_filter;
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
if (!LANG_SCNG(script_encoding)->compatible) {
|
||||
/* and if not, work around w/ script_encoding -> utf-8 -> script_encoding conversion */
|
||||
LANG_SCNG(internal_encoding) = LANG_SCNG(script_encoding);
|
||||
//LANG_SCNG(internal_encoding) = LANG_SCNG(script_encoding);
|
||||
LANG_SCNG(input_filter) = zend_multibyte_script_encoding_filter;
|
||||
LANG_SCNG(output_filter) = zend_multibyte_internal_encoding_filter;
|
||||
//LANG_SCNG(output_filter) = zend_multibyte_internal_encoding_filter;
|
||||
return 0;
|
||||
} else {
|
||||
/* nothing to do in this case */
|
||||
@ -916,6 +921,7 @@ static char* zend_multibyte_assemble_encoding_list(zend_encoding **encoding_list
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static int zend_multibyte_parse_encoding_list(const char *encoding_list, int encoding_list_size, zend_encoding ***result, int *result_size)
|
||||
{
|
||||
int n, size;
|
||||
@ -982,7 +988,7 @@ static int zend_multibyte_parse_encoding_list(const char *encoding_list, int enc
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static zend_encoding* zend_multibyte_find_script_encoding(zend_encoding *onetime_encoding TSRMLS_DC)
|
||||
{
|
||||
|
@ -220,7 +220,7 @@ ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce
|
||||
if (EG(scope) != ce
|
||||
&& is_derived_class(ce, EG(scope))
|
||||
&& EG(scope)
|
||||
&& zend_hash_quick_find(&EG(scope)->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, h, (void **) &scope_property_info)==SUCCESS
|
||||
&& zend_u_hash_quick_find(&EG(scope)->properties_info, Z_TYPE_P(member), Z_UNIVAL_P(member), Z_UNILEN_P(member)+1, h, (void **) &scope_property_info)==SUCCESS
|
||||
&& scope_property_info->flags & ZEND_ACC_PRIVATE) {
|
||||
return scope_property_info;
|
||||
} else if (property_info) {
|
||||
@ -229,15 +229,15 @@ ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce
|
||||
if (silent) {
|
||||
return NULL;
|
||||
}
|
||||
zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, Z_STRVAL_P(member));
|
||||
zend_error(E_ERROR, "Cannot access %s property %v::$%s", zend_visibility_string(property_info->flags), ce->name, Z_STRVAL_P(member));
|
||||
} else {
|
||||
/* fall through, return property_info... */
|
||||
}
|
||||
} else {
|
||||
EG(std_property_info).flags = ZEND_ACC_PUBLIC;
|
||||
EG(std_property_info).name = Z_STRVAL_P(member);
|
||||
EG(std_property_info).name_length = Z_STRLEN_P(member);
|
||||
EG(std_property_info).h = zend_get_hash_value(EG(std_property_info).name, EG(std_property_info).name_length+1);
|
||||
EG(std_property_info).name = Z_UNIVAL_P(member);
|
||||
EG(std_property_info).name_length = Z_UNILEN_P(member);
|
||||
EG(std_property_info).h = zend_u_get_hash_value(Z_TYPE_P(member), EG(std_property_info).name, EG(std_property_info).name_length+1);
|
||||
property_info = &EG(std_property_info);
|
||||
}
|
||||
return property_info;
|
||||
@ -249,14 +249,19 @@ ZEND_API int zend_check_property_access(zend_object *zobj, char *prop_info_name
|
||||
zend_property_info *property_info;
|
||||
char *class_name, *prop_name;
|
||||
zval member;
|
||||
zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
zend_unmangle_property_name(prop_info_name, &class_name, &prop_name);
|
||||
ZVAL_STRING(&member, prop_name, 0);
|
||||
zend_u_unmangle_property_name(utype, prop_info_name, &class_name, &prop_name);
|
||||
if (utype == IS_UNICODE) {
|
||||
ZVAL_UNICODE(&member, (UChar*)prop_name, 0);
|
||||
} else {
|
||||
ZVAL_STRING(&member, prop_name, 0);
|
||||
}
|
||||
property_info = zend_get_property_info(zobj->ce, &member, 1 TSRMLS_CC);
|
||||
if (!property_info) {
|
||||
return FAILURE;
|
||||
}
|
||||
if (prop_info_name[0] == '\0' && prop_info_name[1] != '*') {
|
||||
if (class_name && class_name[0] != '*') {
|
||||
if (!(property_info->flags & ZEND_ACC_PRIVATE)) {
|
||||
/* we we're looking for a private prop but found a non private one of the same name */
|
||||
return FAILURE;
|
||||
@ -298,7 +303,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC)
|
||||
/* make zend_get_property_info silent if we have getter - we may want to use it */
|
||||
property_info = zend_get_property_info(zobj->ce, member, use_get TSRMLS_CC);
|
||||
|
||||
if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) {
|
||||
if (!property_info || zend_u_hash_quick_find(zobj->properties, Z_TYPE_P(member), property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) {
|
||||
if (use_get) {
|
||||
/* have getter - try with it! */
|
||||
zobj->in_get = 1; /* prevent circular getting */
|
||||
@ -312,7 +317,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC)
|
||||
}
|
||||
} else {
|
||||
if (!silent) {
|
||||
zend_error(E_NOTICE,"Undefined property: %s::$%s", zobj->ce->name, Z_STRVAL_P(member));
|
||||
zend_error(E_NOTICE,"Undefined property: %v::$%s", zobj->ce->name, Z_STRVAL_P(member));
|
||||
}
|
||||
retval = &EG(uninitialized_zval_ptr);
|
||||
}
|
||||
@ -338,18 +343,18 @@ static void zend_std_write_property(zval *object, zval *member, zval *value TSRM
|
||||
zobj = Z_OBJ_P(object);
|
||||
use_set = (zobj->ce->__set && !zobj->in_set);
|
||||
|
||||
if (member->type != IS_STRING) {
|
||||
if (member->type != IS_STRING && member->type != IS_UNICODE) {
|
||||
ALLOC_ZVAL(tmp_member);
|
||||
*tmp_member = *member;
|
||||
INIT_PZVAL(tmp_member);
|
||||
zval_copy_ctor(tmp_member);
|
||||
convert_to_string(tmp_member);
|
||||
convert_to_text(tmp_member);
|
||||
member = tmp_member;
|
||||
}
|
||||
|
||||
property_info = zend_get_property_info(zobj->ce, member, use_set TSRMLS_CC);
|
||||
|
||||
if (property_info && zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &variable_ptr) == SUCCESS) {
|
||||
if (property_info && zend_u_hash_quick_find(zobj->properties, Z_TYPE_P(member), property_info->name, property_info->name_length+1, property_info->h, (void **) &variable_ptr) == SUCCESS) {
|
||||
if (*variable_ptr == value) {
|
||||
/* if we already have this value there, we don't actually need to do anything */
|
||||
setter_done = 1;
|
||||
@ -386,7 +391,7 @@ static void zend_std_write_property(zval *object, zval *member, zval *value TSRM
|
||||
if (PZVAL_IS_REF(value)) {
|
||||
SEPARATE_ZVAL(&value);
|
||||
}
|
||||
zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &value, sizeof(zval *), (void **) &foo);
|
||||
zend_u_hash_quick_update(zobj->properties, Z_TYPE_P(member), property_info->name, property_info->name_length+1, property_info->h, &value, sizeof(zval *), (void **) &foo);
|
||||
}
|
||||
if (tmp_member) {
|
||||
zval_ptr_dtor(&tmp_member);
|
||||
@ -411,7 +416,7 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
|
||||
|
||||
if (!retval) {
|
||||
if (!EG(exception)) {
|
||||
zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name);
|
||||
zend_error(E_ERROR, "Undefined offset for object of type %v used as array", ce->name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -421,7 +426,7 @@ zval *zend_std_read_dimension(zval *object, zval *offset, int type TSRMLS_DC)
|
||||
|
||||
return retval;
|
||||
} else {
|
||||
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);
|
||||
zend_error(E_ERROR, "Cannot use object of type %v as array", ce->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -440,7 +445,7 @@ static void zend_std_write_dimension(zval *object, zval *offset, zval *value TSR
|
||||
zend_call_method_with_2_params(&object, ce, NULL, "offsetset", NULL, offset, value);
|
||||
zval_ptr_dtor(&offset);
|
||||
} else {
|
||||
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);
|
||||
zend_error(E_ERROR, "Cannot use object of type %v as array", ce->name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,7 +474,7 @@ static int zend_std_has_dimension(zval *object, zval *offset, int check_empty TS
|
||||
}
|
||||
zval_ptr_dtor(&offset);
|
||||
} else {
|
||||
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);
|
||||
zend_error(E_ERROR, "Cannot use object of type %v as array", ce->name);
|
||||
return 0;
|
||||
}
|
||||
return result;
|
||||
@ -485,10 +490,10 @@ static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC
|
||||
|
||||
zobj = Z_OBJ_P(object);
|
||||
|
||||
if (member->type != IS_STRING) {
|
||||
if (member->type != IS_STRING && member->type != IS_UNICODE) {
|
||||
tmp_member = *member;
|
||||
zval_copy_ctor(&tmp_member);
|
||||
convert_to_string(&tmp_member);
|
||||
convert_to_text(&tmp_member);
|
||||
member = &tmp_member;
|
||||
}
|
||||
|
||||
@ -498,7 +503,7 @@ static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC
|
||||
|
||||
property_info = zend_get_property_info(zobj->ce, member, 0 TSRMLS_CC);
|
||||
|
||||
if (zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) {
|
||||
if (zend_u_hash_quick_find(zobj->properties, Z_TYPE_P(member), property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) {
|
||||
zval *new_zval;
|
||||
|
||||
if (!zobj->ce->__get && !zobj->ce->__set) {
|
||||
@ -507,7 +512,7 @@ static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC
|
||||
|
||||
/* zend_error(E_NOTICE, "Undefined property: %s", Z_STRVAL_P(member)); */
|
||||
new_zval->refcount++;
|
||||
zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &new_zval, sizeof(zval *), (void **) &retval);
|
||||
zend_u_hash_quick_update(zobj->properties, Z_TYPE_P(member), property_info->name, property_info->name_length+1, property_info->h, &new_zval, sizeof(zval *), (void **) &retval);
|
||||
} else {
|
||||
/* we do have getter - fail and let it try again with usual get/set */
|
||||
retval = NULL;
|
||||
@ -530,18 +535,18 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC)
|
||||
zobj = Z_OBJ_P(object);
|
||||
use_unset = (zobj->ce->__unset && !zobj->in_unset);
|
||||
|
||||
if (member->type != IS_STRING) {
|
||||
if (member->type != IS_STRING && member->type != IS_UNICODE) {
|
||||
ALLOC_ZVAL(tmp_member);
|
||||
*tmp_member = *member;
|
||||
INIT_PZVAL(tmp_member);
|
||||
zval_copy_ctor(tmp_member);
|
||||
convert_to_string(tmp_member);
|
||||
convert_to_text(tmp_member);
|
||||
member = tmp_member;
|
||||
}
|
||||
|
||||
property_info = zend_get_property_info(zobj->ce, member, 0 TSRMLS_CC);
|
||||
|
||||
if (!property_info || zend_hash_del(zobj->properties, property_info->name, property_info->name_length+1) == FAILURE) {
|
||||
if (!property_info || zend_u_hash_del(zobj->properties, Z_TYPE_P(member), property_info->name, property_info->name_length+1)) {
|
||||
if (use_unset) {
|
||||
/* have unseter - try with it! */
|
||||
zobj->in_unset = 1; /* prevent circular unsetting */
|
||||
@ -565,7 +570,7 @@ static void zend_std_unset_dimension(zval *object, zval *offset TSRMLS_DC)
|
||||
zend_call_method_with_1_params(&object, ce, NULL, "offsetunset", NULL, offset);
|
||||
zval_ptr_dtor(&offset);
|
||||
} else {
|
||||
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name);
|
||||
zend_error(E_ERROR, "Cannot use object of type %v as array", ce->name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -589,7 +594,11 @@ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS)
|
||||
|
||||
ALLOC_ZVAL(method_name_ptr);
|
||||
INIT_PZVAL(method_name_ptr);
|
||||
ZVAL_STRING(method_name_ptr, func->function_name, 0); /* no dup - it's a copy */
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(method_name_ptr, (UChar*)func->function_name, 0); /* no dup - it's a copy */
|
||||
} else {
|
||||
ZVAL_STRING(method_name_ptr, func->function_name, 0); /* no dup - it's a copy */
|
||||
}
|
||||
|
||||
/* __call handler is called with two arguments:
|
||||
method name
|
||||
@ -640,7 +649,7 @@ static inline zend_function *zend_check_private_int(zend_function *fbc, zend_cla
|
||||
ce = ce->parent;
|
||||
while (ce) {
|
||||
if (ce == EG(scope)) {
|
||||
if (zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen+1, (void **) &fbc)==SUCCESS
|
||||
if (zend_u_hash_find(&ce->function_table, UG(unicode)?IS_UNICODE:IS_STRING, function_name_strval, function_name_strlen+1, (void **) &fbc)==SUCCESS
|
||||
&& fbc->op_array.fn_flags & ZEND_ACC_PRIVATE
|
||||
&& fbc->common.scope == EG(scope)) {
|
||||
return fbc;
|
||||
@ -692,16 +701,19 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
|
||||
{
|
||||
zend_object *zobj;
|
||||
zend_function *fbc;
|
||||
unsigned int lc_method_name_len;
|
||||
char *lc_method_name;
|
||||
zval *object = *object_ptr;
|
||||
|
||||
lc_method_name = do_alloca(method_len+1);
|
||||
/* FIXME: type is default */
|
||||
zend_uchar type = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
/* Create a zend_copy_str_tolower(dest, src, src_length); */
|
||||
zend_str_tolower_copy(lc_method_name, method_name, method_len);
|
||||
lc_method_name = zend_u_str_case_fold(type, method_name, method_len, 1, &lc_method_name_len);
|
||||
|
||||
zobj = Z_OBJ_P(object);
|
||||
if (zend_hash_find(&zobj->ce->function_table, lc_method_name, method_len+1, (void **)&fbc) == FAILURE) {
|
||||
free_alloca(lc_method_name);
|
||||
if (zend_u_hash_find(&zobj->ce->function_table, type, lc_method_name, lc_method_name_len+1, (void **)&fbc) == FAILURE) {
|
||||
efree(lc_method_name);
|
||||
if (zobj->ce->__call) {
|
||||
zend_internal_function *call_user_call = emalloc(sizeof(zend_internal_function));
|
||||
call_user_call->type = ZEND_INTERNAL_FUNCTION;
|
||||
@ -710,7 +722,11 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
|
||||
call_user_call->num_args = 0;
|
||||
call_user_call->scope = zobj->ce;
|
||||
call_user_call->fn_flags = 0;
|
||||
call_user_call->function_name = estrndup(method_name, method_len);
|
||||
if (UG(unicode)) {
|
||||
call_user_call->function_name = (char*)eustrndup((UChar*)method_name, method_len);
|
||||
} else {
|
||||
call_user_call->function_name = estrndup(method_name, method_len);
|
||||
}
|
||||
call_user_call->pass_rest_by_reference = 0;
|
||||
call_user_call->return_reference = ZEND_RETURN_VALUE;
|
||||
|
||||
@ -728,7 +744,7 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
|
||||
if (EG(scope) && fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
|
||||
zend_function *priv_fbc;
|
||||
|
||||
if (zend_hash_find(&EG(scope)->function_table, lc_method_name, method_len+1, (void **) &priv_fbc)==SUCCESS
|
||||
if (zend_u_hash_find(&EG(scope)->function_table, type, lc_method_name, lc_method_name_len+1, (void **) &priv_fbc)==SUCCESS
|
||||
&& priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
|
||||
&& priv_fbc->common.scope == EG(scope)) {
|
||||
fbc = priv_fbc;
|
||||
@ -741,18 +757,18 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
|
||||
*/
|
||||
updated_fbc = zend_check_private_int(fbc, object->value.obj.handlers->get_class_entry(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC);
|
||||
if (!updated_fbc) {
|
||||
zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : "");
|
||||
zend_error(E_ERROR, "Call to %s method %v::%v() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : "");
|
||||
}
|
||||
fbc = updated_fbc;
|
||||
} else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
|
||||
/* Ensure that if we're calling a protected function, we're allowed to do so.
|
||||
*/
|
||||
if (!zend_check_protected(fbc->common.scope, EG(scope))) {
|
||||
zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : "");
|
||||
zend_error(E_ERROR, "Call to %s method %v::%v() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : "");
|
||||
}
|
||||
}
|
||||
|
||||
free_alloca(lc_method_name);
|
||||
efree(lc_method_name);
|
||||
return fbc;
|
||||
}
|
||||
|
||||
@ -761,14 +777,16 @@ static union _zend_function *zend_std_get_method(zval **object_ptr, char *method
|
||||
ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC)
|
||||
{
|
||||
zend_function *fbc;
|
||||
/* FIXME: type is default */
|
||||
zend_uchar type = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
if (zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen+1, (void **) &fbc)==FAILURE) {
|
||||
if (zend_u_hash_find(&ce->function_table, type, function_name_strval, function_name_strlen+1, (void **) &fbc)==FAILURE) {
|
||||
char *class_name = ce->name;
|
||||
|
||||
if (!class_name) {
|
||||
class_name = "";
|
||||
class_name = EMPTY_STR;
|
||||
}
|
||||
zend_error(E_ERROR, "Call to undefined method %s::%s()", class_name, function_name_strval);
|
||||
zend_error(E_ERROR, "Call to undefined method %R::%R()", type, class_name, type, function_name_strval);
|
||||
}
|
||||
if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) {
|
||||
/* No further checks necessary, most common case */
|
||||
@ -779,14 +797,14 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *f
|
||||
*/
|
||||
updated_fbc = zend_check_private_int(fbc, EG(scope), function_name_strval, function_name_strlen TSRMLS_CC);
|
||||
if (!updated_fbc) {
|
||||
zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : "");
|
||||
zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : EMPTY_STR);
|
||||
}
|
||||
fbc = updated_fbc;
|
||||
} else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
|
||||
/* Ensure that if we're calling a protected function, we're allowed to do so.
|
||||
*/
|
||||
if (!zend_check_protected(EG(scope), fbc->common.scope)) {
|
||||
zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : "");
|
||||
zend_error(E_ERROR, "Call to %s method %v::%v() from context '%v'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : EMPTY_STR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -800,8 +818,9 @@ ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *propert
|
||||
zend_class_entry *tmp_ce = ce;
|
||||
zend_property_info *property_info;
|
||||
zend_property_info std_property_info;
|
||||
zend_uchar type = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
if (zend_hash_find(&ce->properties_info, property_name, property_name_len+1, (void **) &property_info)==FAILURE || (property_info->flags & ZEND_ACC_SHADOW)) {
|
||||
if (zend_u_hash_find(&ce->properties_info, type, property_name, property_name_len+1, (void **) &property_info)==FAILURE) {
|
||||
std_property_info.flags = ZEND_ACC_PUBLIC;
|
||||
std_property_info.name = property_name;
|
||||
std_property_info.name_length = property_name_len;
|
||||
@ -810,23 +829,23 @@ ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *propert
|
||||
}
|
||||
|
||||
#if DEBUG_OBJECT_HANDLERS
|
||||
zend_printf("Access type for %s::%s is %s\n", ce->name, property_name, zend_visibility_string(property_info->flags));
|
||||
zend_printf("Access type for %v::%s is %s\n", ce->name, property_name, zend_visibility_string(property_info->flags));
|
||||
#endif
|
||||
|
||||
if (!zend_verify_property_access(property_info, ce TSRMLS_CC)) {
|
||||
if (!silent) {
|
||||
zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, property_name);
|
||||
zend_error(E_ERROR, "Cannot access %s property %v::$%s", zend_visibility_string(property_info->flags), ce->name, property_name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zend_hash_quick_find(tmp_ce->static_members, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval);
|
||||
zend_u_hash_quick_find(tmp_ce->static_members, type, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval);
|
||||
|
||||
if (!retval) {
|
||||
if (silent) {
|
||||
return NULL;
|
||||
} else {
|
||||
zend_error(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name);
|
||||
zend_error(E_ERROR, "Access to undeclared static property: %v::$%s", ce->name, property_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -837,7 +856,7 @@ ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *propert
|
||||
|
||||
ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *property_name, int property_name_len TSRMLS_DC)
|
||||
{
|
||||
zend_error(E_ERROR, "Attempt to unset static property %s::$%s", ce->name, property_name);
|
||||
zend_error(E_ERROR, "Attempt to unset static property %v::$%s", ce->name, property_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -854,13 +873,13 @@ static union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC)
|
||||
/* Ensure that if we're calling a private function, we're allowed to do so.
|
||||
*/
|
||||
if (object->value.obj.handlers->get_class_entry(object TSRMLS_CC) != EG(scope)) {
|
||||
zend_error(E_ERROR, "Call to private %s::%s() from context '%s'", constructor->common.scope->name, constructor->common.function_name, EG(scope) ? EG(scope)->name : "");
|
||||
zend_error(E_ERROR, "Call to private %v::%v() from context '%v'", constructor->common.scope->name, constructor->common.function_name, EG(scope) ? EG(scope)->name : EMPTY_STR);
|
||||
}
|
||||
} else if ((constructor->common.fn_flags & ZEND_ACC_PROTECTED)) {
|
||||
/* Ensure that if we're calling a protected function, we're allowed to do so.
|
||||
*/
|
||||
if (!zend_check_protected(constructor->common.scope, EG(scope))) {
|
||||
zend_error(E_ERROR, "Call to protected %s::%s() from context '%s'", constructor->common.scope->name, constructor->common.function_name, EG(scope) ? EG(scope)->name : "");
|
||||
zend_error(E_ERROR, "Call to protected %v::%v() from context '%v'", constructor->common.scope->name, constructor->common.function_name, EG(scope) ? EG(scope)->name : EMPTY_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -897,12 +916,12 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists
|
||||
zobj = Z_OBJ_P(object);
|
||||
use_isset = (zobj->ce->__isset && !zobj->in_isset);
|
||||
|
||||
if (member->type != IS_STRING) {
|
||||
if (member->type != IS_STRING && member->type != IS_UNICODE) {
|
||||
ALLOC_ZVAL(tmp_member);
|
||||
*tmp_member = *member;
|
||||
INIT_PZVAL(tmp_member);
|
||||
zval_copy_ctor(tmp_member);
|
||||
convert_to_string(tmp_member);
|
||||
convert_to_text(tmp_member);
|
||||
member = tmp_member;
|
||||
}
|
||||
|
||||
@ -912,7 +931,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists
|
||||
|
||||
property_info = zend_get_property_info(zobj->ce, member, 1 TSRMLS_CC);
|
||||
|
||||
if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &value) == FAILURE) {
|
||||
if (!property_info || zend_u_hash_quick_find(zobj->properties, Z_TYPE_P(member), property_info->name, property_info->name_length+1, property_info->h, (void **) &value) == FAILURE) {
|
||||
result = 0;
|
||||
if (use_isset && (has_set_exists != 2)) {
|
||||
zval *rv;
|
||||
@ -979,7 +998,11 @@ int zend_std_object_get_class_name(zval *object, char **class_name, zend_uint *c
|
||||
}
|
||||
|
||||
*class_name_len = ce->name_length;
|
||||
*class_name = estrndup(ce->name, ce->name_length);
|
||||
if (UG(unicode)) {
|
||||
*class_name = (char*)eustrndup((UChar*)ce->name, ce->name_length);
|
||||
} else {
|
||||
*class_name = estrndup(ce->name, ce->name_length);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -989,14 +1012,22 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
|
||||
|
||||
switch (type) {
|
||||
case IS_STRING:
|
||||
case IS_UNICODE:
|
||||
if (!zend_hash_exists(&Z_OBJCE_P(readobj)->function_table, "__tostring", sizeof("__tostring"))) {
|
||||
return FAILURE;
|
||||
}
|
||||
ZVAL_STRING(&fname, "__tostring", 0);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(&fname, USTR_MAKE("__tostring"), 0);
|
||||
} else {
|
||||
ZVAL_STRING(&fname, "__tostring", 0);
|
||||
}
|
||||
if (call_user_function_ex(NULL, &readobj, &fname, &retval, 0, NULL, 0, NULL TSRMLS_CC) == SUCCESS) {
|
||||
if (UG(unicode)) {
|
||||
zval_dtor(&fname);
|
||||
}
|
||||
if (retval) {
|
||||
if (Z_TYPE_P(retval) != IS_STRING) {
|
||||
zend_error(E_ERROR, "Method %s::__toString() must return a string value", Z_OBJCE_P(readobj)->name);
|
||||
if (Z_TYPE_P(retval) != IS_STRING && Z_TYPE_P(retval) != IS_UNICODE) {
|
||||
zend_error(E_ERROR, "Method %v::__toString() must return a string value", Z_OBJCE_P(readobj)->name);
|
||||
}
|
||||
} else {
|
||||
MAKE_STD_ZVAL(retval);
|
||||
@ -1008,6 +1039,9 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
|
||||
zval_ptr_dtor(&retval);
|
||||
return SUCCESS;
|
||||
}
|
||||
if (UG(unicode)) {
|
||||
zval_dtor(&fname);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -42,9 +42,9 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
|
||||
zend_class_entry *ce = object->ce;
|
||||
|
||||
zend_error(EG(in_execution) ? E_ERROR : E_WARNING,
|
||||
"Call to private %s::__destruct() from context '%s'%s",
|
||||
"Call to private %v::__destruct() from context '%v'%s",
|
||||
ce->name,
|
||||
EG(scope) ? EG(scope)->name : "",
|
||||
EG(scope) ? EG(scope)->name : EMPTY_STR,
|
||||
EG(in_execution) ? "" : " during shutdown ignored");
|
||||
return;
|
||||
}
|
||||
@ -55,9 +55,9 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
|
||||
zend_class_entry *ce = object->ce;
|
||||
|
||||
zend_error(EG(in_execution) ? E_ERROR : E_WARNING,
|
||||
"Call to protected %s::__destruct() from context '%s'%s",
|
||||
"Call to protected %v::__destruct() from context '%v'%s",
|
||||
ce->name,
|
||||
EG(scope) ? EG(scope)->name : "",
|
||||
EG(scope) ? EG(scope)->name : EMPTY_STR,
|
||||
EG(in_execution) ? "" : " during shutdown ignored");
|
||||
return;
|
||||
}
|
||||
@ -78,7 +78,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
|
||||
zend_call_method_with_0_params(&obj, object->ce, &object->ce->destructor, ZEND_DESTRUCTOR_FUNC_NAME, NULL);
|
||||
if (old_exception) {
|
||||
if (EG(exception)) {
|
||||
zend_error(E_ERROR, "Ignoring exception from %s::__destruct() while an exception is already active", object->ce->name);
|
||||
zend_error(E_ERROR, "Ignoring exception from %v::__destruct() while an exception is already active", object->ce->name);
|
||||
zval_ptr_dtor(&EG(exception));
|
||||
}
|
||||
EG(exception) = old_exception;
|
||||
@ -167,7 +167,7 @@ ZEND_API zend_object_value zend_objects_clone_obj(zval *zobject TSRMLS_DC)
|
||||
new_obj_val = zend_objects_new(&new_object, old_object->ce TSRMLS_CC);
|
||||
|
||||
ALLOC_HASHTABLE(new_object->properties);
|
||||
zend_hash_init(new_object->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(new_object->properties, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
|
||||
zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
|
||||
|
||||
|
@ -186,7 +186,7 @@ ZEND_API zend_object_value zend_objects_store_clone_obj(zval *zobject TSRMLS_DC)
|
||||
obj = &EG(objects_store).object_buckets[handle].bucket.obj;
|
||||
|
||||
if (obj->clone == NULL) {
|
||||
zend_error(E_CORE_ERROR, "Trying to clone uncloneable object of class %s", Z_OBJCE_P(zobject)->name);
|
||||
zend_error(E_CORE_ERROR, "Trying to clone uncloneable object of class %v", Z_OBJCE_P(zobject)->name);
|
||||
}
|
||||
|
||||
obj->clone(obj->object, &new_object TSRMLS_CC);
|
||||
|
@ -386,9 +386,10 @@ int pass_two(zend_op_array *op_array TSRMLS_DC)
|
||||
|
||||
int print_class(zend_class_entry *class_entry TSRMLS_DC)
|
||||
{
|
||||
printf("Class %s:\n", class_entry->name);
|
||||
/* UTODO: fix these to use spprintf() */
|
||||
printf("Class %v:\n", class_entry->name);
|
||||
zend_hash_apply(&class_entry->function_table, (apply_func_t) pass_two TSRMLS_CC);
|
||||
printf("End of class %s.\n\n", class_entry->name);
|
||||
printf("End of class %v.\n\n", class_entry->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "zend_multiply.h"
|
||||
#include "zend_strtod.h"
|
||||
|
||||
#include "unicode/uchar.h"
|
||||
|
||||
#define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
|
||||
|
||||
ZEND_API int zend_atoi(const char *str, int str_len)
|
||||
@ -111,6 +113,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
|
||||
{
|
||||
switch (op->type) {
|
||||
case IS_STRING:
|
||||
case IS_BINARY:
|
||||
{
|
||||
char *strval;
|
||||
|
||||
@ -127,6 +130,24 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
|
||||
STR_FREE(strval);
|
||||
break;
|
||||
}
|
||||
case IS_UNICODE:
|
||||
{
|
||||
UChar *strval;
|
||||
|
||||
strval = op->value.ustr.val;
|
||||
switch ((op->type=is_numeric_unicode(strval, op->value.ustr.len, &op->value.lval, &op->value.dval, 1))) {
|
||||
case IS_DOUBLE:
|
||||
case IS_LONG:
|
||||
break;
|
||||
default:
|
||||
op->value.lval = zend_u_strtol(op->value.ustr.val, NULL, 10);
|
||||
op->type = IS_LONG;
|
||||
break;
|
||||
}
|
||||
USTR_FREE(strval);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IS_BOOL:
|
||||
op->type = IS_LONG;
|
||||
break;
|
||||
@ -152,6 +173,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
|
||||
} else { \
|
||||
switch ((op)->type) { \
|
||||
case IS_STRING: \
|
||||
case IS_BINARY: \
|
||||
{ \
|
||||
switch (((holder).type=is_numeric_string((op)->value.str.val, (op)->value.str.len, &(holder).value.lval, &(holder).value.dval, 1))) { \
|
||||
case IS_DOUBLE: \
|
||||
@ -165,6 +187,20 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
} \
|
||||
case IS_UNICODE: \
|
||||
{ \
|
||||
switch (((holder).type=is_numeric_unicode((op)->value.ustr.val, (op)->value.ustr.len, &(holder).value.lval, &(holder).value.dval, 1))) { \
|
||||
case IS_DOUBLE: \
|
||||
case IS_LONG: \
|
||||
break; \
|
||||
default: \
|
||||
(holder).value.lval = zend_u_strtol((op)->value.ustr.val, NULL, 10); \
|
||||
(holder).type = IS_LONG; \
|
||||
break; \
|
||||
} \
|
||||
(op) = &(holder); \
|
||||
break; \
|
||||
} \
|
||||
case IS_BOOL: \
|
||||
case IS_RESOURCE: \
|
||||
(holder).value.lval = (op)->value.lval; \
|
||||
@ -202,8 +238,12 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
|
||||
DVAL_TO_LVAL((op)->value.dval, (holder).value.lval); \
|
||||
break; \
|
||||
case IS_STRING: \
|
||||
case IS_BINARY: \
|
||||
(holder).value.lval = strtol((op)->value.str.val, NULL, 10); \
|
||||
break; \
|
||||
case IS_UNICODE: \
|
||||
(holder).value.lval = zend_u_strtol((op)->value.ustr.val, NULL, 10); \
|
||||
break; \
|
||||
case IS_ARRAY: \
|
||||
(holder).value.lval = (zend_hash_num_elements((op)->value.ht)?1:0); \
|
||||
break; \
|
||||
@ -242,6 +282,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
|
||||
(holder).value.lval = ((op)->value.dval ? 1 : 0); \
|
||||
break; \
|
||||
case IS_STRING: \
|
||||
case IS_BINARY: \
|
||||
if ((op)->value.str.len == 0 \
|
||||
|| ((op)->value.str.len==1 && (op)->value.str.val[0]=='0')) { \
|
||||
(holder).value.lval = 0; \
|
||||
@ -249,6 +290,15 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
|
||||
(holder).value.lval = 1; \
|
||||
} \
|
||||
break; \
|
||||
case IS_UNICODE: \
|
||||
if ((op)->value.ustr.len == 0 \
|
||||
|| ((op)->value.ustr.len==1 && \
|
||||
((op)->value.ustr.val[0]=='0'))) { \
|
||||
(holder).value.lval = 0; \
|
||||
} else { \
|
||||
(holder).value.lval = 1; \
|
||||
} \
|
||||
break; \
|
||||
case IS_ARRAY: \
|
||||
(holder).value.lval = (zend_hash_num_elements((op)->value.ht)?1:0); \
|
||||
break; \
|
||||
@ -293,7 +343,6 @@ ZEND_API void convert_to_long(zval *op)
|
||||
|
||||
ZEND_API void convert_to_long_base(zval *op, int base)
|
||||
{
|
||||
char *strval;
|
||||
long tmp;
|
||||
|
||||
switch (op->type) {
|
||||
@ -313,9 +362,19 @@ ZEND_API void convert_to_long_base(zval *op, int base)
|
||||
DVAL_TO_LVAL(op->value.dval, op->value.lval);
|
||||
break;
|
||||
case IS_STRING:
|
||||
strval = op->value.str.val;
|
||||
op->value.lval = strtol(strval, NULL, base);
|
||||
STR_FREE(strval);
|
||||
case IS_BINARY:
|
||||
{
|
||||
char *strval = op->value.str.val;
|
||||
op->value.lval = strtol(strval, NULL, base);
|
||||
STR_FREE(strval);
|
||||
}
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
{
|
||||
UChar *strval = op->value.ustr.val;
|
||||
op->value.lval = zend_u_strtol(strval, NULL, base);
|
||||
USTR_FREE(strval);
|
||||
}
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
tmp = (zend_hash_num_elements(op->value.ht)?1:0);
|
||||
@ -358,7 +417,6 @@ ZEND_API void convert_to_long_base(zval *op, int base)
|
||||
|
||||
ZEND_API void convert_to_double(zval *op)
|
||||
{
|
||||
char *strval;
|
||||
double tmp;
|
||||
|
||||
switch (op->type) {
|
||||
@ -378,10 +436,21 @@ ZEND_API void convert_to_double(zval *op)
|
||||
case IS_DOUBLE:
|
||||
break;
|
||||
case IS_STRING:
|
||||
strval = op->value.str.val;
|
||||
case IS_BINARY:
|
||||
{
|
||||
char *strval = op->value.str.val;
|
||||
|
||||
op->value.dval = zend_strtod(strval, NULL);
|
||||
STR_FREE(strval);
|
||||
op->value.dval = zend_strtod(strval, NULL);
|
||||
STR_FREE(strval);
|
||||
}
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
{
|
||||
UChar *strval = op->value.ustr.val;
|
||||
|
||||
op->value.dval = zend_u_strtod(strval, NULL);
|
||||
USTR_FREE(strval);
|
||||
}
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
tmp = (zend_hash_num_elements(op->value.ht)?1:0);
|
||||
@ -405,7 +474,7 @@ ZEND_API void convert_to_double(zval *op)
|
||||
retval = (zend_hash_num_elements(ht)?1.0:0.0);
|
||||
}
|
||||
} else {
|
||||
zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name);
|
||||
zend_error(E_NOTICE, "Object of class %v could not be converted to double", Z_OBJCE_P(op)->name);
|
||||
}
|
||||
|
||||
zval_dtor(op);
|
||||
@ -440,7 +509,6 @@ ZEND_API void convert_to_null(zval *op)
|
||||
|
||||
ZEND_API void convert_to_boolean(zval *op)
|
||||
{
|
||||
char *strval;
|
||||
int tmp;
|
||||
|
||||
switch (op->type) {
|
||||
@ -462,15 +530,32 @@ ZEND_API void convert_to_boolean(zval *op)
|
||||
op->value.lval = (op->value.dval ? 1 : 0);
|
||||
break;
|
||||
case IS_STRING:
|
||||
strval = op->value.str.val;
|
||||
case IS_BINARY:
|
||||
{
|
||||
char *strval = op->value.str.val;
|
||||
|
||||
if (op->value.str.len == 0
|
||||
|| (op->value.str.len==1 && op->value.str.val[0]=='0')) {
|
||||
op->value.lval = 0;
|
||||
} else {
|
||||
op->value.lval = 1;
|
||||
if (op->value.str.len == 0
|
||||
|| (op->value.str.len==1 && op->value.str.val[0]=='0')) {
|
||||
op->value.lval = 0;
|
||||
} else {
|
||||
op->value.lval = 1;
|
||||
}
|
||||
STR_FREE(strval);
|
||||
}
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
{
|
||||
UChar *strval = op->value.ustr.val;
|
||||
|
||||
if (op->value.ustr.len == 0
|
||||
|| (op->value.ustr.len==1 &&
|
||||
(op->value.ustr.val[0]=='0'))) {
|
||||
op->value.lval = 0;
|
||||
} else {
|
||||
op->value.lval = 1;
|
||||
}
|
||||
USTR_FREE(strval);
|
||||
}
|
||||
STR_FREE(strval);
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
tmp = (zend_hash_num_elements(op->value.ht)?1:0);
|
||||
@ -507,7 +592,94 @@ ZEND_API void convert_to_boolean(zval *op)
|
||||
op->type = IS_BOOL;
|
||||
}
|
||||
|
||||
ZEND_API void _convert_to_unicode(zval *op TSRMLS_DC ZEND_FILE_LINE_DC)
|
||||
{
|
||||
switch (op->type) {
|
||||
case IS_NULL:
|
||||
op->value.ustr.val = USTR_MAKE_REL("");
|
||||
op->value.ustr.len = 0;
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
break;
|
||||
case IS_STRING:
|
||||
zval_string_to_unicode(op TSRMLS_CC);
|
||||
break;
|
||||
case IS_BINARY:
|
||||
zend_error(E_ERROR, "Cannot convert binary type to Unicode type");
|
||||
return;
|
||||
case IS_BOOL:
|
||||
if (op->value.lval) {
|
||||
op->value.ustr.val = USTR_MAKE_REL("1");
|
||||
op->value.ustr.len = 1;
|
||||
} else {
|
||||
op->value.ustr.val = USTR_MAKE_REL("");
|
||||
op->value.ustr.len = 0;
|
||||
}
|
||||
break;
|
||||
case IS_RESOURCE: {
|
||||
long tmp = op->value.lval;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
zend_list_delete(op->value.lval);
|
||||
op->value.ustr.val = eumalloc_rel(sizeof("Resource id #")-1 + MAX_LENGTH_OF_LONG + 1);
|
||||
op->value.ustr.len = u_sprintf(op->value.ustr.val, "Resource id #%ld", tmp);
|
||||
break;
|
||||
}
|
||||
case IS_LONG: {
|
||||
int32_t capacity = MAX_LENGTH_OF_LONG + 1;
|
||||
long lval = op->value.lval;
|
||||
|
||||
op->value.ustr.val = eumalloc_rel(capacity);
|
||||
op->value.ustr.len = u_sprintf(op->value.ustr.val, "%ld", lval);
|
||||
break;
|
||||
}
|
||||
case IS_DOUBLE: {
|
||||
int32_t capacity;
|
||||
double dval = op->value.dval;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
capacity = MAX_LENGTH_OF_DOUBLE + EG(precision) + 1;
|
||||
op->value.ustr.val = eumalloc_rel(capacity);
|
||||
op->value.ustr.len = u_sprintf(op->value.ustr.val, "%.*G", (int) EG(precision), dval);
|
||||
break;
|
||||
}
|
||||
case IS_ARRAY:
|
||||
zend_error(E_NOTICE, "Array to string conversion");
|
||||
zval_dtor(op);
|
||||
op->value.ustr.val = USTR_MAKE_REL("Array");
|
||||
op->value.ustr.len = sizeof("Array")-1;
|
||||
break;
|
||||
case IS_OBJECT: {
|
||||
TSRMLS_FETCH();
|
||||
|
||||
convert_object_to_type(op, IS_UNICODE, convert_to_unicode);
|
||||
|
||||
if (op->type == IS_UNICODE) {
|
||||
return;
|
||||
}
|
||||
|
||||
zend_error(E_NOTICE, "Object of class %v to string conversion", Z_OBJCE_P(op)->name);
|
||||
zval_dtor(op);
|
||||
op->value.ustr.val = USTR_MAKE_REL("Object");
|
||||
op->value.ustr.len = sizeof("Object")-1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
zval_dtor(op);
|
||||
ZVAL_BOOL(op, 0);
|
||||
break;
|
||||
}
|
||||
op->type = IS_UNICODE;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
_convert_to_string_with_converter(op, ZEND_U_CONVERTER(UG(runtime_encoding_conv)) TSRMLS_CC ZEND_FILE_LINE_CC);
|
||||
}
|
||||
|
||||
ZEND_API void _convert_to_string_with_converter(zval *op, UConverter *conv TSRMLS_DC ZEND_FILE_LINE_DC)
|
||||
{
|
||||
long lval;
|
||||
double dval;
|
||||
@ -518,6 +690,26 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC)
|
||||
op->value.str.len = 0;
|
||||
break;
|
||||
case IS_STRING:
|
||||
if (conv == ZEND_U_CONVERTER(UG(runtime_encoding_conv))) {
|
||||
break;
|
||||
} else {
|
||||
char *s;
|
||||
int32_t s_len;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
s = op->value.str.val;
|
||||
s_len = op->value.str.len;
|
||||
zend_convert_encodings(conv, ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &op->value.str.val, &op->value.str.len, s, s_len, &status);
|
||||
efree(s);
|
||||
if (U_FAILURE(status)) {
|
||||
zend_error(E_WARNING, "Error converting string for printing");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IS_BINARY:
|
||||
zend_error(E_ERROR, "Cannot convert binary type to string type");
|
||||
return;
|
||||
case IS_UNICODE:
|
||||
zval_unicode_to_string(op, conv TSRMLS_CC);
|
||||
break;
|
||||
case IS_BOOL:
|
||||
if (op->value.lval) {
|
||||
@ -566,7 +758,7 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC)
|
||||
return;
|
||||
}
|
||||
|
||||
zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name);
|
||||
zend_error(E_NOTICE, "Object of class %v to string conversion", Z_OBJCE_P(op)->name);
|
||||
zval_dtor(op);
|
||||
op->value.str.val = estrndup_rel("Object", sizeof("Object")-1);
|
||||
op->value.str.len = sizeof("Object")-1;
|
||||
@ -580,8 +772,35 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC)
|
||||
op->type = IS_STRING;
|
||||
}
|
||||
|
||||
ZEND_API void convert_to_binary(zval *op)
|
||||
{
|
||||
switch (op->type) {
|
||||
case IS_BINARY:
|
||||
break;
|
||||
case IS_OBJECT: {
|
||||
TSRMLS_FETCH();
|
||||
|
||||
convert_object_to_type(op, IS_BINARY, convert_to_binary);
|
||||
|
||||
static void convert_scalar_to_array(zval *op, int type)
|
||||
if (op->type == IS_BINARY) {
|
||||
return;
|
||||
}
|
||||
|
||||
zend_error(E_NOTICE, "Object of class %v to binary conversion", Z_OBJCE_P(op)->name);
|
||||
zval_dtor(op);
|
||||
op->value.str.val = estrndup("Object", sizeof("Object")-1);
|
||||
op->value.str.len = sizeof("Object")-1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
convert_to_string(op);
|
||||
break;
|
||||
}
|
||||
op->type = IS_BINARY;
|
||||
}
|
||||
|
||||
|
||||
static void convert_scalar_to_array(zval *op, int type TSRMLS_DC)
|
||||
{
|
||||
zval *entry;
|
||||
|
||||
@ -592,7 +811,7 @@ static void convert_scalar_to_array(zval *op, int type)
|
||||
switch (type) {
|
||||
case IS_ARRAY:
|
||||
ALLOC_HASHTABLE(op->value.ht);
|
||||
zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
zend_hash_index_update(op->value.ht, 0, (void *) &entry, sizeof(zval *), NULL);
|
||||
op->type = IS_ARRAY;
|
||||
break;
|
||||
@ -624,7 +843,7 @@ ZEND_API void convert_to_array(zval *op)
|
||||
HashTable *ht;
|
||||
|
||||
ALLOC_HASHTABLE(ht);
|
||||
zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
if (Z_OBJ_HT_P(op)->get_properties) {
|
||||
HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
|
||||
if(obj_ht) {
|
||||
@ -644,11 +863,11 @@ ZEND_API void convert_to_array(zval *op)
|
||||
return;
|
||||
case IS_NULL:
|
||||
ALLOC_HASHTABLE(op->value.ht);
|
||||
zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
op->type = IS_ARRAY;
|
||||
break;
|
||||
default:
|
||||
convert_scalar_to_array(op, IS_ARRAY);
|
||||
convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -656,12 +875,10 @@ ZEND_API void convert_to_array(zval *op)
|
||||
|
||||
ZEND_API void convert_to_object(zval *op)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
switch (op->type) {
|
||||
case IS_ARRAY:
|
||||
{
|
||||
/* OBJECTS_OPTIMIZE */
|
||||
TSRMLS_FETCH();
|
||||
|
||||
object_and_properties_init(op, zend_standard_class_def, op->value.ht);
|
||||
return;
|
||||
break;
|
||||
@ -677,7 +894,7 @@ ZEND_API void convert_to_object(zval *op)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
convert_scalar_to_array(op, IS_OBJECT);
|
||||
convert_scalar_to_array(op, IS_OBJECT TSRMLS_CC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -957,10 +1174,10 @@ ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC)
|
||||
result->type = IS_LONG;
|
||||
return SUCCESS;
|
||||
}
|
||||
if (op1->type == IS_STRING) {
|
||||
if (op1->type == IS_STRING || op1->type == IS_BINARY) {
|
||||
int i;
|
||||
|
||||
result->type = IS_STRING;
|
||||
result->type = op1->type;
|
||||
result->value.str.val = estrndup(op1->value.str.val, op1->value.str.len);
|
||||
result->value.str.len = op1->value.str.len;
|
||||
for (i = 0; i < op1->value.str.len; i++) {
|
||||
@ -976,8 +1193,9 @@ ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC)
|
||||
ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
|
||||
if (op1->type == IS_STRING && op2->type == IS_STRING) {
|
||||
|
||||
if ((op1->type == IS_STRING && op2->type == IS_STRING) ||
|
||||
(op1->type == IS_BINARY && op2->type == IS_BINARY)) {
|
||||
zval *longer, *shorter;
|
||||
char *result_str;
|
||||
int i, result_len;
|
||||
@ -990,7 +1208,7 @@ ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
shorter = op1;
|
||||
}
|
||||
|
||||
result->type = IS_STRING;
|
||||
result->type = op1->type;
|
||||
result_len = longer->value.str.len;
|
||||
result_str = estrndup(longer->value.str.val, longer->value.str.len);
|
||||
for (i = 0; i < shorter->value.str.len; i++) {
|
||||
@ -1003,6 +1221,10 @@ ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
result->value.str.len = result_len;
|
||||
return SUCCESS;
|
||||
}
|
||||
if (op1->type == IS_UNICODE || op2->type == IS_UNICODE) {
|
||||
zend_error(E_ERROR, "Unsupported operand types");
|
||||
return FAILURE;
|
||||
}
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
|
||||
@ -1016,7 +1238,8 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
|
||||
if (op1->type == IS_STRING && op2->type == IS_STRING) {
|
||||
if ((op1->type == IS_STRING && op2->type == IS_STRING) ||
|
||||
(op1->type == IS_BINARY && op2->type == IS_BINARY)) {
|
||||
zval *longer, *shorter;
|
||||
char *result_str;
|
||||
int i, result_len;
|
||||
@ -1029,7 +1252,7 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
shorter = op1;
|
||||
}
|
||||
|
||||
result->type = IS_STRING;
|
||||
result->type = op1->type;
|
||||
result_len = shorter->value.str.len;
|
||||
result_str = estrndup(shorter->value.str.val, shorter->value.str.len);
|
||||
for (i = 0; i < shorter->value.str.len; i++) {
|
||||
@ -1043,6 +1266,10 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (op1->type == IS_UNICODE || op2->type == IS_UNICODE) {
|
||||
zend_error(E_ERROR, "Unsupported operand types");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
@ -1057,7 +1284,8 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
|
||||
if (op1->type == IS_STRING && op2->type == IS_STRING) {
|
||||
if ((op1->type == IS_STRING && op2->type == IS_STRING) ||
|
||||
(op1->type == IS_BINARY && op2->type == IS_BINARY)) {
|
||||
zval *longer, *shorter;
|
||||
char *result_str;
|
||||
int i, result_len;
|
||||
@ -1070,7 +1298,7 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
shorter = op1;
|
||||
}
|
||||
|
||||
result->type = IS_STRING;
|
||||
result->type = op1->type;
|
||||
result_len = shorter->value.str.len;
|
||||
result_str = estrndup(shorter->value.str.val, shorter->value.str.len);
|
||||
for (i = 0; i < shorter->value.str.len; i++) {
|
||||
@ -1084,6 +1312,11 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (op1->type == IS_UNICODE || op2->type == IS_UNICODE) {
|
||||
zend_error(E_ERROR, "Unsupported operand types");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
|
||||
@ -1097,6 +1330,11 @@ ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
|
||||
if (op1->type == IS_UNICODE || op2->type == IS_UNICODE) {
|
||||
zend_error(E_ERROR, "Unsupported operand types");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
result->value.lval = op1->value.lval << op2->value.lval;
|
||||
@ -1109,6 +1347,11 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
|
||||
if (op1->type == IS_UNICODE || op2->type == IS_UNICODE) {
|
||||
zend_error(E_ERROR, "Unsupported operand types");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
result->value.lval = op1->value.lval >> op2->value.lval;
|
||||
@ -1117,15 +1360,31 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* must support result==op1 */
|
||||
ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2)
|
||||
{
|
||||
result->value.str.len = op1->value.str.len + 1;
|
||||
result->value.str.val = (char *) erealloc(op1->value.str.val, result->value.str.len+1);
|
||||
result->value.str.val[result->value.str.len - 1] = (char) op2->value.lval;
|
||||
result->value.str.val[result->value.str.len] = 0;
|
||||
result->type = IS_STRING;
|
||||
if (op1->type == IS_UNICODE) {
|
||||
UChar32 codepoint = (UChar32) op2->value.lval;
|
||||
|
||||
if (U_IS_BMP(codepoint)) {
|
||||
result->value.ustr.len = op1->value.ustr.len + 1;
|
||||
result->value.ustr.val = eurealloc(op1->value.ustr.val, result->value.ustr.len+1);
|
||||
result->value.ustr.val[result->value.ustr.len - 1] = (UChar) op2->value.lval;
|
||||
} else {
|
||||
result->value.ustr.len = op1->value.ustr.len + 2;
|
||||
result->value.ustr.val = eurealloc(op1->value.ustr.val, result->value.ustr.len+1);
|
||||
result->value.ustr.val[result->value.ustr.len - 2] = (UChar) U16_LEAD(codepoint);
|
||||
result->value.ustr.val[result->value.ustr.len - 1] = (UChar) U16_TRAIL(codepoint);
|
||||
}
|
||||
result->value.ustr.val[result->value.ustr.len] = 0;
|
||||
result->type = IS_UNICODE;
|
||||
} else {
|
||||
result->value.str.len = op1->value.str.len + 1;
|
||||
result->value.str.val = (char *) erealloc(op1->value.str.val, result->value.str.len+1);
|
||||
result->value.str.val[result->value.str.len - 1] = (char) op2->value.lval;
|
||||
result->value.str.val[result->value.str.len] = 0;
|
||||
result->type = op1->type;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -1133,13 +1392,25 @@ ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2)
|
||||
/* must support result==op1 */
|
||||
ZEND_API int add_string_to_string(zval *result, zval *op1, zval *op2)
|
||||
{
|
||||
int length = op1->value.str.len + op2->value.str.len;
|
||||
assert(op1->type == op2->type);
|
||||
|
||||
result->value.str.val = (char *) erealloc(op1->value.str.val, length+1);
|
||||
memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
|
||||
result->value.str.val[length] = 0;
|
||||
result->value.str.len = length;
|
||||
result->type = IS_STRING;
|
||||
if (op1->type == IS_UNICODE) {
|
||||
int32_t length = op1->value.ustr.len + op2->value.ustr.len;
|
||||
|
||||
result->value.ustr.val = eurealloc(op1->value.ustr.val, length+1);
|
||||
u_memcpy(result->value.ustr.val+op1->value.ustr.len, op2->value.ustr.val, op2->value.ustr.len);
|
||||
result->value.ustr.val[length] = 0;
|
||||
result->value.ustr.len = length;
|
||||
result->type = IS_UNICODE;
|
||||
} else {
|
||||
int length = op1->value.str.len + op2->value.str.len;
|
||||
|
||||
result->value.str.val = (char *) erealloc(op1->value.str.val, length+1);
|
||||
memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
|
||||
result->value.str.val[length] = 0;
|
||||
result->value.str.len = length;
|
||||
result->type = op1->type;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@ -1148,10 +1419,21 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
int use_copy1, use_copy2;
|
||||
zend_uchar result_type;
|
||||
|
||||
|
||||
zend_make_printable_zval(op1, &op1_copy, &use_copy1);
|
||||
zend_make_printable_zval(op2, &op2_copy, &use_copy2);
|
||||
if (op1->type == IS_UNICODE || op2->type == IS_UNICODE) {
|
||||
zend_make_unicode_zval(op1, &op1_copy, &use_copy1);
|
||||
zend_make_unicode_zval(op2, &op2_copy, &use_copy2);
|
||||
result_type = IS_UNICODE;
|
||||
} else if (op1->type == IS_BINARY && op2->type == IS_BINARY) {
|
||||
result_type = IS_BINARY;
|
||||
/* no conversion necessary */
|
||||
use_copy1 = use_copy2 = 0;
|
||||
} else {
|
||||
result_type = IS_STRING;
|
||||
zend_make_string_zval(op1, &op1_copy, &use_copy1);
|
||||
zend_make_string_zval(op2, &op2_copy, &use_copy2);
|
||||
}
|
||||
|
||||
if (use_copy1) {
|
||||
/* We have created a converted copy of op1. Therefore, op1 won't become the result so
|
||||
@ -1166,20 +1448,23 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
op2 = &op2_copy;
|
||||
}
|
||||
if (result==op1) { /* special case, perform operations on result */
|
||||
uint res_len = op1->value.str.len + op2->value.str.len;
|
||||
|
||||
result->value.str.val = erealloc(result->value.str.val, res_len+1);
|
||||
|
||||
memcpy(result->value.str.val+result->value.str.len, op2->value.str.val, op2->value.str.len);
|
||||
result->value.str.val[res_len]=0;
|
||||
result->value.str.len = res_len;
|
||||
add_string_to_string(result, op1, op2);
|
||||
} else {
|
||||
result->value.str.len = op1->value.str.len + op2->value.str.len;
|
||||
result->value.str.val = (char *) emalloc(result->value.str.len + 1);
|
||||
memcpy(result->value.str.val, op1->value.str.val, op1->value.str.len);
|
||||
memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
|
||||
result->value.str.val[result->value.str.len] = 0;
|
||||
result->type = IS_STRING;
|
||||
if (result_type == IS_UNICODE) {
|
||||
result->value.ustr.len = op1->value.ustr.len + op2->value.ustr.len;
|
||||
result->value.ustr.val = eumalloc(result->value.ustr.len + 1);
|
||||
u_memcpy(result->value.ustr.val, op1->value.ustr.val, op1->value.ustr.len);
|
||||
u_memcpy(result->value.ustr.val+op1->value.ustr.len, op2->value.ustr.val, op2->value.ustr.len);
|
||||
result->value.ustr.val[result->value.ustr.len] = 0;
|
||||
result->type = IS_UNICODE;
|
||||
} else {
|
||||
result->value.str.len = op1->value.str.len + op2->value.str.len;
|
||||
result->value.str.val = (char *) emalloc(result->value.str.len + 1);
|
||||
memcpy(result->value.str.val, op1->value.str.val, op1->value.str.len);
|
||||
memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
|
||||
result->value.str.val[result->value.str.len] = 0;
|
||||
result->type = result_type;
|
||||
}
|
||||
}
|
||||
if (use_copy1) {
|
||||
zval_dtor(op1);
|
||||
@ -1314,8 +1599,18 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
}
|
||||
}
|
||||
|
||||
if (op1->type == IS_STRING && op2->type == IS_STRING) {
|
||||
zendi_smart_strcmp(result, op1, op2);
|
||||
if ((op1->type == IS_UNICODE || op1->type == IS_STRING || op1->type == IS_BINARY) &&
|
||||
(op2->type == IS_UNICODE || op2->type == IS_STRING || op2->type == IS_BINARY)) {
|
||||
|
||||
if (op1->type == IS_UNICODE || op2->type == IS_UNICODE) {
|
||||
zendi_u_smart_strcmp(result, op1, op2);
|
||||
} else if (op1->type == IS_STRING || op2->type == IS_STRING) {
|
||||
zendi_smart_strcmp(result, op1, op2);
|
||||
} else {
|
||||
result->value.lval = zend_binary_zval_strcmp(op1, op2);
|
||||
result->value.lval = ZEND_NORMALIZE_BOOL(result->value.lval);
|
||||
result->type = IS_LONG;
|
||||
}
|
||||
COMPARE_RETURN_AND_FREE(SUCCESS);
|
||||
}
|
||||
|
||||
@ -1421,6 +1716,7 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
result->value.lval = (op1->value.dval == op2->value.dval);
|
||||
break;
|
||||
case IS_STRING:
|
||||
case IS_BINARY:
|
||||
if ((op1->value.str.len == op2->value.str.len)
|
||||
&& (!memcmp(op1->value.str.val, op2->value.str.val, op1->value.str.len))) {
|
||||
result->value.lval = 1;
|
||||
@ -1428,6 +1724,14 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
||||
result->value.lval = 0;
|
||||
}
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
if ((op1->value.ustr.len == op2->value.ustr.len)
|
||||
&& (!memcmp(op1->value.ustr.val, op2->value.ustr.val, UBYTES(op1->value.ustr.len)))) {
|
||||
result->value.lval = 1;
|
||||
} else {
|
||||
result->value.lval = 0;
|
||||
}
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
if (zend_hash_compare(op1->value.ht, op2->value.ht, (compare_func_t) hash_zval_identical_function, 1 TSRMLS_CC)==0) {
|
||||
result->value.lval = 1;
|
||||
@ -1682,6 +1986,7 @@ ZEND_API int increment_function(zval *op1)
|
||||
op1->value.lval = 1;
|
||||
op1->type = IS_LONG;
|
||||
break;
|
||||
case IS_BINARY:
|
||||
case IS_STRING: {
|
||||
long lval;
|
||||
double dval;
|
||||
@ -1711,6 +2016,9 @@ ZEND_API int increment_function(zval *op1)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
zend_error(E_ERROR, "Unsupported operand type");
|
||||
break;
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
@ -1735,6 +2043,7 @@ ZEND_API int decrement_function(zval *op1)
|
||||
case IS_DOUBLE:
|
||||
op1->value.dval = op1->value.dval - 1;
|
||||
break;
|
||||
case IS_BINARY:
|
||||
case IS_STRING: /* Like perl we only support string increment */
|
||||
if (op1->value.str.len == 0) { /* consider as 0 */
|
||||
STR_FREE(op1->value.str.val);
|
||||
@ -1760,6 +2069,9 @@ ZEND_API int decrement_function(zval *op1)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
zend_error(E_ERROR, "Unsupported operand type");
|
||||
break;
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
@ -1788,6 +2100,38 @@ ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned in
|
||||
return dest;
|
||||
}
|
||||
|
||||
ZEND_API char *zend_str_tolower_dup(const char *source, unsigned int length)
|
||||
{
|
||||
return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
|
||||
}
|
||||
|
||||
ZEND_API void *zend_u_str_tolower_copy(zend_uchar type, void *dest, const void *source, unsigned int length)
|
||||
{
|
||||
if (type == IS_UNICODE) {
|
||||
register UChar *str = (UChar*)source;
|
||||
register UChar *result = (UChar*)dest;
|
||||
register UChar *end = str + length;
|
||||
|
||||
while (str < end) {
|
||||
*result++ = u_tolower((int)*str++);
|
||||
}
|
||||
*result = *end;
|
||||
|
||||
return dest;
|
||||
} else {
|
||||
return zend_str_tolower_copy(dest, source, length);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void *zend_u_str_tolower_dup(zend_uchar type, const void *source, unsigned int length)
|
||||
{
|
||||
if (type == IS_UNICODE) {
|
||||
return zend_u_str_tolower_copy(IS_UNICODE, emalloc(UBYTES(length+1)), source, length);
|
||||
} else {
|
||||
return zend_str_tolower_copy((char*)emalloc(length+1), (char*)source, length);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_str_tolower(char *str, unsigned int length)
|
||||
{
|
||||
register unsigned char *p = (unsigned char*)str;
|
||||
@ -1799,6 +2143,42 @@ ZEND_API void zend_str_tolower(char *str, unsigned int length)
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_u_str_tolower(zend_uchar type, void *str, unsigned int length) {
|
||||
if (type == IS_UNICODE) {
|
||||
register UChar *p = (UChar*)str;
|
||||
register UChar *end = p + length;
|
||||
|
||||
while (p < end) {
|
||||
*p = u_tolower((int)*p);
|
||||
p++;
|
||||
}
|
||||
} else {
|
||||
zend_str_tolower((char*)str, length);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void *zend_u_str_case_fold(zend_uchar type, const void *source, unsigned int length, zend_bool normalize, unsigned int *new_len)
|
||||
{
|
||||
if (type == IS_UNICODE) {
|
||||
UChar *ret;
|
||||
int32_t ret_len;
|
||||
|
||||
if (normalize) {
|
||||
zend_normalize_identifier(&ret, &ret_len, (UChar*)source, length, 1);
|
||||
} else {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
zend_case_fold_string(&ret, &ret_len, (UChar*)source, length, U_FOLD_CASE_DEFAULT, &status);
|
||||
}
|
||||
|
||||
*new_len = ret_len;
|
||||
return ret;
|
||||
} else {
|
||||
*new_len = length;
|
||||
return zend_str_tolower_dup(source, length);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API int zend_binary_strcmp(char *s1, uint len1, char *s2, uint len2)
|
||||
{
|
||||
int retval;
|
||||
@ -1811,6 +2191,20 @@ ZEND_API int zend_binary_strcmp(char *s1, uint len1, char *s2, uint len2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_u_binary_strcmp(UChar *s1, int32_t len1, UChar *s2, int32_t len2)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = u_memcmpCodePointOrder(s1, s2, MIN(len1, len2));
|
||||
if (!retval) {
|
||||
return (len1 - len2);
|
||||
} else {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_binary_strncmp(char *s1, uint len1, char *s2, uint len2, uint length)
|
||||
{
|
||||
int retval;
|
||||
@ -1867,6 +2261,13 @@ ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2)
|
||||
return zend_binary_strcmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_u_binary_zval_strcmp(zval *s1, zval *s2)
|
||||
{
|
||||
return zend_u_binary_strcmp(s1->value.ustr.val, s1->value.ustr.len, s2->value.ustr.val, s2->value.ustr.len);
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3)
|
||||
{
|
||||
return zend_binary_strncmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len, s3->value.lval);
|
||||
@ -1891,6 +2292,11 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2)
|
||||
long lval1, lval2;
|
||||
double dval1, dval2;
|
||||
|
||||
if (s1->type == IS_BINARY || s2->type == IS_BINARY) {
|
||||
zend_error(E_ERROR, "Cannot convert binary type to string type");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret1=is_numeric_string(s1->value.str.val, s1->value.str.len, &lval1, &dval1, 0)) &&
|
||||
(ret2=is_numeric_string(s2->value.str.val, s2->value.str.len, &lval2, &dval2, 0))) {
|
||||
if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
|
||||
@ -1916,6 +2322,57 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2)
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zendi_u_smart_strcmp(zval *result, zval *s1, zval *s2)
|
||||
{
|
||||
int ret1, ret2;
|
||||
long lval1, lval2;
|
||||
double dval1, dval2;
|
||||
zval s1_copy, s2_copy;
|
||||
int use_copy1 = 0, use_copy2 = 0;
|
||||
|
||||
if (s1->type != IS_UNICODE || s2->type != IS_UNICODE) {
|
||||
zend_make_unicode_zval(s1, &s1_copy, &use_copy1);
|
||||
zend_make_unicode_zval(s2, &s2_copy, &use_copy2);
|
||||
if (use_copy1) {
|
||||
s1 = &s1_copy;
|
||||
}
|
||||
if (use_copy2) {
|
||||
s2 = &s2_copy;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret1=is_numeric_unicode(s1->value.ustr.val, s1->value.ustr.len, &lval1, &dval1, 0)) &&
|
||||
(ret2=is_numeric_unicode(s2->value.ustr.val, s2->value.ustr.len, &lval2, &dval2, 0))) {
|
||||
if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
|
||||
if (ret1!=IS_DOUBLE) {
|
||||
dval1 = zend_u_strtod(s1->value.ustr.val, NULL);
|
||||
} else if (ret2!=IS_DOUBLE) {
|
||||
dval2 = zend_u_strtod(s2->value.ustr.val, NULL);
|
||||
}
|
||||
result->value.dval = dval1 - dval2;
|
||||
result->value.lval = ZEND_NORMALIZE_BOOL(result->value.dval);
|
||||
result->type = IS_LONG;
|
||||
} else { /* they both have to be long's */
|
||||
result->value.lval = lval1 - lval2;
|
||||
result->value.lval = ZEND_NORMALIZE_BOOL(result->value.lval);
|
||||
result->type = IS_LONG;
|
||||
}
|
||||
} else {
|
||||
result->value.lval = zend_u_binary_zval_strcmp(s1, s2);
|
||||
result->value.lval = ZEND_NORMALIZE_BOOL(result->value.lval);
|
||||
result->type = IS_LONG;
|
||||
}
|
||||
|
||||
if (use_copy1) {
|
||||
zval_dtor(s1);
|
||||
}
|
||||
if (use_copy2) {
|
||||
zval_dtor(s2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int hash_zval_compare_function(const zval **z1, const zval **z2 TSRMLS_DC)
|
||||
{
|
||||
zval result;
|
||||
@ -1962,6 +2419,22 @@ ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC)
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_locale_usprintf_double(zval *op ZEND_FILE_LINE_DC)
|
||||
{
|
||||
double dval = op->value.dval;
|
||||
UFILE *strf;
|
||||
int32_t capacity;
|
||||
|
||||
TSRMLS_FETCH();
|
||||
|
||||
capacity = MAX_LENGTH_OF_DOUBLE + EG(precision) + 1;
|
||||
op->value.ustr.val = eumalloc_rel(capacity);
|
||||
/* UTODO uses default locale for now */
|
||||
strf = u_fstropen(op->value.ustr.val, capacity, NULL);
|
||||
op->value.ustr.len = u_fprintf(strf, "%.*G", (int) EG(precision), dval);
|
||||
u_fclose(strf);
|
||||
}
|
||||
|
||||
ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC)
|
||||
{
|
||||
double dval = op->value.dval;
|
||||
@ -1973,6 +2446,20 @@ ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC)
|
||||
op->value.str.len = strlen(op->value.str.val);
|
||||
}
|
||||
|
||||
ZEND_API void zend_locale_usprintf_long(zval *op ZEND_FILE_LINE_DC)
|
||||
{
|
||||
long lval = op->value.lval;
|
||||
UFILE *strf;
|
||||
int32_t capacity;
|
||||
|
||||
capacity = MAX_LENGTH_OF_LONG + 1;
|
||||
op->value.ustr.val = eumalloc_rel(capacity);
|
||||
/* UTODO uses default locale for now */
|
||||
strf = u_fstropen(op->value.ustr.val, capacity, NULL);
|
||||
op->value.ustr.len = u_fprintf(strf, "%ld", lval);
|
||||
u_fclose(strf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -30,6 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include "zend_strtod.h"
|
||||
#include "zend_unicode.h"
|
||||
|
||||
#if 0&&HAVE_BCMATH
|
||||
#include "ext/bcmath/libbcmath/src/bcmath.h"
|
||||
@ -63,6 +64,8 @@ ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSR
|
||||
|
||||
ZEND_API zend_bool instanceof_function_ex(zend_class_entry *instance_ce, zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC);
|
||||
ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce, zend_class_entry *ce TSRMLS_DC);
|
||||
ZEND_API long zend_u_strtol(const UChar *nptr, UChar **endptr, int base);
|
||||
ZEND_API double zend_u_strtod(const UChar *nptr, UChar **endptr);
|
||||
END_EXTERN_C()
|
||||
|
||||
static inline zend_bool is_numeric_string(char *str, int length, long *lval, double *dval, zend_bool allow_errors)
|
||||
@ -128,6 +131,77 @@ static inline zend_bool is_numeric_string(char *str, int length, long *lval, dou
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline zend_bool is_numeric_unicode(UChar *str, int32_t length, long *lval, double *dval, zend_bool allow_errors)
|
||||
{
|
||||
int32_t local_lval;
|
||||
double local_dval;
|
||||
UChar *end_ptr_long, *end_ptr_double;
|
||||
int conv_base=10;
|
||||
|
||||
if (!length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* handle hex numbers */
|
||||
if (length>=2 && str[0]=='0' && (str[1]=='x' || str[1]=='X')) {
|
||||
conv_base=16;
|
||||
}
|
||||
|
||||
errno=0;
|
||||
local_lval = zend_u_strtol(str, &end_ptr_long, conv_base);
|
||||
if (errno != ERANGE) {
|
||||
if (end_ptr_long == str+length) { /* integer string */
|
||||
if (lval) {
|
||||
*lval = local_lval;
|
||||
}
|
||||
return IS_LONG;
|
||||
} else if (end_ptr_long == str && *end_ptr_long != '\0' && *str != '.' && *str != '-') { /* ignore partial string matches */
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
end_ptr_long = NULL;
|
||||
}
|
||||
|
||||
if (conv_base == 16) { /* hex string, under UNIX strtod() messes it up */
|
||||
/* UTODO: keep compatibility with is_numeric_string() here? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
local_dval = zend_u_strtod(str, &end_ptr_double);
|
||||
if (local_dval == 0 && end_ptr_double == str) {
|
||||
end_ptr_double = NULL;
|
||||
} else {
|
||||
if (end_ptr_double == str+length) { /* floating point string */
|
||||
if (!zend_finite(local_dval)) {
|
||||
/* "inf","nan" and maybe other weird ones */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dval) {
|
||||
*dval = local_dval;
|
||||
}
|
||||
return IS_DOUBLE;
|
||||
}
|
||||
}
|
||||
|
||||
if (allow_errors) {
|
||||
if (end_ptr_double > end_ptr_long && dval) {
|
||||
*dval = local_dval;
|
||||
return IS_DOUBLE;
|
||||
} else if (end_ptr_long && lval) {
|
||||
*lval = local_lval;
|
||||
return IS_LONG;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline UChar*
|
||||
zend_u_memnstr(UChar *haystack, UChar *needle, int32_t needle_len, UChar *end)
|
||||
{
|
||||
return u_strFindFirst(haystack, end - haystack, needle, needle_len);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
zend_memnstr(char *haystack, char *needle, int needle_len, char *end)
|
||||
{
|
||||
@ -160,6 +234,10 @@ ZEND_API int decrement_function(zval *op2);
|
||||
|
||||
ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC);
|
||||
ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC);
|
||||
ZEND_API void _convert_to_string_with_converter(zval *op, UConverter *conv TSRMLS_DC ZEND_FILE_LINE_DC);
|
||||
ZEND_API void _convert_to_unicode(zval *op TSRMLS_DC ZEND_FILE_LINE_DC);
|
||||
ZEND_API void _convert_to_unicode_with_converter(zval *op, UConverter *conv TSRMLS_DC ZEND_FILE_LINE_DC);
|
||||
ZEND_API void convert_to_binary(zval *op);
|
||||
ZEND_API void convert_to_long(zval *op);
|
||||
ZEND_API void convert_to_double(zval *op);
|
||||
ZEND_API void convert_to_long_base(zval *op, int base);
|
||||
@ -172,7 +250,11 @@ ZEND_API void multi_convert_to_double_ex(int argc, ...);
|
||||
ZEND_API void multi_convert_to_string_ex(int argc, ...);
|
||||
ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2);
|
||||
ZEND_API int add_string_to_string(zval *result, zval *op1, zval *op2);
|
||||
#define convert_to_string(op) _convert_to_string((op) ZEND_FILE_LINE_CC)
|
||||
#define convert_to_string(op) _convert_to_string((op) ZEND_FILE_LINE_CC)
|
||||
#define convert_to_string_with_converter(op, conv) _convert_to_string_with_converter((op), (conv) TSRMLS_CC ZEND_FILE_LINE_CC)
|
||||
#define convert_to_unicode(op) _convert_to_unicode((op) TSRMLS_CC ZEND_FILE_LINE_CC)
|
||||
#define convert_to_unicode_with_converter(op, conv) _convert_to_unicode_with_converter((op), (conv) TSRMLS_CC ZEND_FILE_LINE_CC)
|
||||
#define convert_to_text(op) (UG(unicode)?convert_to_unicode(op):convert_to_string(op))
|
||||
|
||||
ZEND_API double zend_string_to_double(const char *number, zend_uint length);
|
||||
|
||||
@ -186,15 +268,14 @@ ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 T
|
||||
|
||||
ZEND_API void zend_str_tolower(char *str, unsigned int length);
|
||||
ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
|
||||
END_EXTERN_C()
|
||||
ZEND_API char *zend_str_tolower_dup(const char *source, unsigned int length);
|
||||
|
||||
static inline char *
|
||||
zend_str_tolower_dup(const char *source, unsigned int length)
|
||||
{
|
||||
return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
|
||||
}
|
||||
ZEND_API void zend_u_str_tolower(zend_uchar type, void *str, unsigned int length);
|
||||
ZEND_API void *zend_u_str_tolower_copy(zend_uchar type, void *dest, const void *source, unsigned int length);
|
||||
ZEND_API void *zend_u_str_tolower_dup(zend_uchar type, const void *source, unsigned int length);
|
||||
|
||||
ZEND_API void *zend_u_str_case_fold(zend_uchar type, const void *source, unsigned int length, zend_bool normalize, unsigned int *new_len);
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
|
||||
ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
|
||||
ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
|
||||
@ -204,7 +285,11 @@ ZEND_API int zend_binary_strncmp(char *s1, uint len1, char *s2, uint len2, uint
|
||||
ZEND_API int zend_binary_strcasecmp(char *s1, uint len1, char *s2, uint len2);
|
||||
ZEND_API int zend_binary_strncasecmp(char *s1, uint len1, char *s2, uint len2, uint length);
|
||||
|
||||
ZEND_API int zend_u_binary_zval_strcmp(zval *s1, zval *s2);
|
||||
ZEND_API int zend_u_binary_strcmp(UChar *s1, int32_t len1, UChar *s2, int32_t len2);
|
||||
|
||||
ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2);
|
||||
ZEND_API void zendi_u_smart_strcmp(zval *result, zval *s1, zval *s2);
|
||||
ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC);
|
||||
ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC);
|
||||
ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC);
|
||||
@ -212,6 +297,8 @@ ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC);
|
||||
ZEND_API int zend_atoi(const char *str, int str_len);
|
||||
|
||||
ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC);
|
||||
ZEND_API void zend_locale_usprintf_double(zval *op ZEND_FILE_LINE_DC);
|
||||
ZEND_API void zend_locale_usprintf_long(zval *op ZEND_FILE_LINE_DC);
|
||||
END_EXTERN_C()
|
||||
#define convert_to_ex_master(ppzv, lower_type, upper_type) \
|
||||
if ((*ppzv)->type!=IS_##upper_type) { \
|
||||
@ -219,14 +306,59 @@ END_EXTERN_C()
|
||||
convert_to_##lower_type(*ppzv); \
|
||||
}
|
||||
|
||||
#define convert_to_explicit_type(pzv, type) \
|
||||
do { \
|
||||
switch (type) { \
|
||||
case IS_NULL: \
|
||||
convert_to_null(pzv); \
|
||||
break; \
|
||||
case IS_LONG: \
|
||||
convert_to_long(pzv); \
|
||||
break; \
|
||||
case IS_DOUBLE: \
|
||||
convert_to_double(pzv); \
|
||||
break; \
|
||||
case IS_BOOL: \
|
||||
convert_to_bool(pzv); \
|
||||
break; \
|
||||
case IS_ARRAY: \
|
||||
convert_to_array(pzv); \
|
||||
break; \
|
||||
case IS_OBJECT: \
|
||||
convert_to_object(pzv); \
|
||||
break; \
|
||||
case IS_STRING: \
|
||||
convert_to_string(pzv); \
|
||||
break; \
|
||||
case IS_UNICODE: \
|
||||
convert_to_unicode(pzv); \
|
||||
break; \
|
||||
case IS_BINARY: \
|
||||
convert_to_binary(pzv); \
|
||||
break; \
|
||||
default: \
|
||||
assert(0); \
|
||||
break; \
|
||||
} \
|
||||
} while (0); \
|
||||
|
||||
#define convert_to_explicit_type_ex(ppzv, type) \
|
||||
if ((*ppzv)->type != type) { \
|
||||
SEPARATE_ZVAL_IF_NOT_REF(ppzv); \
|
||||
convert_to_explicit_type(*ppzv, type); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define convert_to_boolean_ex(ppzv) convert_to_ex_master(ppzv, boolean, BOOL)
|
||||
#define convert_to_long_ex(ppzv) convert_to_ex_master(ppzv, long, LONG)
|
||||
#define convert_to_double_ex(ppzv) convert_to_ex_master(ppzv, double, DOUBLE)
|
||||
#define convert_to_string_ex(ppzv) convert_to_ex_master(ppzv, string, STRING)
|
||||
#define convert_to_unicode_ex(ppzv) convert_to_ex_master(ppzv, unicode, UNICODE)
|
||||
#define convert_to_binary_ex(ppzv) convert_to_ex_master(ppzv, binary, BINARY)
|
||||
#define convert_to_array_ex(ppzv) convert_to_ex_master(ppzv, array, ARRAY)
|
||||
#define convert_to_object_ex(ppzv) convert_to_ex_master(ppzv, object, OBJECT)
|
||||
#define convert_to_null_ex(ppzv) convert_to_ex_master(ppzv, null, NULL)
|
||||
#define convert_to_text_ex(ppzv) if (UG(unicode)) {convert_to_unicode_ex(ppzv);} else {convert_to_string_ex(ppzv);}
|
||||
|
||||
#define convert_scalar_to_number_ex(ppzv) \
|
||||
if ((*ppzv)->type!=IS_LONG && (*ppzv)->type!=IS_DOUBLE) { \
|
||||
@ -242,6 +374,11 @@ END_EXTERN_C()
|
||||
#define Z_DVAL(zval) (zval).value.dval
|
||||
#define Z_STRVAL(zval) (zval).value.str.val
|
||||
#define Z_STRLEN(zval) (zval).value.str.len
|
||||
#define Z_USTRVAL(zval) (zval).value.ustr.val
|
||||
#define Z_USTRLEN(zval) (zval).value.ustr.len
|
||||
#define Z_USTRCPLEN(zval) (u_countChar32((zval).value.ustr.val, (zval).value.ustr.len))
|
||||
#define Z_BINVAL(zval) Z_STRVAL(zval)
|
||||
#define Z_BINLEN(zval) Z_STRLEN(zval)
|
||||
#define Z_ARRVAL(zval) (zval).value.ht
|
||||
#define Z_OBJ_HANDLE(zval) (zval).value.obj.handle
|
||||
#define Z_OBJ_HT(zval) (zval).value.obj.handlers
|
||||
@ -249,12 +386,19 @@ END_EXTERN_C()
|
||||
#define Z_OBJPROP(zval) Z_OBJ_HT((zval))->get_properties(&(zval) TSRMLS_CC)
|
||||
#define Z_OBJ_HANDLER(zval, hf) Z_OBJ_HT((zval))->hf
|
||||
#define Z_RESVAL(zval) (zval).value.lval
|
||||
#define Z_UNIVAL(zval) ((zval).type==IS_UNICODE?(char*)(zval).value.ustr.val:(zval).value.str.val)
|
||||
#define Z_UNILEN(zval) ((zval).type==IS_UNICODE?(zval).value.ustr.len:(zval).value.str.len)
|
||||
|
||||
#define Z_LVAL_P(zval_p) Z_LVAL(*zval_p)
|
||||
#define Z_BVAL_P(zval_p) Z_BVAL(*zval_p)
|
||||
#define Z_DVAL_P(zval_p) Z_DVAL(*zval_p)
|
||||
#define Z_STRVAL_P(zval_p) Z_STRVAL(*zval_p)
|
||||
#define Z_STRLEN_P(zval_p) Z_STRLEN(*zval_p)
|
||||
#define Z_USTRVAL_P(zval_p) Z_USTRVAL(*zval_p)
|
||||
#define Z_USTRLEN_P(zval_p) Z_USTRLEN(*zval_p)
|
||||
#define Z_USTRCPLEN_P(zval_p) Z_USTRCPLEN(*zval_p)
|
||||
#define Z_BINVAL_P(zval) Z_STRVAL_P(zval)
|
||||
#define Z_BINLEN_P(zval) Z_STRLEN_P(zval)
|
||||
#define Z_ARRVAL_P(zval_p) Z_ARRVAL(*zval_p)
|
||||
#define Z_OBJPROP_P(zval_p) Z_OBJPROP(*zval_p)
|
||||
#define Z_OBJCE_P(zval_p) Z_OBJCE(*zval_p)
|
||||
@ -262,12 +406,19 @@ END_EXTERN_C()
|
||||
#define Z_OBJ_HANDLE_P(zval_p) Z_OBJ_HANDLE(*zval_p)
|
||||
#define Z_OBJ_HT_P(zval_p) Z_OBJ_HT(*zval_p)
|
||||
#define Z_OBJ_HANDLER_P(zval_p, h) Z_OBJ_HANDLER(*zval_p, h)
|
||||
#define Z_UNIVAL_P(zval_p) Z_UNIVAL(*zval_p)
|
||||
#define Z_UNILEN_P(zval_p) Z_UNILEN(*zval_p)
|
||||
|
||||
#define Z_LVAL_PP(zval_pp) Z_LVAL(**zval_pp)
|
||||
#define Z_BVAL_PP(zval_pp) Z_BVAL(**zval_pp)
|
||||
#define Z_DVAL_PP(zval_pp) Z_DVAL(**zval_pp)
|
||||
#define Z_STRVAL_PP(zval_pp) Z_STRVAL(**zval_pp)
|
||||
#define Z_STRLEN_PP(zval_pp) Z_STRLEN(**zval_pp)
|
||||
#define Z_USTRVAL_PP(zval_pp) Z_USTRVAL(**zval_pp)
|
||||
#define Z_USTRLEN_PP(zval_pp) Z_USTRLEN(**zval_pp)
|
||||
#define Z_USTRCPLEN_PP(zval_pp) Z_USTRCPLEN(**zval_pp)
|
||||
#define Z_BINVAL_PP(zval) Z_STRVAL_PP(zval)
|
||||
#define Z_BINLEN_PP(zval) Z_STRLEN_PP(zval)
|
||||
#define Z_ARRVAL_PP(zval_pp) Z_ARRVAL(**zval_pp)
|
||||
#define Z_OBJPROP_PP(zval_pp) Z_OBJPROP(**zval_pp)
|
||||
#define Z_OBJCE_PP(zval_pp) Z_OBJCE(**zval_pp)
|
||||
@ -275,6 +426,8 @@ END_EXTERN_C()
|
||||
#define Z_OBJ_HANDLE_PP(zval_p) Z_OBJ_HANDLE(**zval_p)
|
||||
#define Z_OBJ_HT_PP(zval_p) Z_OBJ_HT(**zval_p)
|
||||
#define Z_OBJ_HANDLER_PP(zval_p, h) Z_OBJ_HANDLER(**zval_p, h)
|
||||
#define Z_UNIVAL_PP(zval_pp) Z_UNIVAL(**zval_pp)
|
||||
#define Z_UNILEN_PP(zval_pp) Z_UNILEN(**zval_pp)
|
||||
|
||||
#define Z_TYPE(zval) (zval).type
|
||||
#define Z_TYPE_P(zval_p) Z_TYPE(*zval_p)
|
||||
|
@ -43,7 +43,7 @@ zend_class_entry *reflection_extension_ptr;
|
||||
/* Method macros */
|
||||
#define METHOD_NOTSTATIC \
|
||||
if (!this_ptr) { \
|
||||
zend_error(E_ERROR, "%s() cannot be called statically", get_active_function_name(TSRMLS_C)); \
|
||||
zend_error(E_ERROR, "%v() cannot be called statically", get_active_function_name(TSRMLS_C)); \
|
||||
return; \
|
||||
} \
|
||||
|
||||
@ -233,7 +233,7 @@ static zend_object_value reflection_objects_new(zend_class_entry *class_type TSR
|
||||
intern->free_ptr = 0;
|
||||
|
||||
ALLOC_HASHTABLE(intern->zo.properties);
|
||||
zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
retval.handle = zend_objects_store_put(intern, NULL, reflection_free_objects_storage, reflection_objects_clone TSRMLS_CC);
|
||||
retval.handlers = &reflection_object_handlers;
|
||||
@ -297,17 +297,17 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
|
||||
}
|
||||
string_printf(str, "class ");
|
||||
}
|
||||
string_write(str, ce->name, ce->name_length);
|
||||
string_printf(str, "%v", ce->name);
|
||||
if (ce->parent) {
|
||||
string_printf(str, " extends %s", ce->parent->name);
|
||||
string_printf(str, " extends %v", ce->parent->name);
|
||||
}
|
||||
|
||||
if (ce->num_interfaces) {
|
||||
zend_uint i;
|
||||
|
||||
string_printf(str, " implements %s", ce->interfaces[0]->name);
|
||||
string_printf(str, " implements %v", ce->interfaces[0]->name);
|
||||
for (i = 1; i < ce->num_interfaces; ++i) {
|
||||
string_printf(str, ", %s", ce->interfaces[i]->name);
|
||||
string_printf(str, ", %v", ce->interfaces[i]->name);
|
||||
}
|
||||
}
|
||||
string_printf(str, " ] {\n");
|
||||
@ -540,7 +540,7 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg
|
||||
string_printf(str, "<required> ");
|
||||
}
|
||||
if (arg_info->class_name) {
|
||||
string_printf(str, "%s ", arg_info->class_name);
|
||||
string_printf(str, "%v ", arg_info->class_name);
|
||||
if (arg_info->allow_null) {
|
||||
string_printf(str, "or NULL ");
|
||||
}
|
||||
@ -554,7 +554,7 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg
|
||||
string_write(str, "&", sizeof("&")-1);
|
||||
}
|
||||
if (arg_info->name) {
|
||||
string_printf(str, "$%s", arg_info->name);
|
||||
string_printf(str, "$%v", arg_info->name);
|
||||
} else {
|
||||
string_printf(str, "$param%d", offset);
|
||||
}
|
||||
@ -671,7 +671,7 @@ static void _function_string(string *str, zend_function *fptr, char* indent TSRM
|
||||
if (fptr->op_array.return_reference) {
|
||||
string_printf(str, "&");
|
||||
}
|
||||
string_printf(str, "%s ] {\n", fptr->common.function_name);
|
||||
string_printf(str, "%v ] {\n", fptr->common.function_name);
|
||||
/* The information where a function is declared is only available for user classes */
|
||||
if (fptr->type == ZEND_USER_FUNCTION) {
|
||||
string_printf(str, "%s @@ %s %d - %d\n", indent,
|
||||
@ -720,8 +720,8 @@ static void _property_string(string *str, zend_property_info *prop, char *prop_n
|
||||
string_printf(str, "static ");
|
||||
}
|
||||
|
||||
zend_unmangle_property_name(prop->name, &class_name, &prop_name);
|
||||
string_printf(str, "$%s", prop_name);
|
||||
zend_u_unmangle_property_name(UG(unicode)?IS_UNICODE:IS_STRING, prop->name, &class_name, &prop_name);
|
||||
string_printf(str, "$%v", prop_name);
|
||||
}
|
||||
|
||||
string_printf(str, " ]\n");
|
||||
@ -865,7 +865,11 @@ ZEND_API void zend_reflection_class_factory(zend_class_entry *ce, zval *object T
|
||||
zval *name;
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(name, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
|
||||
}
|
||||
reflection_instanciate(reflection_class_ptr, object TSRMLS_CC);
|
||||
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
intern->ptr = ce;
|
||||
@ -912,7 +916,11 @@ static void reflection_parameter_factory(zend_function *fptr, struct _zend_arg_i
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
if (arg_info->name) {
|
||||
ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(name, (UChar*)arg_info->name, arg_info->name_len, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
|
||||
}
|
||||
} else {
|
||||
ZVAL_NULL(name);
|
||||
}
|
||||
@ -937,7 +945,11 @@ static void reflection_function_factory(zend_function *function, zval *object TS
|
||||
zval *name;
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, function->common.function_name, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)function->common.function_name, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, function->common.function_name, 1);
|
||||
}
|
||||
|
||||
reflection_instanciate(reflection_function_ptr, object TSRMLS_CC);
|
||||
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
@ -956,9 +968,14 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho
|
||||
zval *classname;
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, method->common.function_name, 1);
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)method->common.function_name, 1);
|
||||
ZVAL_UNICODEL(classname, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, method->common.function_name, 1);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
}
|
||||
reflection_instanciate(reflection_method_ptr, object TSRMLS_CC);
|
||||
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
intern->ptr = method;
|
||||
@ -978,7 +995,7 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info
|
||||
property_reference *reference;
|
||||
char *class_name, *prop_name;
|
||||
|
||||
zend_unmangle_property_name(prop->name, &class_name, &prop_name);
|
||||
zend_u_unmangle_property_name(UG(unicode)?IS_UNICODE:IS_STRING, prop->name, &class_name, &prop_name);
|
||||
|
||||
if (!(prop->flags & ZEND_ACC_PRIVATE)) {
|
||||
/* we have to seach the class hierarchy for this (implicit) public or protected property */
|
||||
@ -997,10 +1014,14 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, prop_name, 1);
|
||||
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)prop_name, 1);
|
||||
ZVAL_UNICODEL(classname, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, prop_name, 1);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
}
|
||||
|
||||
reflection_instanciate(reflection_property_ptr, object TSRMLS_CC);
|
||||
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
@ -1144,7 +1165,7 @@ ZEND_METHOD(reflection, export)
|
||||
}
|
||||
|
||||
if (!retval_ptr) {
|
||||
zend_error(E_WARNING, "%s::__toString() did not return anything", Z_OBJCE_P(object)->name);
|
||||
zend_error(E_WARNING, "%v::__toString() did not return anything", Z_OBJCE_P(object)->name);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@ -1211,13 +1232,15 @@ ZEND_METHOD(reflection_function, __construct)
|
||||
{
|
||||
zval *name;
|
||||
zval *object;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
reflection_object *intern;
|
||||
zend_function *fptr;
|
||||
char *name_str;
|
||||
int name_len;
|
||||
zend_uchar type;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &name_str, &name_len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1226,17 +1249,20 @@ ZEND_METHOD(reflection_function, __construct)
|
||||
if (intern == NULL) {
|
||||
return;
|
||||
}
|
||||
lcname = do_alloca(name_len + 1);
|
||||
zend_str_tolower_copy(lcname, name_str, name_len);
|
||||
if (zend_hash_find(EG(function_table), lcname, name_len + 1, (void **)&fptr) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
lcname = zend_u_str_case_fold(type, name_str, name_len, 1, &lcname_len);
|
||||
if (zend_u_hash_find(EG(function_table), type, lcname, lcname_len + 1, (void **)&fptr) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Function %s() does not exist", name_str);
|
||||
"Function %R() does not exist", type, name_str);
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, fptr->common.function_name, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)fptr->common.function_name, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, fptr->common.function_name, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
|
||||
intern->ptr = fptr;
|
||||
intern->free_ptr = 0;
|
||||
@ -1421,7 +1447,7 @@ ZEND_METHOD(reflection_function, invoke)
|
||||
|
||||
if (result == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Invocation of function %s() failed", fptr->common.function_name);
|
||||
"Invocation of function %v() failed", fptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1485,7 +1511,7 @@ ZEND_METHOD(reflection_function, invokeArgs)
|
||||
|
||||
if (result == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Invocation of function %s() failed", fptr->common.function_name);
|
||||
"Invocation of function %v() failed", fptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1598,19 +1624,20 @@ ZEND_METHOD(reflection_parameter, __construct)
|
||||
|
||||
/* First, find the function */
|
||||
switch (Z_TYPE_P(reference)) {
|
||||
case IS_UNICODE:
|
||||
case IS_STRING: {
|
||||
char *lcname;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
|
||||
convert_to_string_ex(&reference);
|
||||
lcname = do_alloca(Z_STRLEN_P(reference) + 1);
|
||||
zend_str_tolower_copy(lcname, Z_STRVAL_P(reference), Z_STRLEN_P(reference));
|
||||
if (zend_hash_find(EG(function_table), lcname, (int) Z_STRLEN_P(reference) + 1, (void**) &fptr) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
convert_to_text_ex(&reference);
|
||||
lcname = zend_u_str_case_fold(Z_TYPE_P(reference), Z_STRVAL_P(reference), Z_STRLEN_P(reference), 1, &lcname_len);
|
||||
if (zend_u_hash_find(EG(function_table), Z_TYPE_P(reference), lcname, lcname_len + 1, (void**) &fptr) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Function %s() does not exist", Z_STRVAL_P(reference));
|
||||
"Function %R() does not exist", Z_TYPE_P(reference), Z_STRVAL_P(reference));
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1618,7 +1645,8 @@ ZEND_METHOD(reflection_parameter, __construct)
|
||||
zval **classref;
|
||||
zval **method;
|
||||
zend_class_entry **pce;
|
||||
char *lcname;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
|
||||
if ((zend_hash_index_find(Z_ARRVAL_P(reference), 0, (void **) &classref) == FAILURE)
|
||||
|| (zend_hash_index_find(Z_ARRVAL_P(reference), 1, (void **) &method) == FAILURE)) {
|
||||
@ -1629,25 +1657,24 @@ ZEND_METHOD(reflection_parameter, __construct)
|
||||
if (Z_TYPE_PP(classref) == IS_OBJECT) {
|
||||
ce = Z_OBJCE_PP(classref);
|
||||
} else {
|
||||
convert_to_string_ex(classref);
|
||||
if (zend_lookup_class(Z_STRVAL_PP(classref), Z_STRLEN_PP(classref), &pce TSRMLS_CC) == FAILURE) {
|
||||
convert_to_text_ex(classref);
|
||||
if (zend_u_lookup_class(Z_TYPE_PP(classref), Z_UNIVAL_PP(classref), Z_UNILEN_PP(classref), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Class %s does not exist", Z_STRVAL_PP(classref));
|
||||
"Class %R does not exist", Z_TYPE_PP(classref), Z_UNIVAL_PP(classref));
|
||||
return;
|
||||
}
|
||||
ce = *pce;
|
||||
}
|
||||
|
||||
convert_to_string_ex(method);
|
||||
lcname = do_alloca(Z_STRLEN_PP(method) + 1);
|
||||
zend_str_tolower_copy(lcname, Z_STRVAL_PP(method), Z_STRLEN_PP(method));
|
||||
if (zend_hash_find(&ce->function_table, lcname, (int)(Z_STRLEN_PP(method) + 1), (void **) &fptr) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
convert_to_text_ex(method);
|
||||
lcname = zend_u_str_case_fold(Z_TYPE_PP(method), Z_UNIVAL_PP(method), Z_UNILEN_PP(method), 1, &lcname_len);
|
||||
if (zend_u_hash_find(&ce->function_table, Z_TYPE_PP(method), lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Method %s::%s() does not exist", Z_STRVAL_PP(classref), Z_STRVAL_PP(method));
|
||||
"Method %R::%R() does not exist", Z_TYPE_PP(classref), Z_UNIVAL_PP(classref), Z_TYPE_PP(method), Z_UNIVAL_PP(method));
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1683,7 +1710,11 @@ ZEND_METHOD(reflection_parameter, __construct)
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
if (arg_info[position].name) {
|
||||
ZVAL_STRINGL(name, arg_info[position].name, arg_info[position].name_len, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(name, (UChar*)arg_info[position].name, arg_info[position].name_len, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(name, arg_info[position].name, arg_info[position].name_len, 1);
|
||||
}
|
||||
} else {
|
||||
ZVAL_NULL(name);
|
||||
}
|
||||
@ -1739,15 +1770,16 @@ ZEND_METHOD(reflection_parameter, getClass)
|
||||
RETURN_NULL();
|
||||
} else {
|
||||
zend_class_entry **pce;
|
||||
char *lcname = do_alloca(param->arg_info->class_name_len + 1);
|
||||
zend_str_tolower_copy(lcname, param->arg_info->class_name, param->arg_info->class_name_len);
|
||||
if (zend_hash_find(EG(class_table), lcname, param->arg_info->class_name_len + 1, (void **) &pce) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
unsigned int lcname_len;
|
||||
char *lcname = zend_u_str_case_fold(UG(unicode)?IS_UNICODE:IS_STRING, param->arg_info->class_name, param->arg_info->class_name_len, 0, &lcname_len);
|
||||
|
||||
if (zend_u_hash_find(EG(class_table), UG(unicode)?IS_UNICODE:IS_STRING, lcname, lcname_len + 1, (void **) &pce) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Class %s does not exist", param->arg_info->class_name);
|
||||
"Class %v does not exist", param->arg_info->class_name);
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
zend_reflection_class_factory(*pce, return_value TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
@ -1884,14 +1916,16 @@ ZEND_METHOD(reflection_method, __construct)
|
||||
zval *name, *classname;
|
||||
zval *object;
|
||||
reflection_object *intern;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
zend_class_entry **pce;
|
||||
zend_class_entry *ce;
|
||||
zend_function *mptr;
|
||||
char *name_str;
|
||||
int name_len;
|
||||
zend_uchar type;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zt", &classname, &name_str, &name_len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1904,9 +1938,10 @@ ZEND_METHOD(reflection_method, __construct)
|
||||
/* Find the class entry */
|
||||
switch (Z_TYPE_P(classname)) {
|
||||
case IS_STRING:
|
||||
if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
|
||||
case IS_UNICODE:
|
||||
if (zend_u_lookup_class(Z_TYPE_P(classname), Z_UNIVAL_P(classname), Z_UNILEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Class %s does not exist", Z_STRVAL_P(classname));
|
||||
"Class %v does not exist", Z_UNIVAL_P(classname));
|
||||
return;
|
||||
}
|
||||
ce = *pce;
|
||||
@ -1922,22 +1957,29 @@ ZEND_METHOD(reflection_method, __construct)
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(classname, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
|
||||
|
||||
lcname = do_alloca(name_len + 1);
|
||||
zend_str_tolower_copy(lcname, name_str, name_len);
|
||||
lcname = zend_u_str_case_fold(type, name_str, name_len, 1, &lcname_len);
|
||||
|
||||
if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) &mptr) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
if (zend_u_hash_find(&ce->function_table, type, lcname, lcname_len + 1, (void **) &mptr) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Method %s::%s() does not exist", ce->name, name_str);
|
||||
"Method %v::%R() does not exist", ce->name, type, name_str);
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, mptr->common.function_name, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)mptr->common.function_name, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, mptr->common.function_name, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
|
||||
intern->ptr = mptr;
|
||||
intern->free_ptr = 0;
|
||||
@ -1989,11 +2031,11 @@ ZEND_METHOD(reflection_method, invoke)
|
||||
(mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) {
|
||||
if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke abstract method %s::%s()",
|
||||
"Trying to invoke abstract method %v::%v()",
|
||||
mptr->common.scope->name, mptr->common.function_name);
|
||||
} else {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke %s method %s::%s() from scope %s",
|
||||
"Trying to invoke %s method %v::%v() from scope %v",
|
||||
mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
|
||||
mptr->common.scope->name, mptr->common.function_name,
|
||||
Z_OBJCE_P(getThis())->name);
|
||||
@ -2054,7 +2096,7 @@ ZEND_METHOD(reflection_method, invoke)
|
||||
|
||||
if (result == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
|
||||
"Invocation of method %v::%v() failed", mptr->common.scope->name, mptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2092,11 +2134,11 @@ ZEND_METHOD(reflection_method, invokeArgs)
|
||||
(mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) {
|
||||
if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke abstract method %s::%s",
|
||||
"Trying to invoke abstract method %v::%v",
|
||||
mptr->common.scope->name, mptr->common.function_name);
|
||||
} else {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke %s method %s::%s from scope %s",
|
||||
"Trying to invoke %s method %v::%v from scope %v",
|
||||
mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
|
||||
mptr->common.scope->name, mptr->common.function_name,
|
||||
Z_OBJCE_P(getThis())->name);
|
||||
@ -2123,7 +2165,7 @@ ZEND_METHOD(reflection_method, invokeArgs)
|
||||
if (!object) {
|
||||
efree(params);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke non static method %s::%s without an object",
|
||||
"Trying to invoke non static method %v::%v without an object",
|
||||
mptr->common.scope->name, mptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
@ -2158,7 +2200,7 @@ ZEND_METHOD(reflection_method, invokeArgs)
|
||||
|
||||
if (result == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
|
||||
"Invocation of method %v::%v() failed", mptr->common.scope->name, mptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2308,7 +2350,11 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob
|
||||
|
||||
if (Z_TYPE_P(argument) == IS_OBJECT) {
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(classname, (UChar*)Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
|
||||
intern->ptr = Z_OBJCE_P(argument);
|
||||
if (is_object) {
|
||||
@ -2317,7 +2363,7 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob
|
||||
}
|
||||
} else {
|
||||
convert_to_string_ex(&argument);
|
||||
if (zend_lookup_class(Z_STRVAL_P(argument), Z_STRLEN_P(argument), &ce TSRMLS_CC) == FAILURE) {
|
||||
if (zend_u_lookup_class(Z_TYPE_P(argument), Z_UNIVAL_P(argument), Z_UNILEN_P(argument), &ce TSRMLS_CC) == FAILURE) {
|
||||
if (!EG(exception)) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", Z_STRVAL_P(argument));
|
||||
}
|
||||
@ -2325,7 +2371,11 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(classname, (UChar*)((*ce)->name), (*ce)->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
|
||||
|
||||
intern->ptr = *ce;
|
||||
@ -2613,17 +2663,19 @@ ZEND_METHOD(reflection_class, hasMethod)
|
||||
{
|
||||
reflection_object *intern;
|
||||
zend_class_entry *ce;
|
||||
unsigned int lc_name_len;
|
||||
char *name, *lc_name;
|
||||
int name_len;
|
||||
zend_uchar type;
|
||||
|
||||
METHOD_NOTSTATIC;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &name, &name_len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
GET_REFLECTION_OBJECT_PTR(ce);
|
||||
lc_name = zend_str_tolower_dup(name, name_len);
|
||||
if (zend_hash_exists(&ce->function_table, lc_name, name_len + 1)) {
|
||||
lc_name = zend_u_str_case_fold(type, name, name_len, 1, &lc_name_len);
|
||||
if (zend_u_hash_exists(&ce->function_table, type, lc_name, lc_name_len + 1)) {
|
||||
efree(lc_name);
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
@ -2640,23 +2692,25 @@ ZEND_METHOD(reflection_class, getMethod)
|
||||
reflection_object *intern;
|
||||
zend_class_entry *ce;
|
||||
zend_function *mptr;
|
||||
unsigned int lc_name_len;
|
||||
char *name, *lc_name;
|
||||
int name_len;
|
||||
zend_uchar type;
|
||||
|
||||
METHOD_NOTSTATIC;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &name, &name_len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
GET_REFLECTION_OBJECT_PTR(ce);
|
||||
lc_name = zend_str_tolower_dup(name, name_len);
|
||||
if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) &mptr) == SUCCESS) {
|
||||
lc_name = zend_u_str_case_fold(type, name, name_len, 1, &lc_name_len);
|
||||
if (zend_u_hash_find(&ce->function_table, type, lc_name, lc_name_len + 1, (void**) &mptr) == SUCCESS) {
|
||||
reflection_method_factory(ce, mptr, return_value TSRMLS_CC);
|
||||
efree(lc_name);
|
||||
} else {
|
||||
efree(lc_name);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Method %s does not exist", name);
|
||||
"Method %R does not exist", type, name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2989,7 +3043,7 @@ ZEND_METHOD(reflection_class, newInstance)
|
||||
zend_fcall_info_cache fcc;
|
||||
|
||||
if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %v", ce->name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3017,7 +3071,7 @@ ZEND_METHOD(reflection_class, newInstance)
|
||||
if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
|
||||
efree(params);
|
||||
zval_ptr_dtor(&retval_ptr);
|
||||
zend_error(E_WARNING, "Invocation of %s's constructor failed", ce->name);
|
||||
zend_error(E_WARNING, "Invocation of %v's constructor failed", ce->name);
|
||||
RETURN_NULL();
|
||||
}
|
||||
if (retval_ptr) {
|
||||
@ -3089,7 +3143,8 @@ ZEND_METHOD(reflection_class, isSubclassOf)
|
||||
|
||||
switch(class_name->type) {
|
||||
case IS_STRING:
|
||||
if (zend_lookup_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), &pce TSRMLS_CC) == FAILURE) {
|
||||
case IS_UNICODE:
|
||||
if (zend_u_lookup_class(Z_TYPE_P(class_name), Z_UNIVAL_P(class_name), Z_UNILEN_P(class_name), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Interface %s does not exist", Z_STRVAL_P(class_name));
|
||||
return;
|
||||
@ -3135,7 +3190,8 @@ ZEND_METHOD(reflection_class, implementsInterface)
|
||||
|
||||
switch(interface->type) {
|
||||
case IS_STRING:
|
||||
if (zend_lookup_class(Z_STRVAL_P(interface), Z_STRLEN_P(interface), &pce TSRMLS_CC) == FAILURE) {
|
||||
case IS_UNICODE:
|
||||
if (zend_u_lookup_class(Z_TYPE_P(interface), Z_UNIVAL_P(interface), Z_UNILEN_P(interface), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Interface %s does not exist", Z_STRVAL_P(interface));
|
||||
return;
|
||||
@ -3161,7 +3217,7 @@ ZEND_METHOD(reflection_class, implementsInterface)
|
||||
|
||||
if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Interface %s is a Class", interface_ce->name);
|
||||
"Interface %v is a Class", interface_ce->name);
|
||||
return;
|
||||
}
|
||||
RETURN_BOOL(instanceof_function(ce, interface_ce TSRMLS_CC));
|
||||
@ -3267,7 +3323,8 @@ ZEND_METHOD(reflection_property, __construct)
|
||||
/* Find the class entry */
|
||||
switch (Z_TYPE_P(classname)) {
|
||||
case IS_STRING:
|
||||
if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
|
||||
case IS_UNICODE:
|
||||
if (zend_u_lookup_class(Z_TYPE_P(classname), Z_UNIVAL_P(classname), Z_UNILEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Class %s does not exist", Z_STRVAL_P(classname));
|
||||
return;
|
||||
@ -3286,7 +3343,7 @@ ZEND_METHOD(reflection_property, __construct)
|
||||
|
||||
if (zend_hash_find(&ce->properties_info, name_str, name_len + 1, (void **) &property_info) == FAILURE || (property_info->flags & ZEND_ACC_SHADOW)) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Property %s::$%s does not exist", ce->name, name_str);
|
||||
"Property %v::$%s does not exist", ce->name, name_str);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3307,12 +3364,20 @@ ZEND_METHOD(reflection_property, __construct)
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(classname, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
|
||||
|
||||
zend_unmangle_property_name(property_info->name, &class_name, &prop_name);
|
||||
zend_u_unmangle_property_name(UG(unicode)?IS_UNICODE:IS_STRING, property_info->name, &class_name, &prop_name);
|
||||
MAKE_STD_ZVAL(propname);
|
||||
ZVAL_STRING(propname, prop_name, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(propname, (UChar*)prop_name, 1);
|
||||
} else {
|
||||
ZVAL_STRING(propname, prop_name, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &propname, sizeof(zval *), NULL);
|
||||
|
||||
reference = (property_reference*) emalloc(sizeof(property_reference));
|
||||
@ -3421,6 +3486,7 @@ ZEND_METHOD(reflection_property, getValue)
|
||||
property_reference *ref;
|
||||
zval *object;
|
||||
zval **member= NULL;
|
||||
zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
METHOD_NOTSTATIC;
|
||||
GET_REFLECTION_OBJECT_PTR(ref);
|
||||
@ -3432,16 +3498,16 @@ ZEND_METHOD(reflection_property, getValue)
|
||||
|
||||
if ((ref->prop->flags & ZEND_ACC_STATIC)) {
|
||||
zend_update_class_constants(intern->ce TSRMLS_CC);
|
||||
if (zend_hash_quick_find(intern->ce->static_members, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %s", ref->prop->name);
|
||||
if (zend_u_hash_quick_find(intern->ce->static_members, utype, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %v", ref->prop->name);
|
||||
/* Bails out */
|
||||
}
|
||||
} else {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
if (zend_hash_quick_find(Z_OBJPROP_P(object), ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %s", ref->prop->name);
|
||||
if (zend_u_hash_quick_find(Z_OBJPROP_P(object), utype, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %v", ref->prop->name);
|
||||
/* Bails out */
|
||||
}
|
||||
}
|
||||
@ -3463,6 +3529,7 @@ ZEND_METHOD(reflection_property, setValue)
|
||||
int setter_done = 0;
|
||||
zval *tmp;
|
||||
HashTable *prop_table;
|
||||
zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
METHOD_NOTSTATIC;
|
||||
GET_REFLECTION_OBJECT_PTR(ref);
|
||||
@ -3486,8 +3553,8 @@ ZEND_METHOD(reflection_property, setValue)
|
||||
prop_table = Z_OBJPROP_P(object);
|
||||
}
|
||||
|
||||
if (zend_hash_quick_find(prop_table, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &variable_ptr) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %s", ref->prop->name);
|
||||
if (zend_u_hash_quick_find(prop_table, utype, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &variable_ptr) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %v", ref->prop->name);
|
||||
/* Bails out */
|
||||
}
|
||||
if (*variable_ptr == value) {
|
||||
@ -3510,7 +3577,7 @@ ZEND_METHOD(reflection_property, setValue)
|
||||
if (PZVAL_IS_REF(value)) {
|
||||
SEPARATE_ZVAL(&value);
|
||||
}
|
||||
zend_hash_quick_update(prop_table, ref->prop->name, ref->prop->name_length+1, ref->prop->h, &value, sizeof(zval *), (void **) &foo);
|
||||
zend_u_hash_quick_update(prop_table, utype, ref->prop->name, ref->prop->name_length+1, ref->prop->h, &value, sizeof(zval *), (void **) &foo);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@ -3943,12 +4010,13 @@ static zend_object_handlers *zend_std_obj_handlers;
|
||||
/* {{{ _reflection_write_property */
|
||||
static void _reflection_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
|
||||
{
|
||||
if (Z_TYPE_P(member) == IS_STRING
|
||||
&& zend_hash_exists(&Z_OBJCE_P(object)->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
|
||||
&& (!strcmp(Z_STRVAL_P(member), "name") || !strcmp(Z_STRVAL_P(member), "class")))
|
||||
if ((Z_TYPE_P(member) == IS_STRING || Z_TYPE_P(member) == IS_UNICODE)
|
||||
&& zend_u_hash_exists(&Z_OBJCE_P(object)->default_properties, Z_TYPE_P(member), Z_UNIVAL_P(member), Z_UNILEN_P(member)+1)
|
||||
&& (ZEND_U_EQUAL(Z_TYPE_P(member), Z_UNIVAL_P(member), Z_UNILEN_P(member), "name", sizeof("name")-1) ||
|
||||
ZEND_U_EQUAL(Z_TYPE_P(member), Z_UNIVAL_P(member), Z_UNILEN_P(member), "class", sizeof("class")-1)))
|
||||
{
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Cannot set read-only property %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member));
|
||||
"Cannot set read-only property %v::$%R", Z_OBJCE_P(object)->name, Z_TYPE_P(member), Z_UNIVAL_P(member));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4038,6 +4106,20 @@ ZEND_API void zend_register_reflection_api(TSRMLS_D) {
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void init_reflection_api(TSRMLS_D)
|
||||
{
|
||||
reflection_exception_ptr = zend_get_named_class_entry("ReflectionException", sizeof("ReflectionException")-1 TSRMLS_CC);
|
||||
reflection_ptr = zend_get_named_class_entry("Reflection", sizeof("Reflection")-1 TSRMLS_CC);
|
||||
reflector_ptr = zend_get_named_class_entry("Reflector", sizeof("Reflector")-1 TSRMLS_CC);
|
||||
reflection_function_ptr = zend_get_named_class_entry("ReflectionFunction", sizeof("ReflectionFunction")-1 TSRMLS_CC);
|
||||
reflection_parameter_ptr = zend_get_named_class_entry("ReflectionParameter", sizeof("ReflectionParameter")-1 TSRMLS_CC);
|
||||
reflection_method_ptr = zend_get_named_class_entry("ReflectionMethod", sizeof("ReflectionMethod")-1 TSRMLS_CC);
|
||||
reflection_class_ptr = zend_get_named_class_entry("ReflectionClass", sizeof("ReflectionClass")-1 TSRMLS_CC);
|
||||
reflection_object_ptr = zend_get_named_class_entry("ReflectionObject", sizeof("ReflectionObject")-1 TSRMLS_CC);
|
||||
reflection_property_ptr = zend_get_named_class_entry("ReflectionProperty", sizeof("ReflectionProperty")-1 TSRMLS_CC);
|
||||
reflection_extension_ptr = zend_get_named_class_entry("ReflectionExtension", sizeof("ReflectionExtension")-1 TSRMLS_CC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -26,6 +26,8 @@ BEGIN_EXTERN_C()
|
||||
ZEND_API void zend_register_reflection_api(TSRMLS_D);
|
||||
ZEND_API void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC);
|
||||
|
||||
void init_reflection_api(TSRMLS_D);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
|
@ -90,6 +90,8 @@
|
||||
*/
|
||||
|
||||
#include <zend_strtod.h>
|
||||
#include <unicode/utypes.h>
|
||||
#include <unicode/ustdio.h>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
@ -1778,3 +1780,23 @@ zend_strtod
|
||||
result = sign ? -value(rv) : value(rv);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* UTODO: someone can reimplement this using the code above, if they really want to. */
|
||||
ZEND_API double zend_u_strtod(const UChar *nptr, UChar **endptr)
|
||||
{
|
||||
double value;
|
||||
int32_t num_conv = 0, num_read = 0;
|
||||
|
||||
num_conv = u_sscanf(nptr, "%f%n", &value, &num_read);
|
||||
if (num_conv != EOF) {
|
||||
if (endptr != 0) {
|
||||
*endptr = (UChar *)nptr + num_read;
|
||||
}
|
||||
return value;
|
||||
} else {
|
||||
if (endptr != 0) {
|
||||
*endptr = (UChar *)nptr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
122
Zend/zend_strtol.c
Normal file
122
Zend/zend_strtol.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unicode/utypes.h>
|
||||
#include <unicode/uchar.h>
|
||||
|
||||
/*
|
||||
* Convert a Unicode string to a long integer.
|
||||
*
|
||||
* Ignores `locale' stuff.
|
||||
*/
|
||||
long
|
||||
zend_u_strtol(nptr, endptr, base)
|
||||
const UChar *nptr;
|
||||
UChar **endptr;
|
||||
register int base;
|
||||
{
|
||||
register const UChar *s = nptr;
|
||||
register unsigned long acc;
|
||||
register UChar c;
|
||||
register unsigned long cutoff;
|
||||
register int neg = 0, any, cutlim;
|
||||
register int32_t val;
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
do {
|
||||
c = *s++;
|
||||
} while (u_isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else if (c == '+')
|
||||
c = *s++;
|
||||
if ((base == 0 || base == 16) &&
|
||||
(c == '0')
|
||||
&& (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = (c == '0') ? 8 : 10;
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for longs is
|
||||
* [-2147483648..2147483647] and the input base is 10,
|
||||
* cutoff will be set to 214748364 and cutlim to either
|
||||
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
|
||||
* a value > 214748364, or equal but the next digit is > 7 (or 8),
|
||||
* the number is too big, and we will return a range error.
|
||||
*
|
||||
* Set any if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
|
||||
cutlim = cutoff % (unsigned long)base;
|
||||
cutoff /= (unsigned long)base;
|
||||
for (acc = 0, any = 0;; c = *s++) {
|
||||
if ((val = u_digit(c, base)) < 0)
|
||||
break;
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += val;
|
||||
}
|
||||
}
|
||||
if (any < 0) {
|
||||
acc = neg ? LONG_MIN : LONG_MAX;
|
||||
errno = ERANGE;
|
||||
} else if (neg)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (UChar *)(any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
597
Zend/zend_unicode.c
Normal file
597
Zend/zend_unicode.c
Normal file
@ -0,0 +1,597 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2004 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andrei Zmievski <andrei@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "zend.h"
|
||||
#include "zend_globals.h"
|
||||
#include "zend_operators.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_unicode.h"
|
||||
#include <unicode/unorm.h>
|
||||
|
||||
#ifdef ZTS
|
||||
ZEND_API ts_rsrc_id unicode_globals_id;
|
||||
#else
|
||||
ZEND_API zend_unicode_globals unicode_globals;
|
||||
#endif
|
||||
|
||||
static void zend_from_unicode_substitute_cb(
|
||||
const void *context,
|
||||
UConverterFromUnicodeArgs *toUArgs,
|
||||
const char *codeUnits,
|
||||
int32_t length,
|
||||
UConverterCallbackReason reason,
|
||||
UErrorCode *err
|
||||
)
|
||||
{
|
||||
if (context == NULL) {
|
||||
if (reason > UCNV_IRREGULAR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
*err = U_ZERO_ERROR;
|
||||
//ucnv_cbFromUWriteSub(fromArgs, 0, err);
|
||||
return;
|
||||
} else if (*((char*)context)=='i') {
|
||||
if (reason != UCNV_UNASSIGNED)
|
||||
{
|
||||
/* the caller must have set
|
||||
* the error code accordingly
|
||||
*/
|
||||
return;
|
||||
} else {
|
||||
*err = U_ZERO_ERROR;
|
||||
//ucnv_cbFromUWriteSub(fromArgs, 0, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* {{{ zend_set_converter_error_mode */
|
||||
void zend_set_converter_error_mode(UConverter *conv, uint8_t error_mode)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
switch (error_mode) {
|
||||
case ZEND_FROM_U_ERROR_STOP:
|
||||
ucnv_setFromUCallBack(conv, UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, &status);
|
||||
break;
|
||||
|
||||
case ZEND_FROM_U_ERROR_SKIP:
|
||||
ucnv_setFromUCallBack(conv, UCNV_FROM_U_CALLBACK_SKIP, UCNV_SKIP_STOP_ON_ILLEGAL, NULL, NULL, &status);
|
||||
break;
|
||||
|
||||
case ZEND_FROM_U_ERROR_ESCAPE:
|
||||
/* UTODO replace with custom callback for various substitution patterns */
|
||||
ucnv_setFromUCallBack(conv, UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_UNICODE, NULL, NULL, &status);
|
||||
break;
|
||||
|
||||
case ZEND_FROM_U_ERROR_SUBST:
|
||||
ucnv_setFromUCallBack(conv, UCNV_FROM_U_CALLBACK_SUBSTITUTE, UCNV_SKIP_STOP_ON_ILLEGAL, NULL, NULL, &status);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_set_converter_subst_char */
|
||||
void zend_set_converter_subst_char(UConverter *conv, UChar *subst_char, int8_t subst_char_len)
|
||||
{
|
||||
char dest[8];
|
||||
int8_t dest_len = 8;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UErrorCode temp = U_ZERO_ERROR;
|
||||
const void *old_context;
|
||||
UConverterFromUCallback old_cb;
|
||||
|
||||
if (!subst_char_len)
|
||||
return;
|
||||
|
||||
ucnv_setFromUCallBack(conv, UCNV_FROM_U_CALLBACK_STOP, NULL, &old_cb, &old_context, &temp);
|
||||
dest_len = ucnv_fromUChars(conv, dest, dest_len, subst_char, subst_char_len, &status);
|
||||
ucnv_setFromUCallBack(conv, old_cb, old_context, NULL, NULL, &temp);
|
||||
if (U_FAILURE(status)) {
|
||||
zend_error(E_WARNING, "Could not set substitution character for the converter");
|
||||
return;
|
||||
}
|
||||
ucnv_setSubstChars(conv, dest, dest_len, &status);
|
||||
if (status == U_ILLEGAL_ARGUMENT_ERROR) {
|
||||
zend_error(E_WARNING, "Substitution character byte sequence is too short or long for this converter");
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_set_converter_encoding */
|
||||
int zend_set_converter_encoding(UConverter **converter, const char *encoding)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UConverter *new_converter = NULL;
|
||||
|
||||
if (!converter) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The specified encoding might be the same as converter's existing one,
|
||||
* which results in a no-op.
|
||||
*/
|
||||
if (*converter && encoding && encoding[0]) {
|
||||
const char *current = ucnv_getName(*converter, &status);
|
||||
status = U_ZERO_ERROR; /* reset error */
|
||||
if (!ucnv_compareNames(current, encoding)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If encoding is NULL, ucnv_open() will return a converter based on
|
||||
* the default platform encoding as determined by ucnv_getDefaultName().
|
||||
*/
|
||||
new_converter = ucnv_open(encoding, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (*converter) {
|
||||
ucnv_close(*converter);
|
||||
}
|
||||
*converter = new_converter;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_copy_converter */
|
||||
int zend_copy_converter(UConverter **target, UConverter *source)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
const char *encoding;
|
||||
|
||||
assert(source != NULL);
|
||||
|
||||
encoding = ucnv_getName(source, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return zend_set_converter_encoding(target, encoding);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_convert_to_unicode */
|
||||
ZEND_API void zend_convert_to_unicode(UConverter *conv, UChar **target, int32_t *target_len, const char *source, int32_t source_len, UErrorCode *status)
|
||||
{
|
||||
UChar *buffer = NULL;
|
||||
UChar *output;
|
||||
int32_t buffer_len = 0;
|
||||
int32_t converted = 0;
|
||||
const char *input = source;
|
||||
UConverterType conv_type;
|
||||
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ucnv_resetToUnicode(conv);
|
||||
conv_type = ucnv_getType(conv);
|
||||
|
||||
switch (conv_type) {
|
||||
case UCNV_SBCS:
|
||||
case UCNV_LATIN_1:
|
||||
case UCNV_US_ASCII:
|
||||
/*
|
||||
* For single-byte charsets, 1 input byte = 1 output UChar
|
||||
*/
|
||||
buffer_len = source_len;
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* Initial estimate: 1.25 UChar's for every 2 source bytes + 2 (past a
|
||||
* certain limit (2)). The rationale behind this is that (atleast
|
||||
* in the case of GB2312) it is possible that there are single byte
|
||||
* characters in the input string. By using an GD2312 text as
|
||||
* example it seemed that a value of 1.25 allowed for as little
|
||||
* re-allocations as possible without over estimating the buffer
|
||||
* too much. In case there is a lot of single-byte characters
|
||||
* around a single multi-byte character this estimation is too low,
|
||||
* and then the re-allocation routines in the loop below kick in.
|
||||
* Here we multiply by 1.33 and add 1 so that it's even quite
|
||||
* efficient for smaller input strings without causing too much
|
||||
* iterations of this loop.
|
||||
*/
|
||||
buffer_len = (source_len > 2) ? ((source_len >> 1) + (source_len >> 3) + 2) : source_len;
|
||||
break;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
buffer = eurealloc(buffer, buffer_len + 1);
|
||||
output = buffer + converted;
|
||||
ucnv_toUnicode(conv, &output, buffer + buffer_len, &input, source + source_len, NULL, TRUE, status);
|
||||
converted = (int32_t) (output - buffer);
|
||||
if (*status == U_BUFFER_OVERFLOW_ERROR) {
|
||||
buffer_len = (buffer_len * 1.33) + 1;
|
||||
*status = U_ZERO_ERROR;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We return the buffer in case of failure anyway. The caller may want to
|
||||
* use partially converted string for something.
|
||||
*/
|
||||
|
||||
buffer[converted] = 0;
|
||||
*target = buffer;
|
||||
*target_len = converted;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_convert_from_unicode */
|
||||
ZEND_API void zend_convert_from_unicode(UConverter *conv, char **target, int32_t *target_len, const UChar *source, int32_t source_len, UErrorCode *status)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
char *output;
|
||||
int32_t buffer_len = 0;
|
||||
int32_t converted = 0;
|
||||
const UChar *input = source;
|
||||
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ucnv_resetFromUnicode(conv);
|
||||
|
||||
buffer_len = ucnv_getMaxCharSize(conv) * source_len;
|
||||
|
||||
while (1) {
|
||||
buffer = erealloc(buffer, buffer_len + 1);
|
||||
output = buffer + converted;
|
||||
ucnv_fromUnicode(conv, &output, buffer + buffer_len, &input, source + source_len, NULL, TRUE, status);
|
||||
converted = (int32_t) (output - buffer);
|
||||
if (*status == U_BUFFER_OVERFLOW_ERROR) {
|
||||
buffer_len += 64;
|
||||
*status = U_ZERO_ERROR;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We return the buffer in case of failure anyway. The caller may want to
|
||||
* use partially converted string for something.
|
||||
*/
|
||||
|
||||
buffer[converted] = 0; /* NULL-terminate the output string */
|
||||
*target = buffer;
|
||||
*target_len = converted;
|
||||
|
||||
/* Report the conversion error */
|
||||
if (U_FAILURE(*status)) {
|
||||
zend_error(E_NOTICE, "Error converting from Unicode to codepage string: %s", u_errorName(*status));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_convert_encodings */
|
||||
ZEND_API void zend_convert_encodings(UConverter *target_conv, UConverter *source_conv,
|
||||
char **target, int32_t *target_len,
|
||||
const char *source, int32_t source_len, UErrorCode *status)
|
||||
{
|
||||
char *buffer = NULL;
|
||||
char *output;
|
||||
const char *input = source;
|
||||
int32_t allocated = 0;
|
||||
int32_t converted = 0;
|
||||
int8_t null_size;
|
||||
UChar pivot_buf[1024], *pivot, *pivot2;
|
||||
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
null_size = ucnv_getMinCharSize(target_conv);
|
||||
allocated = source_len + null_size;
|
||||
|
||||
ucnv_resetToUnicode(source_conv);
|
||||
ucnv_resetFromUnicode(target_conv);
|
||||
pivot = pivot2 = pivot_buf;
|
||||
|
||||
while (1) {
|
||||
buffer = (char *) erealloc(buffer, allocated);
|
||||
output = buffer + converted;
|
||||
ucnv_convertEx(target_conv, source_conv, &output, buffer + allocated - null_size,
|
||||
&input, source + source_len, pivot_buf, &pivot, &pivot2, pivot_buf + 1024, FALSE, TRUE, status);
|
||||
converted = (int32_t) (output - buffer);
|
||||
if (*status == U_BUFFER_OVERFLOW_ERROR) {
|
||||
allocated += 1024;
|
||||
*status = U_ZERO_ERROR;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(buffer + converted, 0, null_size); /* NULL-terminate the output string */
|
||||
*target = buffer;
|
||||
*target_len = converted;
|
||||
|
||||
/* Report the conversion error */
|
||||
if (U_FAILURE(*status)) {
|
||||
zend_error(E_NOTICE, "Error converting from codepage string to Unicode: %s", u_errorName(*status));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zval_unicode_to_string */
|
||||
ZEND_API int zval_unicode_to_string(zval *string, UConverter *conv TSRMLS_DC)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int retval = TRUE;
|
||||
char *s = NULL;
|
||||
int s_len;
|
||||
|
||||
#if 0
|
||||
/* UTODO Putting it here for now, until we figure out the framework */
|
||||
switch (UG(from_u_error_mode)) {
|
||||
case ZEND_FROM_U_ERROR_STOP:
|
||||
ucnv_setFromUCallBack(UG(runtime_encoding_conv), UCNV_FROM_U_CALLBACK_STOP, NULL, NULL, NULL, &status);
|
||||
break;
|
||||
|
||||
case ZEND_FROM_U_ERROR_SKIP:
|
||||
ucnv_setFromUCallBack(UG(runtime_encoding_conv), UCNV_FROM_U_CALLBACK_SKIP, NULL, NULL, NULL, &status);
|
||||
break;
|
||||
|
||||
case ZEND_FROM_U_ERROR_ESCAPE:
|
||||
ucnv_setFromUCallBack(UG(runtime_encoding_conv), UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_UNICODE, NULL, NULL, &status);
|
||||
break;
|
||||
|
||||
case ZEND_FROM_U_ERROR_SUBST:
|
||||
ucnv_setFromUCallBack(UG(runtime_encoding_conv), UCNV_FROM_U_CALLBACK_SUBSTITUTE, NULL, NULL, NULL, &status);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (UG(subst_chars)) {
|
||||
char subchar[16];
|
||||
int8_t char_len = 16;
|
||||
status = U_ZERO_ERROR;
|
||||
ucnv_getSubstChars(UG(runtime_encoding_conv), subchar, &char_len, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
zend_error(E_WARNING, "Could not get substitution characters");
|
||||
return FAILURE;
|
||||
}
|
||||
status = U_ZERO_ERROR;
|
||||
ucnv_setSubstChars(UG(runtime_encoding_conv), UG(subst_chars), MIN(char_len, UG(subst_chars_len)), &status);
|
||||
if (U_FAILURE(status)) {
|
||||
zend_error(E_WARNING, "Could not set substitution characters");
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
#endif
|
||||
|
||||
UChar *u = Z_USTRVAL_P(string);
|
||||
int32_t u_len = Z_USTRLEN_P(string);
|
||||
|
||||
Z_TYPE_P(string) = IS_STRING;
|
||||
zend_convert_from_unicode(conv, &s, &s_len, u, u_len, &status);
|
||||
ZVAL_STRINGL(string, s, s_len, 0);
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
retval = FAILURE;
|
||||
}
|
||||
|
||||
efree(u);
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zval_string_to_unicode */
|
||||
ZEND_API int zval_string_to_unicode(zval *string TSRMLS_DC)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int retval = TRUE;
|
||||
UChar *u = NULL;
|
||||
int32_t u_len;
|
||||
|
||||
char *s = Z_STRVAL_P(string);
|
||||
int s_len = Z_STRLEN_P(string);
|
||||
|
||||
Z_TYPE_P(string) = IS_UNICODE;
|
||||
zend_convert_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &u, &u_len, s, s_len, &status);
|
||||
ZVAL_UNICODEL(string, u, u_len, 0);
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
retval = FALSE;
|
||||
}
|
||||
|
||||
efree(s);
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_cmp_unicode_and_string */
|
||||
ZEND_API int zend_cmp_unicode_and_string(UChar *ustr, char* str, uint len)
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UChar *u = NULL;
|
||||
int32_t u_len;
|
||||
int retval = TRUE;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
zend_convert_to_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &u, &u_len, str, len, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
efree(u);
|
||||
return FALSE;
|
||||
}
|
||||
retval = u_memcmp(ustr, u, u_len);
|
||||
efree(u);
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_cmp_unicode_and_literal */
|
||||
/*
|
||||
* Compare a Unicode string and an ASCII literal. Because ASCII maps nicely onto Unicode
|
||||
* range U+0000 .. U+007F, we can simply casst ASCII chars to Unicode values and avoid
|
||||
* memory allocation.
|
||||
*/
|
||||
ZEND_API int zend_cmp_unicode_and_literal(UChar *ustr, int32_t ulen, char *str, int32_t slen)
|
||||
{
|
||||
int32_t result;
|
||||
uint len = MIN(ulen, slen);
|
||||
|
||||
while (len--) {
|
||||
result = (int32_t)(uint16_t)*ustr - (int32_t)(uint16_t)*str;
|
||||
if (result != 0)
|
||||
return result;
|
||||
ustr++;
|
||||
str++;
|
||||
}
|
||||
|
||||
return ulen - slen;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_is_valid_identifier */
|
||||
ZEND_API int zend_is_valid_identifier(UChar *ident, int32_t ident_len)
|
||||
{
|
||||
UChar32 codepoint;
|
||||
int32_t i;
|
||||
UProperty id_prop = UCHAR_XID_START;
|
||||
|
||||
for (i = 0; i < ident_len; ) {
|
||||
U16_NEXT(ident, i, ident_len, codepoint);
|
||||
if (!u_hasBinaryProperty(codepoint, id_prop) &&
|
||||
codepoint != 0x5f) { /* special case for starting '_' */
|
||||
return 0;
|
||||
}
|
||||
id_prop = UCHAR_XID_CONTINUE;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_normalize_string */
|
||||
static inline void zend_normalize_string(UChar **dest, int32_t *dest_len, UChar *src, int32_t src_len, UErrorCode *status)
|
||||
{
|
||||
UChar *buffer = NULL;
|
||||
int32_t buffer_len;
|
||||
|
||||
buffer_len = src_len;
|
||||
while (1) {
|
||||
*status = U_ZERO_ERROR;
|
||||
buffer = eurealloc(buffer, buffer_len+1);
|
||||
buffer_len = unorm_normalize(src, src_len, UNORM_NFKC, 0, buffer, buffer_len, status);
|
||||
if (*status != U_BUFFER_OVERFLOW_ERROR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (U_SUCCESS(*status)) {
|
||||
buffer[buffer_len] = 0;
|
||||
*dest = buffer;
|
||||
*dest_len = buffer_len;
|
||||
} else {
|
||||
efree(buffer);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_case_fold_string */
|
||||
ZEND_API void zend_case_fold_string(UChar **dest, int32_t *dest_len, UChar *src, int32_t src_len, uint32_t options, UErrorCode *status)
|
||||
{
|
||||
UChar *buffer = NULL;
|
||||
int32_t buffer_len;
|
||||
|
||||
buffer_len = src_len;
|
||||
while (1) {
|
||||
*status = U_ZERO_ERROR;
|
||||
buffer = eurealloc(buffer, buffer_len+1);
|
||||
buffer_len = u_strFoldCase(buffer, buffer_len, src, src_len, options, status);
|
||||
if (*status != U_BUFFER_OVERFLOW_ERROR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (U_SUCCESS(*status)) {
|
||||
buffer[buffer_len] = 0;
|
||||
*dest = buffer;
|
||||
*dest_len = buffer_len;
|
||||
} else {
|
||||
efree(buffer);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_normalize_identifier */
|
||||
ZEND_API int zend_normalize_identifier(UChar **dest, int32_t *dest_len, UChar *ident, int32_t ident_len, zend_bool fold_case)
|
||||
{
|
||||
UChar *buffer = NULL;
|
||||
UChar *orig_ident = ident;
|
||||
int32_t buffer_len;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
if (unorm_quickCheck(ident, ident_len, UNORM_NFKC, &status) != UNORM_YES) {
|
||||
zend_normalize_string(&buffer, &buffer_len, ident, ident_len, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
ident = buffer;
|
||||
ident_len = buffer_len;
|
||||
}
|
||||
|
||||
if (fold_case) {
|
||||
zend_case_fold_string(&buffer, &buffer_len, ident, ident_len, U_FOLD_CASE_DEFAULT, &status);
|
||||
if (ident != orig_ident) {
|
||||
efree(ident);
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
ident = buffer;
|
||||
ident_len = buffer_len;
|
||||
|
||||
if (unorm_quickCheck(ident, ident_len, UNORM_NFKC, &status) != UNORM_YES) {
|
||||
zend_normalize_string(&buffer, &buffer_len, ident, ident_len, &status);
|
||||
if (ident != orig_ident) {
|
||||
efree(ident);
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
ident = buffer;
|
||||
ident_len = buffer_len;
|
||||
}
|
||||
}
|
||||
|
||||
*dest = ident;
|
||||
*dest_len = ident_len;
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* vim: set fdm=marker et sts=4: */
|
90
Zend/zend_unicode.h
Normal file
90
Zend/zend_unicode.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2004 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available at through the world-wide-web at |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andrei Zmievski <andrei@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef ZEND_UNICODE_H
|
||||
#define ZEND_UNICODE_H
|
||||
|
||||
#include "zend.h"
|
||||
#include <unicode/utypes.h>
|
||||
#include <unicode/ustring.h>
|
||||
#include <unicode/ucnv.h>
|
||||
#include <unicode/ustdio.h>
|
||||
#include <unicode/uchar.h>
|
||||
#include <unicode/uloc.h>
|
||||
#include <unicode/ucol.h>
|
||||
|
||||
#define ZEND_FROM_U_ERROR_STOP 0
|
||||
#define ZEND_FROM_U_ERROR_SKIP 1
|
||||
#define ZEND_FROM_U_ERROR_SUBST 2
|
||||
#define ZEND_FROM_U_ERROR_ESCAPE 3
|
||||
|
||||
/* internal functions */
|
||||
|
||||
int zend_set_converter_encoding(UConverter **converter, const char *encoding);
|
||||
void zend_set_converter_subst_char(UConverter *conv, UChar *subst_char, int8_t subst_char_len);
|
||||
void zend_set_converter_error_mode(UConverter *conv, uint8_t error_mode);
|
||||
|
||||
|
||||
/* API functions */
|
||||
|
||||
ZEND_API void zend_convert_to_unicode(UConverter *conv, UChar **target, int32_t *target_len, const char *source, int32_t source_len, UErrorCode *status);
|
||||
ZEND_API void zend_convert_from_unicode(UConverter *conv, char **target, int32_t *target_len, const UChar *source, int32_t source_len, UErrorCode *status);
|
||||
ZEND_API void zend_convert_encodings(UConverter *target_conv, UConverter *source_conv, char **target, int32_t *target_len, const char *source, int32_t source_len, UErrorCode *status);
|
||||
ZEND_API int zval_string_to_unicode(zval *string TSRMLS_DC);
|
||||
ZEND_API int zval_unicode_to_string(zval *string, UConverter *conv TSRMLS_DC);
|
||||
|
||||
ZEND_API int zend_cmp_unicode_and_string(UChar *ustr, char* str, uint len);
|
||||
ZEND_API int zend_cmp_unicode_and_literal(UChar *ustr, int32_t ulen, char* str, int32_t slen);
|
||||
|
||||
ZEND_API void zend_case_fold_string(UChar **dest, int32_t *dest_len, UChar *src, int32_t src_len, uint32_t options, UErrorCode *status);
|
||||
|
||||
ZEND_API int zend_is_valid_identifier(UChar *ident, int32_t ident_len);
|
||||
ZEND_API int zend_normalize_identifier(UChar **dest, int32_t *dest_len, UChar *ident, int32_t ident_len, zend_bool fold_case);
|
||||
|
||||
/*
|
||||
* Function to get a codepoint at position n. Iterates over codepoints starting from the
|
||||
* beginning of the string. Does not check for n > length, this is left up to the caller.
|
||||
*/
|
||||
static inline UChar32 zend_get_codepoint_at(UChar *str, int32_t length, int32_t n)
|
||||
{
|
||||
int32_t offset = 0;
|
||||
UChar32 c = 0;
|
||||
|
||||
U16_FWD_N(str, offset, length, n);
|
||||
U16_GET(str, 0, offset, length, c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
#define ZEND_U_CONVERTER(c) ((c)?(c):UG(fallback_encoding_conv))
|
||||
|
||||
#define USTR_FREE(ustr) do { if (ustr) { efree(ustr); } } while (0);
|
||||
#define UBYTES(len) ((len) * sizeof(UChar))
|
||||
#define USTR_LEN(str) (UG(unicode)?u_strlen((UChar*)(str)):strlen((char*)(str)))
|
||||
|
||||
#define USTR_MAKE(cs) zend_ascii_to_unicode(cs, sizeof(cs) ZEND_FILE_LINE_CC)
|
||||
#define USTR_MAKE_REL(cs) zend_ascii_to_unicode(cs, sizeof(cs) ZEND_FILE_LINE_RELAY_CC)
|
||||
static inline UChar* zend_ascii_to_unicode(const char *cs, size_t cs_size ZEND_FILE_LINE_DC)
|
||||
{
|
||||
/* u_charsToUChars() takes care of the terminating NULL */
|
||||
UChar *us = eumalloc_rel(cs_size);
|
||||
u_charsToUChars(cs, us, cs_size);
|
||||
return us;
|
||||
}
|
||||
|
||||
#endif /* ZEND_UNICODE_H */
|
@ -30,11 +30,21 @@
|
||||
ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
{
|
||||
switch (zvalue->type & ~IS_CONSTANT_INDEX) {
|
||||
case IS_CONSTANT: {
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (UG(unicode)) goto dtor_unicode;
|
||||
}
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
case IS_BINARY:
|
||||
CHECK_ZVAL_STRING_REL(zvalue);
|
||||
STR_FREE_REL(zvalue->value.str.val);
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
dtor_unicode:
|
||||
CHECK_ZVAL_UNICODE_REL(zvalue);
|
||||
STR_FREE_REL(zvalue->value.ustr.val);
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY: {
|
||||
TSRMLS_FETCH();
|
||||
@ -74,11 +84,21 @@ ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
{
|
||||
switch (zvalue->type & ~IS_CONSTANT_INDEX) {
|
||||
case IS_CONSTANT: {
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (UG(unicode)) goto dtor_unicode;
|
||||
}
|
||||
case IS_STRING:
|
||||
case IS_CONSTANT:
|
||||
case IS_BINARY:
|
||||
CHECK_ZVAL_STRING_REL(zvalue);
|
||||
free(zvalue->value.str.val);
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
dtor_unicode:
|
||||
CHECK_ZVAL_UNICODE_REL(zvalue);
|
||||
free(zvalue->value.ustr.val);
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY:
|
||||
case IS_OBJECT:
|
||||
@ -114,11 +134,21 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
case IS_LONG:
|
||||
case IS_NULL:
|
||||
break;
|
||||
case IS_CONSTANT:
|
||||
case IS_CONSTANT: {
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (UG(unicode)) goto copy_unicode;
|
||||
}
|
||||
case IS_STRING:
|
||||
case IS_BINARY:
|
||||
CHECK_ZVAL_STRING_REL(zvalue);
|
||||
zvalue->value.str.val = (char *) estrndup_rel(zvalue->value.str.val, zvalue->value.str.len);
|
||||
break;
|
||||
case IS_UNICODE:
|
||||
copy_unicode:
|
||||
CHECK_ZVAL_UNICODE_REL(zvalue);
|
||||
zvalue->value.ustr.val = eustrndup_rel(zvalue->value.ustr.val, zvalue->value.ustr.len);
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_CONSTANT_ARRAY: {
|
||||
zval *tmp;
|
||||
@ -130,7 +160,7 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
return; /* do nothing */
|
||||
}
|
||||
ALLOC_HASHTABLE_REL(tmp_ht);
|
||||
zend_hash_init(tmp_ht, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(tmp_ht, 0, NULL, ZVAL_PTR_DTOR, 0, original_ht->unicode);
|
||||
zend_hash_copy(tmp_ht, original_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
zvalue->value.ht = tmp_ht;
|
||||
}
|
||||
@ -144,7 +174,6 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZEND_API int zend_print_variable(zval *var)
|
||||
{
|
||||
return zend_print_zval(var, 0);
|
||||
|
@ -886,11 +886,27 @@ ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMP|VAR|CV, ANY)
|
||||
zval *z = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get_method != NULL &&
|
||||
zend_std_cast_object_tostring(z, &z_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS) {
|
||||
zend_std_cast_object_tostring(z, &z_copy, UG(unicode) ? IS_UNICODE : IS_STRING, 0 TSRMLS_CC) == SUCCESS) {
|
||||
zend_print_variable(&z_copy);
|
||||
zval_dtor(&z_copy);
|
||||
} else {
|
||||
zend_print_variable(z);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
/* Convert inline HTML blocks to the output encoding, but only if necessary. */
|
||||
if (opline->extended_value &&
|
||||
strcmp(ucnv_getName(ZEND_U_CONVERTER(UG(output_encoding_conv)), &status),
|
||||
ucnv_getName(ZEND_U_CONVERTER(UG(script_encoding_conv)), &status))) {
|
||||
zval z_conv;
|
||||
zend_convert_encodings(ZEND_U_CONVERTER(UG(output_encoding_conv)), ZEND_U_CONVERTER(UG(script_encoding_conv)), &z_conv.value.str.val, &z_conv.value.str.len, z->value.str.val, z->value.str.len, &status);
|
||||
z_conv.type = IS_BINARY;
|
||||
if (U_SUCCESS(status)) {
|
||||
zend_print_variable(&z_conv);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Could not convert inline HTML for output");
|
||||
}
|
||||
zval_dtor(&z_conv);
|
||||
} else {
|
||||
zend_print_variable(z);
|
||||
}
|
||||
}
|
||||
|
||||
FREE_OP1();
|
||||
@ -932,23 +948,23 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
*/
|
||||
if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) {
|
||||
if (zend_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, (void **) &retval) == FAILURE) {
|
||||
switch (type) {
|
||||
case BP_VAR_R:
|
||||
case BP_VAR_UNSET:
|
||||
zend_error(E_NOTICE,"Undefined variable: %s", varname->value.str.val);
|
||||
zend_error(E_NOTICE,"Undefined variable: %R", Z_TYPE_P(varname), Z_UNIVAL_P(varname));
|
||||
/* break missing intentionally */
|
||||
case BP_VAR_IS:
|
||||
retval = &EG(uninitialized_zval_ptr);
|
||||
break;
|
||||
case BP_VAR_RW:
|
||||
zend_error(E_NOTICE,"Undefined variable: %s", varname->value.str.val);
|
||||
zend_error(E_NOTICE,"Undefined variable: %R", Z_TYPE_P(varname), Z_UNIVAL_P(varname));
|
||||
/* break missing intentionally */
|
||||
case BP_VAR_W: {
|
||||
zval *new_zval = &EG(uninitialized_zval);
|
||||
|
||||
new_zval->refcount++;
|
||||
zend_hash_update(target_symbol_table, varname->value.str.val, varname->value.str.len+1, &new_zval, sizeof(zval *), (void **) &retval);
|
||||
zend_u_hash_update(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, &new_zval, sizeof(zval *), (void **) &retval);
|
||||
}
|
||||
break;
|
||||
EMPTY_SWITCH_DEFAULT_CASE()
|
||||
@ -956,6 +972,10 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type
|
||||
}
|
||||
switch (opline->op2.u.EA.type) {
|
||||
case ZEND_FETCH_GLOBAL:
|
||||
if (OP1_TYPE != IS_TMP_VAR) {
|
||||
FREE_OP1();
|
||||
}
|
||||
break;
|
||||
case ZEND_FETCH_LOCAL:
|
||||
FREE_OP1();
|
||||
break;
|
||||
@ -1519,11 +1539,18 @@ ZEND_VM_HANDLER(53, ZEND_INIT_STRING, ANY, ANY)
|
||||
{
|
||||
zval *tmp = &EX_T(EX(opline)->result.u.var).tmp_var;
|
||||
|
||||
tmp->value.str.val = emalloc(1);
|
||||
tmp->value.str.val[0] = 0;
|
||||
tmp->value.str.len = 0;
|
||||
if (EX(opline)->extended_value == IS_UNICODE) {
|
||||
tmp->value.ustr.val = eumalloc(1);
|
||||
tmp->value.ustr.val[0] = 0;
|
||||
tmp->value.ustr.len = 0;
|
||||
tmp->type = IS_UNICODE;
|
||||
} else {
|
||||
tmp->value.str.val = emalloc(1);
|
||||
tmp->value.str.val[0] = 0;
|
||||
tmp->value.str.len = 0;
|
||||
tmp->type = EX(opline)->extended_value;
|
||||
}
|
||||
tmp->refcount = 1;
|
||||
tmp->type = IS_STRING;
|
||||
tmp->is_ref = 0;
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
@ -1534,8 +1561,8 @@ ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP, CONST)
|
||||
zend_free_op free_op1;
|
||||
|
||||
add_char_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
GET_OP1_ZVAL_PTR(BP_VAR_NA),
|
||||
&opline->op2.u.constant);
|
||||
GET_OP1_ZVAL_PTR(BP_VAR_NA),
|
||||
&opline->op2.u.constant);
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
@ -1546,8 +1573,8 @@ ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP, CONST)
|
||||
zend_free_op free_op1;
|
||||
|
||||
add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
GET_OP1_ZVAL_PTR(BP_VAR_NA),
|
||||
&opline->op2.u.constant);
|
||||
GET_OP1_ZVAL_PTR(BP_VAR_NA),
|
||||
&opline->op2.u.constant);
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
@ -1560,13 +1587,16 @@ ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP, TMP|VAR|CV)
|
||||
zval var_copy;
|
||||
int use_copy;
|
||||
|
||||
zend_make_printable_zval(var, &var_copy, &use_copy);
|
||||
if (opline->extended_value == IS_UNICODE) {
|
||||
zend_make_unicode_zval(var, &var_copy, &use_copy);
|
||||
} else {
|
||||
zend_make_printable_zval(var, &var_copy, &use_copy);
|
||||
}
|
||||
if (use_copy) {
|
||||
var = &var_copy;
|
||||
}
|
||||
add_string_to_string( &EX_T(opline->result.u.var).tmp_var,
|
||||
GET_OP1_ZVAL_PTR(BP_VAR_NA),
|
||||
var);
|
||||
add_string_to_string(&EX_T(opline->result.u.var).tmp_var,
|
||||
GET_OP1_ZVAL_PTR(BP_VAR_NA), var);
|
||||
if (use_copy) {
|
||||
zval_dtor(var);
|
||||
}
|
||||
@ -1600,7 +1630,8 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
|
||||
EX_T(opline->result.u.var).class_entry = Z_OBJCE_P(class_name);
|
||||
break;
|
||||
case IS_STRING:
|
||||
EX_T(opline->result.u.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
|
||||
case IS_UNICODE:
|
||||
EX_T(opline->result.u.var).class_entry = zend_u_fetch_class(Z_TYPE_P(class_name), Z_UNIVAL_P(class_name), Z_UNILEN_P(class_name), opline->extended_value TSRMLS_CC);
|
||||
break;
|
||||
default:
|
||||
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
|
||||
@ -1618,17 +1649,19 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
char *function_name_strval;
|
||||
int function_name_strlen;
|
||||
zend_free_op free_op1, free_op2;
|
||||
/* FIXME: type is default */
|
||||
zend_uchar type = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(calling_scope));
|
||||
|
||||
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (Z_TYPE_P(function_name)!=IS_STRING) {
|
||||
if (Z_TYPE_P(function_name) != IS_STRING && Z_TYPE_P(function_name) != IS_UNICODE) {
|
||||
zend_error_noreturn(E_ERROR, "Method name must be a string");
|
||||
}
|
||||
|
||||
function_name_strval = function_name->value.str.val;
|
||||
function_name_strlen = function_name->value.str.len;
|
||||
function_name_strval = Z_UNIVAL_P(function_name);
|
||||
function_name_strlen = Z_UNILEN_P(function_name);
|
||||
|
||||
EX(calling_scope) = EG(scope);
|
||||
|
||||
@ -1642,10 +1675,10 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
/* First, locate the function. */
|
||||
EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen TSRMLS_CC);
|
||||
if (!EX(fbc)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined method %R::%R()", type, Z_OBJ_CLASS_NAME_P(EX(object)), Z_TYPE_P(function_name), function_name_strval);
|
||||
}
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
|
||||
zend_error_noreturn(E_ERROR, "Call to a member function %R() on a non-object", Z_TYPE_P(function_name), function_name_strval);
|
||||
}
|
||||
|
||||
if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
|
||||
@ -1685,21 +1718,20 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, ANY, CONST|TMP|VAR|UNUSED|CV)
|
||||
ce = EX_T(opline->op1.u.var).class_entry;
|
||||
if(OP2_TYPE != IS_UNUSED) {
|
||||
char *function_name_strval;
|
||||
int function_name_strlen;
|
||||
unsigned int function_name_strlen;
|
||||
zend_bool is_const = (OP2_TYPE == IS_CONST);
|
||||
zend_free_op free_op2;
|
||||
|
||||
if (is_const) {
|
||||
function_name_strval = opline->op2.u.constant.value.str.val;
|
||||
function_name_strlen = opline->op2.u.constant.value.str.len;
|
||||
function_name_strval = Z_UNIVAL(opline->op2.u.constant);
|
||||
function_name_strlen = Z_UNILEN(opline->op2.u.constant);
|
||||
} else {
|
||||
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (Z_TYPE_P(function_name) != IS_STRING) {
|
||||
if (Z_TYPE_P(function_name) != IS_STRING && Z_TYPE_P(function_name) != IS_UNICODE) {
|
||||
zend_error_noreturn(E_ERROR, "Function name must be a string");
|
||||
}
|
||||
function_name_strval = zend_str_tolower_dup(function_name->value.str.val, function_name->value.str.len);
|
||||
function_name_strlen = function_name->value.str.len;
|
||||
function_name_strval = zend_u_str_case_fold(Z_TYPE_P(function_name), Z_UNIVAL_P(function_name), Z_UNILEN_P(function_name), 1, &function_name_strlen);
|
||||
}
|
||||
|
||||
EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
|
||||
@ -1733,29 +1765,28 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
|
||||
zend_op *opline = EX(opline);
|
||||
zval *function_name;
|
||||
zend_function *function;
|
||||
char *function_name_strval, *lcname;
|
||||
int function_name_strlen;
|
||||
void *function_name_strval, *lcname;
|
||||
unsigned int function_name_strlen, lcname_len;
|
||||
zend_free_op free_op2;
|
||||
|
||||
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(calling_scope));
|
||||
|
||||
if (OP2_TYPE == IS_CONST) {
|
||||
function_name_strval = opline->op2.u.constant.value.str.val;
|
||||
function_name_strlen = opline->op2.u.constant.value.str.len;
|
||||
function_name = &opline->op2.u.constant;
|
||||
} else {
|
||||
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (Z_TYPE_P(function_name) != IS_STRING) {
|
||||
if (Z_TYPE_P(function_name) != IS_STRING && Z_TYPE_P(function_name) != IS_UNICODE) {
|
||||
zend_error_noreturn(E_ERROR, "Function name must be a string");
|
||||
}
|
||||
function_name_strval = function_name->value.str.val;
|
||||
function_name_strlen = function_name->value.str.len;
|
||||
}
|
||||
function_name_strval = Z_UNIVAL_P(function_name);
|
||||
function_name_strlen = Z_UNILEN_P(function_name);
|
||||
|
||||
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
|
||||
if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &function)==FAILURE) {
|
||||
lcname = zend_u_str_case_fold(Z_TYPE_P(function_name), Z_STRVAL_P(function_name), function_name_strlen, 1, &lcname_len);
|
||||
if (zend_u_hash_find(EG(function_table), Z_TYPE_P(function_name), lcname, lcname_len+1, (void **) &function)==FAILURE) {
|
||||
efree(lcname);
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined function %R()", Z_TYPE_P(function_name), function_name_strval);
|
||||
}
|
||||
|
||||
efree(lcname);
|
||||
@ -1782,7 +1813,8 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
zend_bool should_change_scope;
|
||||
|
||||
if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
|
||||
/* FIXME: output identifiers properly */
|
||||
zend_error_noreturn(E_ERROR, "Cannot call abstract method %v::%v()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
|
||||
ZEND_VM_NEXT_OPCODE(); /* Never reached */
|
||||
}
|
||||
|
||||
@ -1814,7 +1846,8 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
severity = E_ERROR;
|
||||
severity_word = "cannot";
|
||||
}
|
||||
zend_error(severity, "Non-static method %s::%s() %s be called statically", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name, severity_word);
|
||||
/* FIXME: output identifiers properly */
|
||||
zend_error(severity, "Non-static method %v::%v() %s be called statically", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name, severity_word);
|
||||
}
|
||||
}
|
||||
if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
|
||||
@ -1862,7 +1895,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
EX(function_state).function_symbol_table = *(EG(symtable_cache_ptr)--);
|
||||
} else {
|
||||
ALLOC_HASHTABLE(EX(function_state).function_symbol_table);
|
||||
zend_hash_init(EX(function_state).function_symbol_table, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(EX(function_state).function_symbol_table, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
/*printf("Cache miss! Initialized %x\n", function_state.function_symbol_table);*/
|
||||
}
|
||||
calling_symbol_table = EG(active_symbol_table);
|
||||
@ -1968,8 +2001,9 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY)
|
||||
|
||||
zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(calling_scope));
|
||||
|
||||
if (zend_hash_find(EG(function_table), fname->value.str.val, fname->value.str.len+1, (void **) &EX(function_state).function)==FAILURE) {
|
||||
zend_error_noreturn(E_ERROR, "Unknown function: %s()\n", fname->value.str.val);
|
||||
if (zend_u_hash_find(EG(function_table), Z_TYPE_P(fname), Z_UNIVAL_P(fname), Z_UNILEN_P(fname)+1, (void **) &EX(function_state).function)==FAILURE) {
|
||||
/* FIXME: output identifiers properly */
|
||||
zend_error_noreturn(E_ERROR, "Unknown function: %R()\n", Z_TYPE_P(fname), Z_UNIVAL_P(fname));
|
||||
}
|
||||
EX(object) = NULL;
|
||||
EX(calling_scope) = EX(function_state).function->common.scope;
|
||||
@ -2031,9 +2065,9 @@ ZEND_VM_C_LABEL(return_by_value):
|
||||
INIT_PZVAL_COPY(ret, retval_ptr);
|
||||
dup = zend_get_object_classname(retval_ptr, &class_name, &class_name_len TSRMLS_CC);
|
||||
if (Z_OBJ_HT_P(retval_ptr)->clone_obj == NULL) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", class_name);
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", Z_OBJCE_P(retval_ptr)->name);
|
||||
}
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
|
||||
zend_error(E_STRICT, "Implicit cloning object of class '%v' because of 'zend.ze1_compatibility_mode'", Z_OBJCE_P(retval_ptr)->name);
|
||||
ret->value.obj = Z_OBJ_HT_P(retval_ptr)->clone_obj(retval_ptr TSRMLS_CC);
|
||||
*EG(return_value_ptr_ptr) = ret;
|
||||
if (!dup) {
|
||||
@ -2110,8 +2144,8 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, ANY, ANY)
|
||||
}
|
||||
}
|
||||
|
||||
zend_hash_update(EG(active_symbol_table), opline->op2.u.constant.value.str.val,
|
||||
opline->op2.u.constant.value.str.len+1, &EG(exception), sizeof(zval *), (void **) NULL);
|
||||
zend_u_hash_update(EG(active_symbol_table), Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant),
|
||||
Z_UNILEN(opline->op2.u.constant)+1, &EG(exception), sizeof(zval *), (void **) NULL);
|
||||
EG(exception) = NULL;
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
@ -2243,9 +2277,9 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
|
||||
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL TSRMLS_CC);
|
||||
if(ptr && ptr->op_array) {
|
||||
zend_error(E_WARNING, "Missing argument %ld for %s%s%s(), called in %s on line %d and defined", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
|
||||
zend_error(E_WARNING, "Missing argument %ld for %v%s%v(), called in %s on line %d and defined", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C), ptr->op_array->filename, ptr->opline->lineno);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Missing argument %ld for %s%s%s()", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C));
|
||||
zend_error(E_WARNING, "Missing argument %ld for %v%s%v()", opline->op1.u.constant.value.lval, class_name, space, get_active_function_name(TSRMLS_C));
|
||||
}
|
||||
if (opline->result.op_type == IS_VAR) {
|
||||
PZVAL_UNLOCK_FREE(*EX_T(opline->result.u.var).var.ptr_ptr);
|
||||
@ -2400,7 +2434,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
|
||||
} else {
|
||||
class_type = "abstract class";
|
||||
}
|
||||
zend_error_noreturn(E_ERROR, "Cannot instantiate %s %s", class_type, EX_T(opline->op1.u.var).class_entry->name);
|
||||
zend_error_noreturn(E_ERROR, "Cannot instantiate %s %v", class_type, EX_T(opline->op1.u.var).class_entry->name);
|
||||
}
|
||||
ALLOC_ZVAL(object_zval);
|
||||
object_init_ex(object_zval, EX_T(opline->op1.u.var).class_entry);
|
||||
@ -2458,7 +2492,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
|
||||
clone = ce ? ce->clone : NULL;
|
||||
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
|
||||
if (!clone_call) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %s", ce->name);
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
|
||||
EX_T(opline->result.u.var).var.ptr->refcount++;
|
||||
}
|
||||
@ -2468,13 +2502,13 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
|
||||
/* Ensure that if we're calling a private function, we're allowed to do so.
|
||||
*/
|
||||
if (ce != EG(scope)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to private %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
|
||||
zend_error_noreturn(E_ERROR, "Call to private %v::__clone() from context '%v'", ce->name, EG(scope) ? EG(scope)->name : EMPTY_STR);
|
||||
}
|
||||
} else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
|
||||
/* Ensure that if we're calling a protected function, we're allowed to do so.
|
||||
*/
|
||||
if (!zend_check_protected(clone->common.scope, EG(scope))) {
|
||||
zend_error_noreturn(E_ERROR, "Call to protected %s::__clone() from context '%s'", ce->name, EG(scope) ? EG(scope)->name : "");
|
||||
zend_error_noreturn(E_ERROR, "Call to protected %v::__clone() from context '%v'", ce->name, EG(scope) ? EG(scope)->name : EMPTY_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2511,10 +2545,12 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, CONST|UNUSED, CONST)
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!zend_get_constant(opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len, &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
|
||||
opline->op2.u.constant.value.str.val,
|
||||
opline->op2.u.constant.value.str.val);
|
||||
if (!zend_get_constant(Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant), &EX_T(opline->result.u.var).tmp_var TSRMLS_CC)) {
|
||||
zend_error(E_NOTICE, "Use of undefined constant %R - assumed '%R'",
|
||||
Z_TYPE(opline->op2.u.constant),
|
||||
Z_UNIVAL(opline->op2.u.constant),
|
||||
Z_TYPE(opline->op2.u.constant),
|
||||
Z_UNIVAL(opline->op2.u.constant));
|
||||
EX_T(opline->result.u.var).tmp_var = opline->op2.u.constant;
|
||||
zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
|
||||
}
|
||||
@ -2523,12 +2559,12 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, CONST|UNUSED, CONST)
|
||||
|
||||
ce = EX_T(opline->op1.u.var).class_entry;
|
||||
|
||||
if (zend_hash_find(&ce->constants_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
|
||||
if (zend_u_hash_find(&ce->constants_table, Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant), Z_UNILEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) {
|
||||
zval_update_constant(value, (void *) 1 TSRMLS_CC);
|
||||
EX_T(opline->result.u.var).tmp_var = **value;
|
||||
zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", opline->op2.u.constant.value.str.val);
|
||||
zend_error_noreturn(E_ERROR, "Undefined class constant '%R'", Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant));
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
@ -2587,7 +2623,9 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|V
|
||||
zend_hash_index_update(array_ptr->value.ht, offset->value.lval, &expr_ptr, sizeof(zval *), NULL);
|
||||
break;
|
||||
case IS_STRING:
|
||||
zend_symtable_update(array_ptr->value.ht, offset->value.str.val, offset->value.str.len+1, &expr_ptr, sizeof(zval *), NULL);
|
||||
case IS_BINARY:
|
||||
case IS_UNICODE:
|
||||
zend_u_symtable_update(array_ptr->value.ht, Z_TYPE_P(offset), Z_UNIVAL_P(offset), Z_UNILEN_P(offset)+1, &expr_ptr, sizeof(zval *), NULL);
|
||||
break;
|
||||
case IS_NULL:
|
||||
zend_hash_update(array_ptr->value.ht, "", sizeof(""), &expr_ptr, sizeof(zval *), NULL);
|
||||
@ -2643,13 +2681,27 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY)
|
||||
zval var_copy;
|
||||
int use_copy;
|
||||
|
||||
zend_make_printable_zval(result, &var_copy, &use_copy);
|
||||
zend_make_string_zval(result, &var_copy, &use_copy);
|
||||
if (use_copy) {
|
||||
zval_dtor(result);
|
||||
*result = var_copy;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_UNICODE: {
|
||||
zval var_copy;
|
||||
int use_copy;
|
||||
|
||||
zend_make_unicode_zval(result, &var_copy, &use_copy);
|
||||
if (use_copy) {
|
||||
zval_dtor(result);
|
||||
*result = var_copy;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_BINARY:
|
||||
convert_to_binary(result);
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
convert_to_array(result);
|
||||
break;
|
||||
@ -2672,7 +2724,14 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
|
||||
zval tmp_inc_filename;
|
||||
zend_bool failure_retval=0;
|
||||
|
||||
if (inc_filename->type!=IS_STRING) {
|
||||
if (UG(unicode) && opline->op2.u.constant.value.lval == ZEND_EVAL) {
|
||||
if (inc_filename->type != IS_UNICODE) {
|
||||
tmp_inc_filename = *inc_filename;
|
||||
zval_copy_ctor(&tmp_inc_filename);
|
||||
convert_to_unicode(&tmp_inc_filename);
|
||||
inc_filename = &tmp_inc_filename;
|
||||
}
|
||||
} else if (inc_filename->type!=IS_STRING) {
|
||||
tmp_inc_filename = *inc_filename;
|
||||
zval_copy_ctor(&tmp_inc_filename);
|
||||
convert_to_string(&tmp_inc_filename);
|
||||
@ -2789,10 +2848,10 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY)
|
||||
|
||||
varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (varname->type != IS_STRING) {
|
||||
if (varname->type != IS_STRING && varname->type != IS_UNICODE) {
|
||||
tmp = *varname;
|
||||
zval_copy_ctor(&tmp);
|
||||
convert_to_string(&tmp);
|
||||
convert_to_text(&tmp);
|
||||
varname = &tmp;
|
||||
}
|
||||
|
||||
@ -2800,17 +2859,17 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY)
|
||||
zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
|
||||
} else {
|
||||
target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
|
||||
if (zend_hash_del(target_symbol_table, varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
|
||||
if (zend_u_hash_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1) == SUCCESS) {
|
||||
zend_execute_data *ex = EXECUTE_DATA;
|
||||
ulong hash_value = zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
|
||||
ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
|
||||
|
||||
do {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ex->op_array->last_var; i++) {
|
||||
if (ex->op_array->vars[i].hash_value == hash_value &&
|
||||
ex->op_array->vars[i].name_len == varname->value.str.len &&
|
||||
!memcmp(ex->op_array->vars[i].name, varname->value.str.val, varname->value.str.len)) {
|
||||
ex->op_array->vars[i].name_len == Z_UNILEN_P(varname) &&
|
||||
!memcmp(ex->op_array->vars[i].name, Z_UNIVAL_P(varname), Z_TYPE_P(varname)==IS_UNICODE?UBYTES(Z_UNILEN_P(varname)):Z_UNILEN_P(varname))) {
|
||||
ex->CVs[i] = NULL;
|
||||
break;
|
||||
}
|
||||
@ -2857,10 +2916,31 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
zend_hash_index_del(ht, index);
|
||||
break;
|
||||
case IS_STRING:
|
||||
if (zend_symtable_del(ht, offset->value.str.val, offset->value.str.len+1) == SUCCESS &&
|
||||
ht == &EG(symbol_table)) {
|
||||
case IS_BINARY:
|
||||
case IS_UNICODE: {
|
||||
void *offset_key = Z_UNIVAL_P(offset);
|
||||
int offset_len = Z_UNILEN_P(offset);
|
||||
int free_offset = 0;
|
||||
|
||||
if (UG(unicode) && ht == &EG(symbol_table) && offset->type == IS_UNICODE) {
|
||||
/* Identifier normalization */
|
||||
UChar *norm;
|
||||
int32_t norm_len;
|
||||
|
||||
if (!zend_normalize_identifier(&norm, &norm_len,
|
||||
(UChar*)offset_key, offset_len, 0)) {
|
||||
zend_error(E_WARNING, "Could not normalize identifier: %r", offset_key);
|
||||
} else if ((char*)norm != offset_key) {
|
||||
offset_key = (char*)norm;
|
||||
offset_len = norm_len;
|
||||
free_offset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (zend_u_symtable_del(ht, Z_TYPE_P(offset), offset_key, offset_len+1) == SUCCESS &&
|
||||
ht == &EG(symbol_table)) {
|
||||
zend_execute_data *ex;
|
||||
ulong hash_value = zend_inline_hash_func(offset->value.str.val, offset->value.str.len+1);
|
||||
ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(offset), offset_key, offset_len+1);
|
||||
|
||||
for (ex = EXECUTE_DATA; ex; ex = ex->prev_execute_data) {
|
||||
if (ex->symbol_table == ht) {
|
||||
@ -2868,8 +2948,8 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
|
||||
for (i = 0; i < ex->op_array->last_var; i++) {
|
||||
if (ex->op_array->vars[i].hash_value == hash_value &&
|
||||
ex->op_array->vars[i].name_len == offset->value.str.len &&
|
||||
!memcmp(ex->op_array->vars[i].name, offset->value.str.val, offset->value.str.len)) {
|
||||
ex->op_array->vars[i].name_len == offset_len &&
|
||||
!memcmp(ex->op_array->vars[i].name, offset_key, Z_TYPE_P(offset)==IS_UNICODE?UBYTES(offset_len):offset_len)) {
|
||||
ex->CVs[i] = NULL;
|
||||
break;
|
||||
}
|
||||
@ -2877,7 +2957,11 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (free_offset) {
|
||||
efree(offset_key);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_NULL:
|
||||
zend_hash_del(ht, "", sizeof(""));
|
||||
break;
|
||||
@ -3008,7 +3092,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
|
||||
FREE_OP1_IF_VAR();
|
||||
}
|
||||
if (!EG(exception)) {
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name);
|
||||
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %v did not create an Iterator", ce->name);
|
||||
}
|
||||
zend_throw_exception_internal(NULL TSRMLS_CC);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
@ -3043,8 +3127,11 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
|
||||
char *str_key;
|
||||
uint str_key_len;
|
||||
ulong int_key;
|
||||
if (zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL) == HASH_KEY_IS_STRING
|
||||
&& zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS) {
|
||||
zend_uchar key_type;
|
||||
|
||||
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
|
||||
if (key_type != HASH_KEY_NON_EXISTANT &&
|
||||
zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS) {
|
||||
break;
|
||||
}
|
||||
zend_hash_move_forward(fe_ht);
|
||||
@ -3106,11 +3193,16 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
|
||||
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
|
||||
|
||||
zend_hash_move_forward(fe_ht);
|
||||
} while (key_type != HASH_KEY_IS_STRING || zend_check_property_access(zobj, str_key TSRMLS_CC) != SUCCESS);
|
||||
} while (key_type == HASH_KEY_NON_EXISTANT || zend_check_property_access(zobj, str_key TSRMLS_CC) != SUCCESS);
|
||||
if (use_key) {
|
||||
zend_unmangle_property_name(str_key, &class_name, &prop_name);
|
||||
str_key_len = strlen(prop_name);
|
||||
str_key = estrndup(prop_name, str_key_len);
|
||||
zend_u_unmangle_property_name(key_type == HASH_KEY_IS_UNICODE?IS_UNICODE:IS_STRING, str_key, &class_name, &prop_name);
|
||||
if (key_type == HASH_KEY_IS_UNICODE) {
|
||||
str_key_len = u_strlen((UChar*)prop_name);
|
||||
str_key = (char*)eustrndup((UChar*)prop_name, str_key_len);
|
||||
} else {
|
||||
str_key_len = strlen(prop_name);
|
||||
str_key = estrndup(prop_name, str_key_len);
|
||||
}
|
||||
str_key_len++;
|
||||
}
|
||||
break;
|
||||
@ -3200,6 +3292,16 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
|
||||
key->value.str.len = str_key_len-1;
|
||||
key->type = IS_STRING;
|
||||
break;
|
||||
case HASH_KEY_IS_BINARY:
|
||||
key->value.str.val = str_key;
|
||||
key->value.str.len = str_key_len-1;
|
||||
key->type = IS_BINARY;
|
||||
break;
|
||||
case HASH_KEY_IS_UNICODE:
|
||||
key->value.ustr.val = (UChar*)str_key;
|
||||
key->value.ustr.len = str_key_len-1;
|
||||
key->type = IS_UNICODE;
|
||||
break;
|
||||
case HASH_KEY_IS_LONG:
|
||||
key->value.lval = int_key;
|
||||
key->type = IS_LONG;
|
||||
@ -3221,10 +3323,10 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, ANY)
|
||||
zend_bool isset = 1;
|
||||
HashTable *target_symbol_table;
|
||||
|
||||
if (varname->type != IS_STRING) {
|
||||
if (varname->type != IS_STRING && varname->type != IS_UNICODE) {
|
||||
tmp = *varname;
|
||||
zval_copy_ctor(&tmp);
|
||||
convert_to_string(&tmp);
|
||||
convert_to_text(&tmp);
|
||||
varname = &tmp;
|
||||
}
|
||||
|
||||
@ -3235,7 +3337,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, ANY)
|
||||
}
|
||||
} else {
|
||||
target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
|
||||
if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
|
||||
if (zend_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, (void **) &value) == FAILURE) {
|
||||
isset = 0;
|
||||
}
|
||||
}
|
||||
@ -3301,10 +3403,34 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|
|
||||
}
|
||||
break;
|
||||
case IS_STRING:
|
||||
if (zend_symtable_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) {
|
||||
case IS_BINARY:
|
||||
case IS_UNICODE: {
|
||||
char *offset_key = Z_UNIVAL_P(offset);
|
||||
int offset_len = Z_UNILEN_P(offset);
|
||||
int free_offset = 0;
|
||||
|
||||
if (UG(unicode) && ht == &EG(symbol_table) && Z_TYPE_P(offset) == IS_UNICODE) {
|
||||
/* Identifier normalization */
|
||||
UChar *norm;
|
||||
int32_t norm_len;
|
||||
|
||||
if (!zend_normalize_identifier(&norm, &norm_len,
|
||||
(UChar*)offset_key, offset_len, 0)) {
|
||||
zend_error(E_WARNING, "Could not normalize identifier: %r", offset_key);
|
||||
} else if ((char*)norm != offset_key) {
|
||||
offset_key = (char*)norm;
|
||||
offset_len = norm_len;
|
||||
free_offset = 1;
|
||||
}
|
||||
}
|
||||
if (zend_u_symtable_find(ht, Z_TYPE_P(offset), offset_key, offset_len+1, (void **) &value) == SUCCESS) {
|
||||
isset = 1;
|
||||
}
|
||||
if (free_offset) {
|
||||
efree(offset_key);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IS_NULL:
|
||||
if (zend_hash_find(ht, "", sizeof(""), (void **) &value) == SUCCESS) {
|
||||
isset = 1;
|
||||
@ -3347,7 +3473,9 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|
|
||||
} else {
|
||||
FREE_OP2();
|
||||
}
|
||||
} else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
|
||||
} else if (((*container)->type == IS_STRING ||
|
||||
(*container)->type == IS_BINARY ||
|
||||
(*container)->type == IS_UNICODE) && !prop_dim) { /* string offsets */
|
||||
zval tmp;
|
||||
|
||||
if (offset->type != IS_LONG) {
|
||||
@ -3359,12 +3487,17 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|
|
||||
if (offset->type == IS_LONG) {
|
||||
switch (opline->extended_value) {
|
||||
case ZEND_ISSET:
|
||||
if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
|
||||
if (offset->value.lval >= 0 &&
|
||||
offset->value.lval < Z_UNILEN_PP(container)) {
|
||||
result = 1;
|
||||
}
|
||||
break;
|
||||
case ZEND_ISEMPTY:
|
||||
if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
|
||||
if (offset->value.lval >= 0 &&
|
||||
offset->value.lval < Z_UNILEN_PP(container) &&
|
||||
((Z_TYPE_PP(container) == IS_UNICODE)?
|
||||
(Z_USTRVAL_PP(container)[offset->value.lval] != 0):
|
||||
(Z_STRVAL_PP(container)[offset->value.lval] != '0'))) {
|
||||
result = 1;
|
||||
}
|
||||
break;
|
||||
@ -3432,7 +3565,7 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
|
||||
|
||||
ZEND_VM_HANDLER(142, ZEND_RAISE_ABSTRACT_ERROR, ANY, ANY)
|
||||
{
|
||||
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EG(scope)->name, EX(op_array)->function_name);
|
||||
zend_error_noreturn(E_ERROR, "Cannot call abstract method %v::%v()", EG(scope)->name, EX(op_array)->function_name);
|
||||
ZEND_VM_NEXT_OPCODE(); /* Never reached */
|
||||
}
|
||||
|
||||
@ -3558,7 +3691,7 @@ ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, ANY)
|
||||
zend_class_entry *iface = EX_T(opline->op2.u.var).class_entry;
|
||||
|
||||
if (!(iface->ce_flags & ZEND_ACC_INTERFACE)) {
|
||||
zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name);
|
||||
zend_error_noreturn(E_ERROR, "%v cannot implement %v - it is not an interface", ce->name, iface->name);
|
||||
}
|
||||
|
||||
ce->interfaces[opline->extended_value] = iface;
|
||||
@ -3631,4 +3764,39 @@ ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(151, ZEND_U_NORMALIZE, CONST|TMP|VAR|CV, ANY)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
zval *string = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
zval *result = &EX_T(opline->result.u.var).tmp_var;
|
||||
|
||||
*result = *string;
|
||||
if (!IS_OP1_TMP_FREE()) {
|
||||
zendi_zval_copy_ctor(*result);
|
||||
}
|
||||
|
||||
if (UG(unicode)) {
|
||||
zval var_copy;
|
||||
int use_copy;
|
||||
UChar *norm;
|
||||
int32_t norm_len;
|
||||
|
||||
zend_make_unicode_zval(result, &var_copy, &use_copy);
|
||||
if (use_copy) {
|
||||
zval_dtor(result);
|
||||
*result = var_copy;
|
||||
}
|
||||
if (!zend_normalize_identifier(&norm, &norm_len,
|
||||
Z_USTRVAL_P(result), Z_USTRLEN_P(result), 0)) {
|
||||
zend_error(E_WARNING, "Could not normalize identifier: %r", Z_USTRVAL_P(result));
|
||||
} else if (norm != Z_USTRVAL_P(result)) {
|
||||
efree(Z_USTRVAL_P(result));
|
||||
ZVAL_UNICODEL(result, norm, norm_len, 0);
|
||||
}
|
||||
}
|
||||
FREE_OP1_IF_VAR();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1058,7 +1058,7 @@ function gen_vm($def, $skel) {
|
||||
fputs($f,"#define $op $code\n");
|
||||
}
|
||||
fclose($f);
|
||||
echo "zend_vm_opcodes.h generated succesfull.\n";
|
||||
echo "zend_vm_opcodes.h generated succesfully.\n";
|
||||
|
||||
// Generate zend_vm_execute.h
|
||||
$f = fopen("zend_vm_execute.h", "w+") or die("ERROR: Cannot create zend_vm_execute.h\n");
|
||||
@ -1198,7 +1198,7 @@ function gen_vm($def, $skel) {
|
||||
}
|
||||
|
||||
fclose($f);
|
||||
echo "zend_vm_execute.h generated succesfull.\n";
|
||||
echo "zend_vm_execute.h generated succesfully.\n";
|
||||
}
|
||||
|
||||
function usage() {
|
||||
|
@ -147,3 +147,4 @@
|
||||
#define ZEND_ISSET_ISEMPTY_PROP_OBJ 148
|
||||
#define ZEND_HANDLE_EXCEPTION 149
|
||||
#define ZEND_USER_OPCODE 150
|
||||
#define ZEND_U_NORMALIZE 151
|
||||
|
@ -43,7 +43,7 @@ zend_class_entry *reflection_extension_ptr;
|
||||
/* Method macros */
|
||||
#define METHOD_NOTSTATIC \
|
||||
if (!this_ptr) { \
|
||||
zend_error(E_ERROR, "%s() cannot be called statically", get_active_function_name(TSRMLS_C)); \
|
||||
zend_error(E_ERROR, "%v() cannot be called statically", get_active_function_name(TSRMLS_C)); \
|
||||
return; \
|
||||
} \
|
||||
|
||||
@ -233,7 +233,7 @@ static zend_object_value reflection_objects_new(zend_class_entry *class_type TSR
|
||||
intern->free_ptr = 0;
|
||||
|
||||
ALLOC_HASHTABLE(intern->zo.properties);
|
||||
zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_u_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
|
||||
zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
retval.handle = zend_objects_store_put(intern, NULL, reflection_free_objects_storage, reflection_objects_clone TSRMLS_CC);
|
||||
retval.handlers = &reflection_object_handlers;
|
||||
@ -297,17 +297,17 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
|
||||
}
|
||||
string_printf(str, "class ");
|
||||
}
|
||||
string_write(str, ce->name, ce->name_length);
|
||||
string_printf(str, "%v", ce->name);
|
||||
if (ce->parent) {
|
||||
string_printf(str, " extends %s", ce->parent->name);
|
||||
string_printf(str, " extends %v", ce->parent->name);
|
||||
}
|
||||
|
||||
if (ce->num_interfaces) {
|
||||
zend_uint i;
|
||||
|
||||
string_printf(str, " implements %s", ce->interfaces[0]->name);
|
||||
string_printf(str, " implements %v", ce->interfaces[0]->name);
|
||||
for (i = 1; i < ce->num_interfaces; ++i) {
|
||||
string_printf(str, ", %s", ce->interfaces[i]->name);
|
||||
string_printf(str, ", %v", ce->interfaces[i]->name);
|
||||
}
|
||||
}
|
||||
string_printf(str, " ] {\n");
|
||||
@ -540,7 +540,7 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg
|
||||
string_printf(str, "<required> ");
|
||||
}
|
||||
if (arg_info->class_name) {
|
||||
string_printf(str, "%s ", arg_info->class_name);
|
||||
string_printf(str, "%v ", arg_info->class_name);
|
||||
if (arg_info->allow_null) {
|
||||
string_printf(str, "or NULL ");
|
||||
}
|
||||
@ -554,7 +554,7 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg
|
||||
string_write(str, "&", sizeof("&")-1);
|
||||
}
|
||||
if (arg_info->name) {
|
||||
string_printf(str, "$%s", arg_info->name);
|
||||
string_printf(str, "$%v", arg_info->name);
|
||||
} else {
|
||||
string_printf(str, "$param%d", offset);
|
||||
}
|
||||
@ -671,7 +671,7 @@ static void _function_string(string *str, zend_function *fptr, char* indent TSRM
|
||||
if (fptr->op_array.return_reference) {
|
||||
string_printf(str, "&");
|
||||
}
|
||||
string_printf(str, "%s ] {\n", fptr->common.function_name);
|
||||
string_printf(str, "%v ] {\n", fptr->common.function_name);
|
||||
/* The information where a function is declared is only available for user classes */
|
||||
if (fptr->type == ZEND_USER_FUNCTION) {
|
||||
string_printf(str, "%s @@ %s %d - %d\n", indent,
|
||||
@ -720,8 +720,8 @@ static void _property_string(string *str, zend_property_info *prop, char *prop_n
|
||||
string_printf(str, "static ");
|
||||
}
|
||||
|
||||
zend_unmangle_property_name(prop->name, &class_name, &prop_name);
|
||||
string_printf(str, "$%s", prop_name);
|
||||
zend_u_unmangle_property_name(UG(unicode)?IS_UNICODE:IS_STRING, prop->name, &class_name, &prop_name);
|
||||
string_printf(str, "$%v", prop_name);
|
||||
}
|
||||
|
||||
string_printf(str, " ]\n");
|
||||
@ -865,7 +865,11 @@ ZEND_API void zend_reflection_class_factory(zend_class_entry *ce, zval *object T
|
||||
zval *name;
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(name, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(name, ce->name, ce->name_length, 1);
|
||||
}
|
||||
reflection_instanciate(reflection_class_ptr, object TSRMLS_CC);
|
||||
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
intern->ptr = ce;
|
||||
@ -912,7 +916,11 @@ static void reflection_parameter_factory(zend_function *fptr, struct _zend_arg_i
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
if (arg_info->name) {
|
||||
ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(name, (UChar*)arg_info->name, arg_info->name_len, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(name, arg_info->name, arg_info->name_len, 1);
|
||||
}
|
||||
} else {
|
||||
ZVAL_NULL(name);
|
||||
}
|
||||
@ -937,7 +945,11 @@ static void reflection_function_factory(zend_function *function, zval *object TS
|
||||
zval *name;
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, function->common.function_name, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)function->common.function_name, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, function->common.function_name, 1);
|
||||
}
|
||||
|
||||
reflection_instanciate(reflection_function_ptr, object TSRMLS_CC);
|
||||
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
@ -956,9 +968,14 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho
|
||||
zval *classname;
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, method->common.function_name, 1);
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)method->common.function_name, 1);
|
||||
ZVAL_UNICODEL(classname, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, method->common.function_name, 1);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
}
|
||||
reflection_instanciate(reflection_method_ptr, object TSRMLS_CC);
|
||||
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
intern->ptr = method;
|
||||
@ -978,7 +995,7 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info
|
||||
property_reference *reference;
|
||||
char *class_name, *prop_name;
|
||||
|
||||
zend_unmangle_property_name(prop->name, &class_name, &prop_name);
|
||||
zend_u_unmangle_property_name(UG(unicode)?IS_UNICODE:IS_STRING, prop->name, &class_name, &prop_name);
|
||||
|
||||
if (!(prop->flags & ZEND_ACC_PRIVATE)) {
|
||||
/* we have to seach the class hierarchy for this (implicit) public or protected property */
|
||||
@ -997,10 +1014,14 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, prop_name, 1);
|
||||
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)prop_name, 1);
|
||||
ZVAL_UNICODEL(classname, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, prop_name, 1);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
}
|
||||
|
||||
reflection_instanciate(reflection_property_ptr, object TSRMLS_CC);
|
||||
intern = (reflection_object *) zend_object_store_get_object(object TSRMLS_CC);
|
||||
@ -1144,7 +1165,7 @@ ZEND_METHOD(reflection, export)
|
||||
}
|
||||
|
||||
if (!retval_ptr) {
|
||||
zend_error(E_WARNING, "%s::__toString() did not return anything", Z_OBJCE_P(object)->name);
|
||||
zend_error(E_WARNING, "%v::__toString() did not return anything", Z_OBJCE_P(object)->name);
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@ -1211,13 +1232,15 @@ ZEND_METHOD(reflection_function, __construct)
|
||||
{
|
||||
zval *name;
|
||||
zval *object;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
reflection_object *intern;
|
||||
zend_function *fptr;
|
||||
char *name_str;
|
||||
int name_len;
|
||||
zend_uchar type;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &name_str, &name_len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1226,17 +1249,20 @@ ZEND_METHOD(reflection_function, __construct)
|
||||
if (intern == NULL) {
|
||||
return;
|
||||
}
|
||||
lcname = do_alloca(name_len + 1);
|
||||
zend_str_tolower_copy(lcname, name_str, name_len);
|
||||
if (zend_hash_find(EG(function_table), lcname, name_len + 1, (void **)&fptr) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
lcname = zend_u_str_case_fold(type, name_str, name_len, 1, &lcname_len);
|
||||
if (zend_u_hash_find(EG(function_table), type, lcname, lcname_len + 1, (void **)&fptr) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Function %s() does not exist", name_str);
|
||||
"Function %R() does not exist", type, name_str);
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, fptr->common.function_name, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)fptr->common.function_name, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, fptr->common.function_name, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
|
||||
intern->ptr = fptr;
|
||||
intern->free_ptr = 0;
|
||||
@ -1421,7 +1447,7 @@ ZEND_METHOD(reflection_function, invoke)
|
||||
|
||||
if (result == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Invocation of function %s() failed", fptr->common.function_name);
|
||||
"Invocation of function %v() failed", fptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1485,7 +1511,7 @@ ZEND_METHOD(reflection_function, invokeArgs)
|
||||
|
||||
if (result == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Invocation of function %s() failed", fptr->common.function_name);
|
||||
"Invocation of function %v() failed", fptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1598,19 +1624,20 @@ ZEND_METHOD(reflection_parameter, __construct)
|
||||
|
||||
/* First, find the function */
|
||||
switch (Z_TYPE_P(reference)) {
|
||||
case IS_UNICODE:
|
||||
case IS_STRING: {
|
||||
char *lcname;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
|
||||
convert_to_string_ex(&reference);
|
||||
lcname = do_alloca(Z_STRLEN_P(reference) + 1);
|
||||
zend_str_tolower_copy(lcname, Z_STRVAL_P(reference), Z_STRLEN_P(reference));
|
||||
if (zend_hash_find(EG(function_table), lcname, (int) Z_STRLEN_P(reference) + 1, (void**) &fptr) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
convert_to_text_ex(&reference);
|
||||
lcname = zend_u_str_case_fold(Z_TYPE_P(reference), Z_STRVAL_P(reference), Z_STRLEN_P(reference), 1, &lcname_len);
|
||||
if (zend_u_hash_find(EG(function_table), Z_TYPE_P(reference), lcname, lcname_len + 1, (void**) &fptr) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Function %s() does not exist", Z_STRVAL_P(reference));
|
||||
"Function %R() does not exist", Z_TYPE_P(reference), Z_STRVAL_P(reference));
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1618,7 +1645,8 @@ ZEND_METHOD(reflection_parameter, __construct)
|
||||
zval **classref;
|
||||
zval **method;
|
||||
zend_class_entry **pce;
|
||||
char *lcname;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
|
||||
if ((zend_hash_index_find(Z_ARRVAL_P(reference), 0, (void **) &classref) == FAILURE)
|
||||
|| (zend_hash_index_find(Z_ARRVAL_P(reference), 1, (void **) &method) == FAILURE)) {
|
||||
@ -1629,25 +1657,24 @@ ZEND_METHOD(reflection_parameter, __construct)
|
||||
if (Z_TYPE_PP(classref) == IS_OBJECT) {
|
||||
ce = Z_OBJCE_PP(classref);
|
||||
} else {
|
||||
convert_to_string_ex(classref);
|
||||
if (zend_lookup_class(Z_STRVAL_PP(classref), Z_STRLEN_PP(classref), &pce TSRMLS_CC) == FAILURE) {
|
||||
convert_to_text_ex(classref);
|
||||
if (zend_u_lookup_class(Z_TYPE_PP(classref), Z_UNIVAL_PP(classref), Z_UNILEN_PP(classref), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Class %s does not exist", Z_STRVAL_PP(classref));
|
||||
"Class %R does not exist", Z_TYPE_PP(classref), Z_UNIVAL_PP(classref));
|
||||
return;
|
||||
}
|
||||
ce = *pce;
|
||||
}
|
||||
|
||||
convert_to_string_ex(method);
|
||||
lcname = do_alloca(Z_STRLEN_PP(method) + 1);
|
||||
zend_str_tolower_copy(lcname, Z_STRVAL_PP(method), Z_STRLEN_PP(method));
|
||||
if (zend_hash_find(&ce->function_table, lcname, (int)(Z_STRLEN_PP(method) + 1), (void **) &fptr) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
convert_to_text_ex(method);
|
||||
lcname = zend_u_str_case_fold(Z_TYPE_PP(method), Z_UNIVAL_PP(method), Z_UNILEN_PP(method), 1, &lcname_len);
|
||||
if (zend_u_hash_find(&ce->function_table, Z_TYPE_PP(method), lcname, lcname_len + 1, (void **) &fptr) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Method %s::%s() does not exist", Z_STRVAL_PP(classref), Z_STRVAL_PP(method));
|
||||
"Method %R::%R() does not exist", Z_TYPE_PP(classref), Z_UNIVAL_PP(classref), Z_TYPE_PP(method), Z_UNIVAL_PP(method));
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1683,7 +1710,11 @@ ZEND_METHOD(reflection_parameter, __construct)
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
if (arg_info[position].name) {
|
||||
ZVAL_STRINGL(name, arg_info[position].name, arg_info[position].name_len, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(name, (UChar*)arg_info[position].name, arg_info[position].name_len, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(name, arg_info[position].name, arg_info[position].name_len, 1);
|
||||
}
|
||||
} else {
|
||||
ZVAL_NULL(name);
|
||||
}
|
||||
@ -1739,15 +1770,16 @@ ZEND_METHOD(reflection_parameter, getClass)
|
||||
RETURN_NULL();
|
||||
} else {
|
||||
zend_class_entry **pce;
|
||||
char *lcname = do_alloca(param->arg_info->class_name_len + 1);
|
||||
zend_str_tolower_copy(lcname, param->arg_info->class_name, param->arg_info->class_name_len);
|
||||
if (zend_hash_find(EG(class_table), lcname, param->arg_info->class_name_len + 1, (void **) &pce) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
unsigned int lcname_len;
|
||||
char *lcname = zend_u_str_case_fold(UG(unicode)?IS_UNICODE:IS_STRING, param->arg_info->class_name, param->arg_info->class_name_len, 0, &lcname_len);
|
||||
|
||||
if (zend_u_hash_find(EG(class_table), UG(unicode)?IS_UNICODE:IS_STRING, lcname, lcname_len + 1, (void **) &pce) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Class %s does not exist", param->arg_info->class_name);
|
||||
"Class %v does not exist", param->arg_info->class_name);
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
zend_reflection_class_factory(*pce, return_value TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
@ -1884,14 +1916,16 @@ ZEND_METHOD(reflection_method, __construct)
|
||||
zval *name, *classname;
|
||||
zval *object;
|
||||
reflection_object *intern;
|
||||
unsigned int lcname_len;
|
||||
char *lcname;
|
||||
zend_class_entry **pce;
|
||||
zend_class_entry *ce;
|
||||
zend_function *mptr;
|
||||
char *name_str;
|
||||
int name_len;
|
||||
zend_uchar type;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &classname, &name_str, &name_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zt", &classname, &name_str, &name_len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1904,9 +1938,10 @@ ZEND_METHOD(reflection_method, __construct)
|
||||
/* Find the class entry */
|
||||
switch (Z_TYPE_P(classname)) {
|
||||
case IS_STRING:
|
||||
if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
|
||||
case IS_UNICODE:
|
||||
if (zend_u_lookup_class(Z_TYPE_P(classname), Z_UNIVAL_P(classname), Z_UNILEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Class %s does not exist", Z_STRVAL_P(classname));
|
||||
"Class %v does not exist", Z_UNIVAL_P(classname));
|
||||
return;
|
||||
}
|
||||
ce = *pce;
|
||||
@ -1922,22 +1957,29 @@ ZEND_METHOD(reflection_method, __construct)
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(classname, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
|
||||
|
||||
lcname = do_alloca(name_len + 1);
|
||||
zend_str_tolower_copy(lcname, name_str, name_len);
|
||||
lcname = zend_u_str_case_fold(type, name_str, name_len, 1, &lcname_len);
|
||||
|
||||
if (zend_hash_find(&ce->function_table, lcname, name_len + 1, (void **) &mptr) == FAILURE) {
|
||||
free_alloca(lcname);
|
||||
if (zend_u_hash_find(&ce->function_table, type, lcname, lcname_len + 1, (void **) &mptr) == FAILURE) {
|
||||
efree(lcname);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Method %s::%s() does not exist", ce->name, name_str);
|
||||
"Method %v::%R() does not exist", ce->name, type, name_str);
|
||||
return;
|
||||
}
|
||||
free_alloca(lcname);
|
||||
efree(lcname);
|
||||
|
||||
MAKE_STD_ZVAL(name);
|
||||
ZVAL_STRING(name, mptr->common.function_name, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(name, (UChar*)mptr->common.function_name, 1);
|
||||
} else {
|
||||
ZVAL_STRING(name, mptr->common.function_name, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL);
|
||||
intern->ptr = mptr;
|
||||
intern->free_ptr = 0;
|
||||
@ -1989,11 +2031,11 @@ ZEND_METHOD(reflection_method, invoke)
|
||||
(mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) {
|
||||
if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke abstract method %s::%s()",
|
||||
"Trying to invoke abstract method %v::%v()",
|
||||
mptr->common.scope->name, mptr->common.function_name);
|
||||
} else {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke %s method %s::%s() from scope %s",
|
||||
"Trying to invoke %s method %v::%v() from scope %v",
|
||||
mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
|
||||
mptr->common.scope->name, mptr->common.function_name,
|
||||
Z_OBJCE_P(getThis())->name);
|
||||
@ -2054,7 +2096,7 @@ ZEND_METHOD(reflection_method, invoke)
|
||||
|
||||
if (result == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
|
||||
"Invocation of method %v::%v() failed", mptr->common.scope->name, mptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2092,11 +2134,11 @@ ZEND_METHOD(reflection_method, invokeArgs)
|
||||
(mptr->common.fn_flags & ZEND_ACC_ABSTRACT)) {
|
||||
if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke abstract method %s::%s",
|
||||
"Trying to invoke abstract method %v::%v",
|
||||
mptr->common.scope->name, mptr->common.function_name);
|
||||
} else {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke %s method %s::%s from scope %s",
|
||||
"Trying to invoke %s method %v::%v from scope %v",
|
||||
mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private",
|
||||
mptr->common.scope->name, mptr->common.function_name,
|
||||
Z_OBJCE_P(getThis())->name);
|
||||
@ -2123,7 +2165,7 @@ ZEND_METHOD(reflection_method, invokeArgs)
|
||||
if (!object) {
|
||||
efree(params);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Trying to invoke non static method %s::%s without an object",
|
||||
"Trying to invoke non static method %v::%v without an object",
|
||||
mptr->common.scope->name, mptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
@ -2158,7 +2200,7 @@ ZEND_METHOD(reflection_method, invokeArgs)
|
||||
|
||||
if (result == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Invocation of method %s::%s() failed", mptr->common.scope->name, mptr->common.function_name);
|
||||
"Invocation of method %v::%v() failed", mptr->common.scope->name, mptr->common.function_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2308,7 +2350,11 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob
|
||||
|
||||
if (Z_TYPE_P(argument) == IS_OBJECT) {
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(classname, (UChar*)Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
|
||||
intern->ptr = Z_OBJCE_P(argument);
|
||||
if (is_object) {
|
||||
@ -2317,7 +2363,7 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob
|
||||
}
|
||||
} else {
|
||||
convert_to_string_ex(&argument);
|
||||
if (zend_lookup_class(Z_STRVAL_P(argument), Z_STRLEN_P(argument), &ce TSRMLS_CC) == FAILURE) {
|
||||
if (zend_u_lookup_class(Z_TYPE_P(argument), Z_UNIVAL_P(argument), Z_UNILEN_P(argument), &ce TSRMLS_CC) == FAILURE) {
|
||||
if (!EG(exception)) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, -1 TSRMLS_CC, "Class %s does not exist", Z_STRVAL_P(argument));
|
||||
}
|
||||
@ -2325,7 +2371,11 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(classname, (UChar*)((*ce)->name), (*ce)->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL);
|
||||
|
||||
intern->ptr = *ce;
|
||||
@ -2613,17 +2663,19 @@ ZEND_METHOD(reflection_class, hasMethod)
|
||||
{
|
||||
reflection_object *intern;
|
||||
zend_class_entry *ce;
|
||||
unsigned int lc_name_len;
|
||||
char *name, *lc_name;
|
||||
int name_len;
|
||||
zend_uchar type;
|
||||
|
||||
METHOD_NOTSTATIC;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &name, &name_len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
GET_REFLECTION_OBJECT_PTR(ce);
|
||||
lc_name = zend_str_tolower_dup(name, name_len);
|
||||
if (zend_hash_exists(&ce->function_table, lc_name, name_len + 1)) {
|
||||
lc_name = zend_u_str_case_fold(type, name, name_len, 1, &lc_name_len);
|
||||
if (zend_u_hash_exists(&ce->function_table, type, lc_name, lc_name_len + 1)) {
|
||||
efree(lc_name);
|
||||
RETURN_TRUE;
|
||||
} else {
|
||||
@ -2640,23 +2692,25 @@ ZEND_METHOD(reflection_class, getMethod)
|
||||
reflection_object *intern;
|
||||
zend_class_entry *ce;
|
||||
zend_function *mptr;
|
||||
unsigned int lc_name_len;
|
||||
char *name, *lc_name;
|
||||
int name_len;
|
||||
zend_uchar type;
|
||||
|
||||
METHOD_NOTSTATIC;
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "t", &name, &name_len, &type) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
GET_REFLECTION_OBJECT_PTR(ce);
|
||||
lc_name = zend_str_tolower_dup(name, name_len);
|
||||
if (zend_hash_find(&ce->function_table, lc_name, name_len + 1, (void**) &mptr) == SUCCESS) {
|
||||
lc_name = zend_u_str_case_fold(type, name, name_len, 1, &lc_name_len);
|
||||
if (zend_u_hash_find(&ce->function_table, type, lc_name, lc_name_len + 1, (void**) &mptr) == SUCCESS) {
|
||||
reflection_method_factory(ce, mptr, return_value TSRMLS_CC);
|
||||
efree(lc_name);
|
||||
} else {
|
||||
efree(lc_name);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Method %s does not exist", name);
|
||||
"Method %R does not exist", type, name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2989,7 +3043,7 @@ ZEND_METHOD(reflection_class, newInstance)
|
||||
zend_fcall_info_cache fcc;
|
||||
|
||||
if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %v", ce->name);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3017,7 +3071,7 @@ ZEND_METHOD(reflection_class, newInstance)
|
||||
if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
|
||||
efree(params);
|
||||
zval_ptr_dtor(&retval_ptr);
|
||||
zend_error(E_WARNING, "Invocation of %s's constructor failed", ce->name);
|
||||
zend_error(E_WARNING, "Invocation of %v's constructor failed", ce->name);
|
||||
RETURN_NULL();
|
||||
}
|
||||
if (retval_ptr) {
|
||||
@ -3089,7 +3143,8 @@ ZEND_METHOD(reflection_class, isSubclassOf)
|
||||
|
||||
switch(class_name->type) {
|
||||
case IS_STRING:
|
||||
if (zend_lookup_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), &pce TSRMLS_CC) == FAILURE) {
|
||||
case IS_UNICODE:
|
||||
if (zend_u_lookup_class(Z_TYPE_P(class_name), Z_UNIVAL_P(class_name), Z_UNILEN_P(class_name), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Interface %s does not exist", Z_STRVAL_P(class_name));
|
||||
return;
|
||||
@ -3135,7 +3190,8 @@ ZEND_METHOD(reflection_class, implementsInterface)
|
||||
|
||||
switch(interface->type) {
|
||||
case IS_STRING:
|
||||
if (zend_lookup_class(Z_STRVAL_P(interface), Z_STRLEN_P(interface), &pce TSRMLS_CC) == FAILURE) {
|
||||
case IS_UNICODE:
|
||||
if (zend_u_lookup_class(Z_TYPE_P(interface), Z_UNIVAL_P(interface), Z_UNILEN_P(interface), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Interface %s does not exist", Z_STRVAL_P(interface));
|
||||
return;
|
||||
@ -3161,7 +3217,7 @@ ZEND_METHOD(reflection_class, implementsInterface)
|
||||
|
||||
if (!(interface_ce->ce_flags & ZEND_ACC_INTERFACE)) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Interface %s is a Class", interface_ce->name);
|
||||
"Interface %v is a Class", interface_ce->name);
|
||||
return;
|
||||
}
|
||||
RETURN_BOOL(instanceof_function(ce, interface_ce TSRMLS_CC));
|
||||
@ -3267,7 +3323,8 @@ ZEND_METHOD(reflection_property, __construct)
|
||||
/* Find the class entry */
|
||||
switch (Z_TYPE_P(classname)) {
|
||||
case IS_STRING:
|
||||
if (zend_lookup_class(Z_STRVAL_P(classname), Z_STRLEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
|
||||
case IS_UNICODE:
|
||||
if (zend_u_lookup_class(Z_TYPE_P(classname), Z_UNIVAL_P(classname), Z_UNILEN_P(classname), &pce TSRMLS_CC) == FAILURE) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Class %s does not exist", Z_STRVAL_P(classname));
|
||||
return;
|
||||
@ -3286,7 +3343,7 @@ ZEND_METHOD(reflection_property, __construct)
|
||||
|
||||
if (zend_hash_find(&ce->properties_info, name_str, name_len + 1, (void **) &property_info) == FAILURE || (property_info->flags & ZEND_ACC_SHADOW)) {
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Property %s::$%s does not exist", ce->name, name_str);
|
||||
"Property %v::$%s does not exist", ce->name, name_str);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3307,12 +3364,20 @@ ZEND_METHOD(reflection_property, __construct)
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(classname);
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODEL(classname, (UChar*)ce->name, ce->name_length, 1);
|
||||
} else {
|
||||
ZVAL_STRINGL(classname, ce->name, ce->name_length, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL);
|
||||
|
||||
zend_unmangle_property_name(property_info->name, &class_name, &prop_name);
|
||||
zend_u_unmangle_property_name(UG(unicode)?IS_UNICODE:IS_STRING, property_info->name, &class_name, &prop_name);
|
||||
MAKE_STD_ZVAL(propname);
|
||||
ZVAL_STRING(propname, prop_name, 1);
|
||||
if (UG(unicode)) {
|
||||
ZVAL_UNICODE(propname, (UChar*)prop_name, 1);
|
||||
} else {
|
||||
ZVAL_STRING(propname, prop_name, 1);
|
||||
}
|
||||
zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &propname, sizeof(zval *), NULL);
|
||||
|
||||
reference = (property_reference*) emalloc(sizeof(property_reference));
|
||||
@ -3421,6 +3486,7 @@ ZEND_METHOD(reflection_property, getValue)
|
||||
property_reference *ref;
|
||||
zval *object;
|
||||
zval **member= NULL;
|
||||
zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
METHOD_NOTSTATIC;
|
||||
GET_REFLECTION_OBJECT_PTR(ref);
|
||||
@ -3432,16 +3498,16 @@ ZEND_METHOD(reflection_property, getValue)
|
||||
|
||||
if ((ref->prop->flags & ZEND_ACC_STATIC)) {
|
||||
zend_update_class_constants(intern->ce TSRMLS_CC);
|
||||
if (zend_hash_quick_find(intern->ce->static_members, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %s", ref->prop->name);
|
||||
if (zend_u_hash_quick_find(intern->ce->static_members, utype, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %v", ref->prop->name);
|
||||
/* Bails out */
|
||||
}
|
||||
} else {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &object) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
if (zend_hash_quick_find(Z_OBJPROP_P(object), ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %s", ref->prop->name);
|
||||
if (zend_u_hash_quick_find(Z_OBJPROP_P(object), utype, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %v", ref->prop->name);
|
||||
/* Bails out */
|
||||
}
|
||||
}
|
||||
@ -3463,6 +3529,7 @@ ZEND_METHOD(reflection_property, setValue)
|
||||
int setter_done = 0;
|
||||
zval *tmp;
|
||||
HashTable *prop_table;
|
||||
zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
|
||||
|
||||
METHOD_NOTSTATIC;
|
||||
GET_REFLECTION_OBJECT_PTR(ref);
|
||||
@ -3486,8 +3553,8 @@ ZEND_METHOD(reflection_property, setValue)
|
||||
prop_table = Z_OBJPROP_P(object);
|
||||
}
|
||||
|
||||
if (zend_hash_quick_find(prop_table, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &variable_ptr) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %s", ref->prop->name);
|
||||
if (zend_u_hash_quick_find(prop_table, utype, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &variable_ptr) == FAILURE) {
|
||||
zend_error(E_ERROR, "Internal error: Could not find the property %v", ref->prop->name);
|
||||
/* Bails out */
|
||||
}
|
||||
if (*variable_ptr == value) {
|
||||
@ -3510,7 +3577,7 @@ ZEND_METHOD(reflection_property, setValue)
|
||||
if (PZVAL_IS_REF(value)) {
|
||||
SEPARATE_ZVAL(&value);
|
||||
}
|
||||
zend_hash_quick_update(prop_table, ref->prop->name, ref->prop->name_length+1, ref->prop->h, &value, sizeof(zval *), (void **) &foo);
|
||||
zend_u_hash_quick_update(prop_table, utype, ref->prop->name, ref->prop->name_length+1, ref->prop->h, &value, sizeof(zval *), (void **) &foo);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@ -3943,12 +4010,13 @@ static zend_object_handlers *zend_std_obj_handlers;
|
||||
/* {{{ _reflection_write_property */
|
||||
static void _reflection_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
|
||||
{
|
||||
if (Z_TYPE_P(member) == IS_STRING
|
||||
&& zend_hash_exists(&Z_OBJCE_P(object)->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1)
|
||||
&& (!strcmp(Z_STRVAL_P(member), "name") || !strcmp(Z_STRVAL_P(member), "class")))
|
||||
if ((Z_TYPE_P(member) == IS_STRING || Z_TYPE_P(member) == IS_UNICODE)
|
||||
&& zend_u_hash_exists(&Z_OBJCE_P(object)->default_properties, Z_TYPE_P(member), Z_UNIVAL_P(member), Z_UNILEN_P(member)+1)
|
||||
&& (ZEND_U_EQUAL(Z_TYPE_P(member), Z_UNIVAL_P(member), Z_UNILEN_P(member), "name", sizeof("name")-1) ||
|
||||
ZEND_U_EQUAL(Z_TYPE_P(member), Z_UNIVAL_P(member), Z_UNILEN_P(member), "class", sizeof("class")-1)))
|
||||
{
|
||||
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
|
||||
"Cannot set read-only property %s::$%s", Z_OBJCE_P(object)->name, Z_STRVAL_P(member));
|
||||
"Cannot set read-only property %v::$%R", Z_OBJCE_P(object)->name, Z_TYPE_P(member), Z_UNIVAL_P(member));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4038,6 +4106,20 @@ ZEND_API void zend_register_reflection_api(TSRMLS_D) {
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void init_reflection_api(TSRMLS_D)
|
||||
{
|
||||
reflection_exception_ptr = zend_get_named_class_entry("ReflectionException", sizeof("ReflectionException")-1 TSRMLS_CC);
|
||||
reflection_ptr = zend_get_named_class_entry("Reflection", sizeof("Reflection")-1 TSRMLS_CC);
|
||||
reflector_ptr = zend_get_named_class_entry("Reflector", sizeof("Reflector")-1 TSRMLS_CC);
|
||||
reflection_function_ptr = zend_get_named_class_entry("ReflectionFunction", sizeof("ReflectionFunction")-1 TSRMLS_CC);
|
||||
reflection_parameter_ptr = zend_get_named_class_entry("ReflectionParameter", sizeof("ReflectionParameter")-1 TSRMLS_CC);
|
||||
reflection_method_ptr = zend_get_named_class_entry("ReflectionMethod", sizeof("ReflectionMethod")-1 TSRMLS_CC);
|
||||
reflection_class_ptr = zend_get_named_class_entry("ReflectionClass", sizeof("ReflectionClass")-1 TSRMLS_CC);
|
||||
reflection_object_ptr = zend_get_named_class_entry("ReflectionObject", sizeof("ReflectionObject")-1 TSRMLS_CC);
|
||||
reflection_property_ptr = zend_get_named_class_entry("ReflectionProperty", sizeof("ReflectionProperty")-1 TSRMLS_CC);
|
||||
reflection_extension_ptr = zend_get_named_class_entry("ReflectionExtension", sizeof("ReflectionExtension")-1 TSRMLS_CC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -26,6 +26,8 @@ BEGIN_EXTERN_C()
|
||||
ZEND_API void zend_register_reflection_api(TSRMLS_D);
|
||||
ZEND_API void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSRMLS_DC);
|
||||
|
||||
void init_reflection_api(TSRMLS_D);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user