/2.1/Source/ExtSupport/PHP4/Variables.cpp
C++ | 3574 lines | 2902 code | 469 blank | 203 comment | 661 complexity | ccf186d0a57acaa894deee49e80d345c MD5 | raw file
Possible License(s): CPL-1.0, GPL-2.0, CC-BY-SA-3.0, MPL-2.0-no-copyleft-exception, Apache-2.0
Large files files are truncated, but you can click here to view the full file
- //
- // ExtSupport.PHP4 - substitute for php4ts.dll
- //
- // Variables.cpp
- // - contains definitions of variables related functions
- //
-
- #include "stdafx.h"
- #include "Variables.h"
- #include "Helpers.h"
- #include "ExtSupport.h"
- #include "Memory.h"
- #include "Errors.h"
- #include "Hash.h"
- #include "Resources.h"
- #include "TsrmLs.h"
- #include "Request.h"
- #include "Constants.h"
- #include "Unsupported.h"
- #include "Spprintf.h"
- #include "Parameters.h"
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <limits.h>
- #include <math.h>
-
- using namespace System;
-
- using namespace PHP::ExtManager;
-
- #pragma unmanaged
-
- static inline char *
- zend_str_tolower_dup(const char *source, unsigned int length)
- {
- return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
- }
-
- char *empty_string = ""; /* in order to save emalloc() and efree() time for
- * empty strings (usually used to denote empty
- * return values in failed functions).
- * The macro STR_FREE() will not efree() it.
- */
-
- #define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
-
- #define zend_strtod(str, endptr) strtod(str, endptr)
-
- zval zval_used_for_init = { NULL, IS_NULL, 0, 1 };
-
- zend_utility_values zend_uv = { ".php", 4, 1 };
-
- // copied from zend_API.c and slightly modified
- #define zendi_convert_scalar_to_number(op, holder, result) \
- if (op==result) { \
- convert_scalar_to_number(op TSRMLS_CC); \
- } else { \
- switch ((op)->type) { \
- case IS_STRING: \
- { \
- switch (((holder).type=is_numeric_string((op)->value.str.val, (op)->value.str.len, &(holder).value.lval, &(holder).value.dval, 1))) { \
- case IS_DOUBLE: \
- case IS_LONG: \
- break; \
- default: \
- (holder).value.lval = strtol((op)->value.str.val, NULL, 10); \
- (holder).type = IS_LONG; \
- break; \
- } \
- (op) = &(holder); \
- break; \
- } \
- case IS_BOOL: \
- case IS_RESOURCE: \
- (holder).value.lval = (op)->value.lval; \
- (holder).type = IS_LONG; \
- (op) = &(holder); \
- break; \
- case IS_NULL: \
- (holder).value.lval = 0; \
- (holder).type = IS_LONG; \
- (op) = &(holder); \
- break; \
- } \
- }
-
- // copied from zend_API.c
- #define DVAL_TO_LVAL(d, l) (l) = (d) > LONG_MAX ? (unsigned long) (d) : (long) (d)
-
- // copied from zend_API.c
- #define zendi_convert_to_long(op, holder, result) \
- if (op==result) { \
- convert_to_long(op); \
- } else if ((op)->type != IS_LONG) { \
- switch ((op)->type) { \
- case IS_NULL: \
- (holder).value.lval = 0; \
- break; \
- case IS_DOUBLE: \
- DVAL_TO_LVAL((op)->value.dval, (holder).value.lval); \
- break; \
- case IS_STRING: \
- (holder).value.lval = strtol((op)->value.str.val, NULL, 10); \
- break; \
- case IS_ARRAY: \
- (holder).value.lval = (zend_hash_num_elements((op)->value.ht)?1:0); \
- break; \
- case IS_OBJECT: \
- (holder).value.lval = (zend_hash_num_elements(Z_OBJPROP_P(op))?1:0); \
- break; \
- case IS_BOOL: \
- case IS_RESOURCE: \
- (holder).value.lval = (op)->value.lval; \
- break; \
- default: \
- zend_error(E_WARNING, "Cannot convert to ordinal value"); \
- (holder).value.lval = 0; \
- break; \
- } \
- (holder).type = IS_LONG; \
- (op) = &(holder); \
- }
-
- // copied from zend_API.c
- #define zendi_convert_to_boolean(op, holder, result) \
- if (op==result) { \
- convert_to_boolean(op); \
- } else if ((op)->type != IS_BOOL) { \
- switch ((op)->type) { \
- case IS_NULL: \
- (holder).value.lval = 0; \
- break; \
- case IS_RESOURCE: \
- case IS_LONG: \
- (holder).value.lval = ((op)->value.lval ? 1 : 0); \
- break; \
- case IS_DOUBLE: \
- (holder).value.lval = ((op)->value.dval ? 1 : 0); \
- break; \
- case IS_STRING: \
- if ((op)->value.str.len == 0 \
- || ((op)->value.str.len==1 && (op)->value.str.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; \
- case IS_OBJECT: \
- (holder).value.lval = (zend_hash_num_elements(Z_OBJPROP_P(op))?1:0); \
- break; \
- default: \
- (holder).value.lval = 0; \
- break; \
- } \
- (holder).type = IS_BOOL; \
- (op) = &(holder); \
- }
-
- // copied from zend_API.c and beautified
- ZEND_API char *zend_zval_type_name(zval *arg)
- {
- switch (arg->type)
- {
- case IS_NULL: return "null";
- case IS_LONG: return "integer";
- case IS_DOUBLE: return "double";
- case IS_STRING: return "string";
- case IS_ARRAY: return "array";
- case IS_OBJECT: return "object";
- case IS_BOOL: return "boolean";
- case IS_RESOURCE: return "resource";
-
- default: return "unknown";
- }
- }
-
- // copied from zend_variables.c, slightly modified and beautified
- #ifdef PHP4TS
- ZEND_API int _zval_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC)
- {
- switch (zvalue->type)
- {
- case IS_RESOURCE: {
- TSRMLS_FETCH();
- _zend_list_addref(zvalue->value.lval, tsrm_ls);
- }
- break;
-
- case IS_BOOL:
- case IS_LONG:
- case IS_NULL: break;
-
- case IS_CONSTANT:
- case IS_STRING: if (zvalue->value.str.val)
- {
- if (zvalue->value.str.len==0)
- {
- zvalue->value.str.val = empty_string;
- return SUCCESS;
- }
- }
- CHECK_ZVAL_STRING_REL(zvalue);
- zvalue->value.str.val = (char *)estrndup_rel(zvalue->value.str.val, zvalue->value.str.len);
- break;
-
- case IS_ARRAY:
- case IS_CONSTANT_ARRAY:
- {
- zval *tmp;
- HashTable *original_ht = zvalue->value.ht;
-
- TSRMLS_FETCH();
- if (zvalue->value.ht == &EG(symbol_table)) return SUCCESS;
-
- ALLOC_HASHTABLE_REL(zvalue->value.ht);
- zend_hash_init(zvalue->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
- zend_hash_copy(zvalue->value.ht, original_ht, (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
- }
- break;
-
- case IS_OBJECT: {
- zval *tmp;
- HashTable *original_ht = Z_OBJPROP_P(zvalue);
- TSRMLS_FETCH();
-
- if (original_ht == &EG(symbol_table)) return SUCCESS; /* do nothing */
-
- ALLOC_HASHTABLE_REL(Z_OBJPROP_P(zvalue));
- zend_hash_init(Z_OBJPROP_P(zvalue), 0, NULL, ZVAL_PTR_DTOR, 0);
- zend_hash_copy(Z_OBJPROP_P(zvalue), original_ht,
- (copy_ctor_func_t)zval_add_ref, (void *) &tmp, sizeof(zval *));
- }
- break;
- }
- return SUCCESS;
- }
- #elif defined(PHP5TS)
- ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
- {
- switch (zvalue->type) {
- case IS_RESOURCE: {
- TSRMLS_FETCH();
-
- zend_list_addref(zvalue->value.lval);
- }
- break;
- case IS_BOOL:
- case IS_LONG:
- case IS_NULL:
- break;
- case IS_CONSTANT:
- case IS_STRING:
- CHECK_ZVAL_STRING_REL(zvalue);
- zvalue->value.str.val = (char *) estrndup_rel(zvalue->value.str.val, zvalue->value.str.len);
- break;
- case IS_ARRAY:
- case IS_CONSTANT_ARRAY: {
- zval *tmp;
- HashTable *original_ht = zvalue->value.ht;
- HashTable *tmp_ht = NULL;
- TSRMLS_FETCH();
-
- if (zvalue->value.ht == &EG(symbol_table)) {
- return; /* do nothing */
- }
- ALLOC_HASHTABLE_REL(tmp_ht);
- zend_hash_init(tmp_ht, zend_hash_num_elements(original_ht), NULL, ZVAL_PTR_DTOR, 0);
- zend_hash_copy(tmp_ht, original_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
- zvalue->value.ht = tmp_ht;
- }
- break;
- case IS_OBJECT:
- {
- TSRMLS_FETCH();
- Z_OBJ_HT_P(zvalue)->add_ref(zvalue TSRMLS_CC);
- }
- break;
- }
- }
- #endif
- #pragma managed
-
- // copied from zend_variables.c, slightly modified and beautified
- #ifdef PHP4TS
- ZEND_API void _zval_dtor(zval *zvalue ZEND_FILE_LINE_DC)
- {
- if (zvalue->type == IS_LONG) return;
-
- switch (zvalue->type & ~IS_CONSTANT_INDEX)
- {
- case IS_STRING:
- case IS_CONSTANT: CHECK_ZVAL_STRING_REL(zvalue);
- STR_FREE_REL(zvalue->value.str.val);
- break;
-
- case IS_ARRAY:
- case IS_CONSTANT_ARRAY:
- {
- TSRMLS_FETCH();
- if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table)))
- {
- zend_hash_destroy(zvalue->value.ht);
- FREE_HASHTABLE(zvalue->value.ht);
- }
- }
- break;
-
- case IS_OBJECT: {
- TSRMLS_FETCH();
-
- zend_hash_destroy(Z_OBJPROP_P(zvalue));
- FREE_HASHTABLE(Z_OBJPROP_P(zvalue));
- }
- break;
-
- case IS_RESOURCE: {
- // NEVER DESTROY RESOURCES LIKE THIS - causes many problems
- // destroy resource
- //if (Request::GetCurrentRequest()->DontDestroyResources == false)
- //{
- // TSRMLS_FETCH();
- // _zend_list_delete(zvalue->value.lval, tsrm_ls);
- //}
- }
- break;
-
- case IS_LONG: case IS_DOUBLE:
- case IS_BOOL: case IS_NULL:
- default:
- return;
- }
- }
- #elif defined(PHP5TS)
- ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
- {
- switch (zvalue->type & ~IS_CONSTANT_INDEX) {
- case IS_STRING:
- case IS_CONSTANT:
- CHECK_ZVAL_STRING_REL(zvalue);
- STR_FREE_REL(zvalue->value.str.val);
- break;
- case IS_ARRAY:
- case IS_CONSTANT_ARRAY: {
- TSRMLS_FETCH();
-
- if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
- zend_hash_destroy(zvalue->value.ht);
- FREE_HASHTABLE(zvalue->value.ht);
- }
- }
- break;
- case IS_OBJECT:
- {
- TSRMLS_FETCH();
-
- Z_OBJ_HT_P(zvalue)->del_ref(zvalue TSRMLS_CC);
- }
- break;
- case IS_RESOURCE:
- {
- // NEVER DESTROY RESOURCES LIKE THIS - causes many problems
- // destroy resource
- //if (Request::GetCurrentRequest()->DontDestroyResources == false)
- //{
- //TSRMLS_FETCH();
- ///* destroy resource */
- //zend_list_delete(zvalue->value.lval);
- //}
- }
- break;
- case IS_LONG:
- case IS_DOUBLE:
- case IS_BOOL:
- case IS_NULL:
- default:
- return;
- break;
- }
- }
- #endif
-
- #pragma unmanaged
-
- // copied from zend_variables.c and beautified
- ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
- {
- switch (zvalue->type & ~IS_CONSTANT_INDEX)
- {
- case IS_STRING:
- case IS_CONSTANT:
- CHECK_ZVAL_STRING_REL(zvalue);
- if (zvalue->value.str.val != empty_string) free(zvalue->value.str.val);
- break;
-
- case IS_ARRAY:
- case IS_CONSTANT_ARRAY:
- case IS_OBJECT:
- case IS_RESOURCE:
- zend_error(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
- break;
-
- case IS_LONG:
- case IS_DOUBLE:
- case IS_BOOL:
- case IS_NULL:
- default:
- break;
- }
- }
-
- // copied from zend_execute.h, slightly modified and beautified
- static inline void safe_free_zval_ptr(zval *p)
- {
- TSRMLS_FETCH();
-
- if (p != EG(uninitialized_zval_ptr))
- {
- FREE_ZVAL(p);
- }
- }
-
- // copied from zend_execute_API.c, slightly modified and beautified
- ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC)
- {
- (*zval_ptr)->refcount--;
- if ((*zval_ptr)->refcount == 0)
- {
- zval_dtor(*zval_ptr);
- safe_free_zval_ptr(*zval_ptr);
- }
- else if (((*zval_ptr)->refcount == 1) && ((*zval_ptr)->type != IS_OBJECT))
- {
- (*zval_ptr)->is_ref = 0;
- }
- }
-
- // copied from zend_execute_API.c, slightly modified and beautified
- ZEND_API void _zval_internal_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC)
- {
- (*zval_ptr)->refcount--;
- if ((*zval_ptr)->refcount == 0)
- {
- zval_internal_dtor(*zval_ptr);
- free(*zval_ptr);
- }
- else if ((*zval_ptr)->refcount == 1) (*zval_ptr)->is_ref = 0;
- }
-
- // copied from zend_variables.c
- ZEND_API void zval_add_ref(zval **p)
- {
- (*p)->refcount++;
- }
-
- // copied from zend_operators.c, slightly modified and beautified
- #ifdef PHP4TS
- ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
- {
- switch (op->type)
- {
- case IS_STRING:
- {
- char *strval;
-
- strval = op->value.str.val;
- switch ((op->type = is_numeric_string(strval, op->value.str.len, &op->value.lval, &op->value.dval, 1)))
- {
- case IS_DOUBLE:
- case IS_LONG:
- break;
-
- default:
- op->value.lval = strtol(op->value.str.val, NULL, 10);
- op->type = IS_LONG;
- break;
- }
- STR_FREE(strval);
- break;
- }
-
- case IS_BOOL: op->type = IS_LONG;
- break;
-
- case IS_RESOURCE: _zend_list_delete(op->value.lval, tsrm_ls);
- op->type = IS_LONG;
- break;
-
- case IS_NULL: op->type = IS_LONG;
- op->value.lval = 0;
- break;
- }
- }
-
- // copied from zend_operators.c and beautified
- static void convert_scalar_to_array(zval *op, int type)
- {
- zval *entry;
-
- ALLOC_ZVAL(entry);
- *entry = *op;
- INIT_PZVAL(entry);
-
- switch (type)
- {
- case IS_ARRAY:
- ALLOC_HASHTABLE(op->value.ht);
- zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
- zend_hash_index_update(op->value.ht, 0, (void *) &entry, sizeof(zval *), NULL);
- op->type = IS_ARRAY;
- break;
-
- case IS_OBJECT:
- ALLOC_HASHTABLE(Z_OBJPROP_P(op));
- zend_hash_init(Z_OBJPROP_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
- zend_hash_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar"), (void *)&entry, sizeof(zval *), NULL);
- Z_OBJCE_P(op) = &zend_standard_class_def;
- Z_TYPE_P(op) = IS_OBJECT;
- break;
- }
- }
-
- // copied from zend_operators.c, slightly modified and beautified
- ZEND_API void convert_to_array(zval *op)
- {
- TSRMLS_FETCH();
-
- switch(op->type)
- {
- case IS_ARRAY: return;
-
- /* OBJECTS_OPTIMIZE */
- case IS_OBJECT:
- op->type = IS_ARRAY;
- op->value.ht = Z_OBJPROP_P(op);
- return;
-
- case IS_NULL: ALLOC_HASHTABLE(op->value.ht);
- zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
- op->type = IS_ARRAY;
- break;
-
- default: convert_scalar_to_array(op, IS_ARRAY);
- break;
- }
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void convert_to_boolean(zval *op)
- {
- char *strval;
- int tmp;
-
- switch (op->type)
- {
- case IS_BOOL:
- break;
-
- case IS_NULL:
- op->value.lval = 0;
- break;
-
- case IS_RESOURCE:
- {
- TSRMLS_FETCH();
- zend_list_delete(op->value.lval);
- }
- /* break missing intentionally */
-
- case IS_LONG:
- op->value.lval = (op->value.lval ? 1 : 0);
- break;
-
- case IS_DOUBLE:
- op->value.lval = (op->value.dval ? 1 : 0);
- break;
-
- case IS_STRING:
- 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;
- STR_FREE(strval);
- break;
-
- case IS_ARRAY:
- tmp = (zend_hash_num_elements(op->value.ht) ? 1 : 0);
- zval_dtor(op);
- op->value.lval = tmp;
- break;
-
- case IS_OBJECT:
- tmp = (zend_hash_num_elements(Z_OBJPROP_P(op)) ? 1 : 0);
- zval_dtor(op);
- op->value.lval = tmp;
- break;
-
- default:
- zval_dtor(op);
- op->value.lval = 0;
- break;
- }
- op->type = IS_BOOL;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void convert_to_double(zval *op)
- {
- char *strval;
- double tmp;
-
- switch (op->type)
- {
- case IS_NULL:
- op->value.dval = 0.0;
- break;
-
- case IS_RESOURCE:
- {
- TSRMLS_FETCH();
- zend_list_delete(op->value.lval);
- }
- /* break missing intentionally */
-
- case IS_BOOL:
- case IS_LONG:
- op->value.dval = (double)op->value.lval;
- break;
-
- case IS_DOUBLE:
- break;
-
- case IS_STRING:
- strval = op->value.str.val;
- op->value.dval = strtod(strval, NULL);
- STR_FREE(strval);
- break;
-
- case IS_ARRAY:
- tmp = (zend_hash_num_elements(op->value.ht) ? 1 : 0);
- zval_dtor(op);
- op->value.dval = tmp;
- break;
-
- case IS_OBJECT:
- tmp = (zend_hash_num_elements(Z_OBJPROP_P(op))? 1 : 0);
- zval_dtor(op);
- op->value.dval = tmp;
- break;
-
- default:
- zend_error(E_WARNING, "Cannot convert to real value (type=%d)", op->type);
- zval_dtor(op);
- op->value.dval = 0;
- break;
- }
- op->type = IS_DOUBLE;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void convert_to_long(zval *op)
- {
- convert_to_long_base(op, 10);
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void convert_to_long_base(zval *op, int base)
- {
- char *strval;
- long tmp;
-
- switch (op->type)
- {
- case IS_NULL:
- op->value.lval = 0;
- break;
- case IS_RESOURCE:
- {
- TSRMLS_FETCH();
- zend_list_delete(op->value.lval);
- }
- /* break missing intentionally */
-
- case IS_BOOL:
- case IS_LONG:
- break;
-
- case IS_DOUBLE:
- 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);
- break;
-
- case IS_ARRAY:
- tmp = (zend_hash_num_elements(op->value.ht) ? 1 : 0);
- zval_dtor(op);
- op->value.lval = tmp;
- break;
-
- case IS_OBJECT:
- tmp = (zend_hash_num_elements(Z_OBJPROP_P(op))?1:0);
- zval_dtor(op);
- op->value.lval = tmp;
- break;
-
- default:
- zend_error(E_WARNING, "Cannot convert to ordinal value");
- zval_dtor(op);
- op->value.lval = 0;
- break;
- }
-
- op->type = IS_LONG;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void convert_to_null(zval *op)
- {
- zval_dtor(op);
- op->type = IS_NULL;
- }
-
- // copied from zend_operators.c, slightly modified and beautified
- ZEND_API void convert_to_object(zval *op)
- {
- switch (op->type)
- {
- /* OBJECTS_FIXME */
- case IS_ARRAY:
- Z_TYPE_P(op) = IS_OBJECT;
- Z_OBJPROP_P(op) = op->value.ht;
- Z_OBJCE_P(op) = &zend_standard_class_def;
- return;
-
- case IS_OBJECT:
- return;
-
- /* OBJECTS_FIXME */
- case IS_NULL:
- ALLOC_HASHTABLE(Z_OBJPROP_P(op));
- zend_hash_init(Z_OBJPROP_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
- Z_OBJCE_P(op) = &zend_standard_class_def;
- Z_TYPE_P(op) = IS_OBJECT;
- break;
-
- default:
- convert_scalar_to_array(op, IS_OBJECT);
- break;
- }
- }
-
- // copied from zend_operators.c, slightly modified and beautified
- ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC)
- {
- long lval;
- double dval;
- TSRMLS_FETCH();
-
- switch (op->type)
- {
- case IS_NULL: op->value.str.val = empty_string;
- op->value.str.len = 0;
- break;
-
- case IS_STRING: break;
-
- case IS_BOOL: if (op->value.lval)
- {
- op->value.str.val = estrndup_rel("1", 1);
- op->value.str.len = 1;
- }
- else
- {
- op->value.str.val = empty_string;
- op->value.str.len = 0;
- }
- break;
-
- case IS_RESOURCE:
- {
- long tmp = op->value.lval;
-
- _zend_list_delete(op->value.lval, tsrm_ls);
- op->value.str.val = (char *)emalloc(sizeof("Resource id #") - 1 + MAX_LENGTH_OF_LONG);
- op->value.str.len = sprintf(op->value.str.val, "Resource id #%ld", tmp);
- break;
- }
-
- case IS_LONG: lval = op->value.lval;
- op->value.str.val = (char *) emalloc_rel(MAX_LENGTH_OF_LONG + 1);
- op->value.str.len = zend_sprintf(op->value.str.val, "%ld", lval); /* SAFE */
- break;
-
- case IS_DOUBLE: {
- dval = op->value.dval;
- op->value.str.val = (char *)emalloc_rel(MAX_LENGTH_OF_DOUBLE + EG_precision + 1);
- op->value.str.len = zend_sprintf(op->value.str.val, "%.*G", (int)EG_precision, dval); /* SAFE */
- /* %G already handles removing trailing zeros from the fractional part, yay */
- break;
- }
-
- case IS_ARRAY: zval_dtor(op);
- op->value.str.val = estrndup_rel("Array", sizeof("Array") - 1);
- op->value.str.len = sizeof("Array") - 1;
- zend_error(E_NOTICE, "Array to string conversion");
- break;
-
- case IS_OBJECT: zval_dtor(op);
- op->value.str.val = estrndup_rel("Object", sizeof("Object") - 1);
- op->value.str.len = sizeof("Object") - 1;
- zend_error(E_NOTICE, "Object to string conversion");
- break;
-
- default: zval_dtor(op);
- ZVAL_BOOL(op, 0);
- break;
- }
- op->type = IS_STRING;
- }
- #elif defined(PHP5TS)
-
- #define convert_object_to_type(op, ctype, conv_func) \
- if (Z_OBJ_HT_P(op)->cast_object) { \
- zval dst; \
- if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) { \
- zend_error(E_RECOVERABLE_ERROR, \
- "Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name, \
- zend_get_type_by_const(ctype)); \
- } else { \
- zval_dtor(op); \
- Z_TYPE_P(op) = ctype; \
- op->value = dst.value; \
- } \
- } else { \
- if(Z_OBJ_HT_P(op)->get) { \
- zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC); \
- if(Z_TYPE_P(newop) != IS_OBJECT) { \
- /* for safety - avoid loop */ \
- zval_dtor(op); \
- *op = *newop; \
- FREE_ZVAL(newop); \
- conv_func(op); \
- } \
- } \
- }
-
- /* Argument parsing API -- andrei */
-
- ZEND_API char *zend_get_type_by_const(int type)
- {
- switch(type) {
- case IS_BOOL:
- return "boolean";
- case IS_LONG:
- return "integer";
- case IS_DOUBLE:
- return "double";
- case IS_STRING:
- return "string";
- case IS_OBJECT:
- return "object";
- case IS_RESOURCE:
- return "resource";
- case IS_NULL:
- return "null";
- case IS_ARRAY:
- return "array";
- default:
- return "unknown";
- }
- }
-
- ZEND_API void convert_to_long(zval *op)
- {
- if ((op)->type != IS_LONG) {
- convert_to_long_base(op, 10);
- }
- }
-
- ZEND_API void convert_to_long_base(zval *op, int base)
- {
- char *strval;
- long tmp;
-
- switch (op->type) {
- case IS_NULL:
- op->value.lval = 0;
- break;
- case IS_RESOURCE: {
- TSRMLS_FETCH();
-
- zend_list_delete(op->value.lval);
- }
- /* break missing intentionally */
- case IS_BOOL:
- case IS_LONG:
- break;
- case IS_DOUBLE:
- 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);
- break;
- case IS_ARRAY:
- tmp = (zend_hash_num_elements(op->value.ht)?1:0);
- zval_dtor(op);
- op->value.lval = tmp;
- break;
- case IS_OBJECT:
- {
- int retval = 1;
- TSRMLS_FETCH();
-
- convert_object_to_type(op, IS_LONG, convert_to_long);
-
- if (op->type == IS_LONG) {
- return;
- }
-
- if (EG(ze1_compatibility_mode)) {
- HashTable *ht = Z_OBJPROP_P(op);
- if (ht) {
- retval = (zend_hash_num_elements(ht)?1:0);
- }
- } else {
- zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);
- }
- zval_dtor(op);
- ZVAL_LONG(op, retval);
- return;
- }
- default:
- zend_error(E_WARNING, "Cannot convert to ordinal value");
- zval_dtor(op);
- op->value.lval = 0;
- break;
- }
-
- op->type = IS_LONG;
- }
-
-
- ZEND_API void convert_to_double(zval *op)
- {
- char *strval;
- double tmp;
-
- switch (op->type) {
- case IS_NULL:
- op->value.dval = 0.0;
- break;
- case IS_RESOURCE: {
- TSRMLS_FETCH();
-
- zend_list_delete(op->value.lval);
- }
- /* break missing intentionally */
- case IS_BOOL:
- case IS_LONG:
- op->value.dval = (double) op->value.lval;
- break;
- case IS_DOUBLE:
- break;
- case IS_STRING:
- strval = op->value.str.val;
-
- op->value.dval = zend_strtod(strval, NULL);
- STR_FREE(strval);
- break;
- case IS_ARRAY:
- tmp = (zend_hash_num_elements(op->value.ht)?1:0);
- zval_dtor(op);
- op->value.dval = tmp;
- break;
- case IS_OBJECT:
- {
- double retval = 1.0;
- TSRMLS_FETCH();
-
- convert_object_to_type(op, IS_DOUBLE, convert_to_double);
-
- if (op->type == IS_DOUBLE) {
- return;
- }
-
- if (EG(ze1_compatibility_mode)) {
- HashTable *ht = Z_OBJPROP_P(op);
- if (ht) {
- 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);
- }
-
- zval_dtor(op);
- ZVAL_DOUBLE(op, retval);
- break;
- }
- default:
- zend_error(E_WARNING, "Cannot convert to real value (type=%d)", op->type);
- zval_dtor(op);
- op->value.dval = 0;
- break;
- }
- op->type = IS_DOUBLE;
- }
-
-
- ZEND_API void convert_to_null(zval *op)
- {
- if (Z_TYPE_P(op) == IS_OBJECT) {
- if (Z_OBJ_HT_P(op)->cast_object) {
- zval *org;
- TSRMLS_FETCH();
-
- ALLOC_ZVAL(org);
- *org = *op;
- if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
- zval_dtor(org);
- return;
- }
- *op = *org;
- FREE_ZVAL(org);
- }
- }
-
- zval_dtor(op);
- Z_TYPE_P(op) = IS_NULL;
- }
-
-
- ZEND_API void convert_to_boolean(zval *op)
- {
- char *strval;
- int tmp;
-
- switch (op->type) {
- case IS_BOOL:
- break;
- case IS_NULL:
- op->value.lval = 0;
- break;
- case IS_RESOURCE: {
- TSRMLS_FETCH();
-
- zend_list_delete(op->value.lval);
- }
- /* break missing intentionally */
- case IS_LONG:
- op->value.lval = (op->value.lval ? 1 : 0);
- break;
- case IS_DOUBLE:
- op->value.lval = (op->value.dval ? 1 : 0);
- break;
- case IS_STRING:
- 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;
- }
- STR_FREE(strval);
- break;
- case IS_ARRAY:
- tmp = (zend_hash_num_elements(op->value.ht)?1:0);
- zval_dtor(op);
- op->value.lval = tmp;
- break;
- case IS_OBJECT:
- {
- zend_bool retval = 1;
- TSRMLS_FETCH();
-
- convert_object_to_type(op, IS_BOOL, convert_to_boolean);
-
- if (op->type == IS_BOOL) {
- return;
- }
-
- if (EG(ze1_compatibility_mode)) {
- HashTable *ht = Z_OBJPROP_P(op);
- if (ht) {
- retval = (zend_hash_num_elements(ht)?1:0);
- }
- }
-
- zval_dtor(op);
- ZVAL_BOOL(op, retval);
- break;
- }
- default:
- zval_dtor(op);
- op->value.lval = 0;
- break;
- }
- op->type = IS_BOOL;
- }
-
- ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC)
- {
- long lval;
- double dval;
-
- switch (op->type) {
- case IS_NULL:
- op->value.str.val = STR_EMPTY_ALLOC();
- op->value.str.len = 0;
- break;
- case IS_STRING:
- break;
- case IS_BOOL:
- if (op->value.lval) {
- op->value.str.val = estrndup_rel("1", 1);
- op->value.str.len = 1;
- } else {
- op->value.str.val = STR_EMPTY_ALLOC();
- op->value.str.len = 0;
- }
- break;
- case IS_RESOURCE: {
- long tmp = op->value.lval;
- TSRMLS_FETCH();
-
- zend_list_delete(op->value.lval);
- op->value.str.len = zend_spprintf(&op->value.str.val, 0, "Resource id #%ld", tmp);
- break;
- }
- case IS_LONG:
- lval = op->value.lval;
-
- op->value.str.len = zend_spprintf(&op->value.str.val, 0, "%ld", lval); /* SAFE */
- break;
- case IS_DOUBLE: {
- TSRMLS_FETCH();
- dval = op->value.dval;
- op->value.str.len = zend_spprintf(&op->value.str.val, 0, "%.*G", (int) EG(precision), dval); /* SAFE */
- /* %G already handles removing trailing zeros from the fractional part, yay */
- break;
- }
- case IS_ARRAY:
- zend_error(E_NOTICE, "Array to string conversion");
- zval_dtor(op);
- op->value.str.val = estrndup_rel("Array", sizeof("Array")-1);
- op->value.str.len = sizeof("Array")-1;
- break;
- case IS_OBJECT: {
- TSRMLS_FETCH();
-
- convert_object_to_type(op, IS_STRING, convert_to_string);
-
- if (op->type == IS_STRING) {
- return;
- }
-
- zend_error(E_NOTICE, "Object of class %s 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;
- break;
- }
- default:
- zval_dtor(op);
- ZVAL_BOOL(op, 0);
- break;
- }
- op->type = IS_STRING;
- }
-
-
- static void convert_scalar_to_array(zval *op, int type)
- {
- zval *entry;
-
- ALLOC_ZVAL(entry);
- *entry = *op;
- INIT_PZVAL(entry);
-
- switch (type) {
- case IS_ARRAY:
- ALLOC_HASHTABLE(op->value.ht);
- zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
- zend_hash_index_update(op->value.ht, 0, (void *) &entry, sizeof(zval *), NULL);
- op->type = IS_ARRAY;
- break;
- case IS_OBJECT:
- {
- /* OBJECTS_OPTIMIZE */
- TSRMLS_FETCH();
-
- object_init(op);
- zend_hash_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar"), (void *) &entry, sizeof(zval *), NULL);
- }
- break;
- }
- }
-
-
- ZEND_API void convert_to_array(zval *op)
- {
- TSRMLS_FETCH();
-
- switch (op->type) {
- case IS_ARRAY:
- return;
- break;
- /* OBJECTS_OPTIMIZE */
- case IS_OBJECT:
- {
- zval *tmp;
- HashTable *ht;
-
- ALLOC_HASHTABLE(ht);
- zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
- if (Z_OBJ_HT_P(op)->get_properties) {
- HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
- if(obj_ht) {
- zend_hash_copy(ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
- }
- } else {
- convert_object_to_type(op, IS_ARRAY, convert_to_array);
-
- if (op->type == IS_ARRAY) {
- zend_hash_destroy(ht);
- FREE_HASHTABLE(ht);
- return;
- }
- }
- zval_dtor(op);
- op->type = IS_ARRAY;
- op->value.ht = ht;
- }
- return;
- case IS_NULL:
- ALLOC_HASHTABLE(op->value.ht);
- zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
- op->type = IS_ARRAY;
- break;
- default:
- convert_scalar_to_array(op, IS_ARRAY);
- break;
- }
- }
-
-
- ZEND_API void convert_to_object(zval *op)
- {
- switch (op->type) {
- case IS_ARRAY:
- {
- /* OBJECTS_OPTIMIZE */
- TSRMLS_FETCH();
-
- object_and_properties_init(op, &zend_standard_class_def, op->value.ht);
- return;
- break;
- }
- case IS_OBJECT:
- return;
- case IS_NULL:
- {
- /* OBJECTS_OPTIMIZE */
- TSRMLS_FETCH();
-
- object_init(op);
- break;
- }
- default:
- convert_scalar_to_array(op, IS_OBJECT);
- break;
- }
- }
-
- ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
- {
- switch (op->type) {
- case IS_STRING:
- {
- char *strval;
-
- strval = op->value.str.val;
- if ((op->type=is_numeric_string(strval, op->value.str.len, &op->value.lval, &op->value.dval, 1)) == 0) {
- op->value.lval = 0;
- op->type = IS_LONG;
- }
- STR_FREE(strval);
- break;
- }
- case IS_BOOL:
- op->type = IS_LONG;
- break;
- case IS_RESOURCE:
- zend_list_delete(op->value.lval);
- op->type = IS_LONG;
- break;
- case IS_OBJECT:
- convert_to_long_base(op, 10);
- break;
- case IS_NULL:
- op->type = IS_LONG;
- op->value.lval = 0;
- break;
- }
- }
- #endif
- // copied from zend_strtod.c
- ZEND_API double zend_hex_strtod(const char *str, char **endptr)
- {
- const char *s = str;
- char c;
- int any = 0;
- double value = 0;
-
- if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) {
- s += 2;
- }
-
- while ((c = *s++)) {
- if (c >= '0' && c <= '9') {
- c -= '0';
- } else if (c >= 'A' && c <= 'F') {
- c -= 'A' - 10;
- } else if (c >= 'a' && c <= 'f') {
- c -= 'a' - 10;
- } else {
- break;
- }
-
- any = 1;
- value = value * 16 + c;
- }
-
- if (endptr != NULL) {
- *endptr = (char *)(any ? s - 1 : str);
- }
-
- return value;
- }
-
- ZEND_API double zend_oct_strtod(const char *str, char **endptr)
- {
- const char *s = str;
- char c;
- double value = 0;
- int any = 0;
-
- /* skip leading zero */
- s++;
-
- while ((c = *s++)) {
- if (c < '0' || c > '7') {
- /* break and return the current value if the number is not well-formed
- * that's what Linux strtol() does
- */
- break;
- }
- value = value * 8 + c - '0';
- any = 1;
- }
-
- if (endptr != NULL) {
- *endptr = (char *)(any ? s - 1 : str);
- }
-
- return value;
- }
-
-
- // copied from zend_operators.c and beautified
- ZEND_API long zend_atol(const char *str, int str_len)
- {
- long retval;
-
- if (!str_len) {
- str_len = strlen(str);
- }
- retval = strtol(str, NULL, 0);
- if (str_len>0) {
- switch (str[str_len-1]) {
- case 'g':
- case 'G':
- retval *= 1024;
- /* break intentionally missing */
- case 'm':
- case 'M':
- retval *= 1024;
- /* break intentionally missing */
- case 'k':
- case 'K':
- retval *= 1024;
- break;
- }
- }
- return retval;
- }
- ZEND_API int zend_atoi(const char *str, int str_len)
- {
- int retval;
-
- if (!str_len) str_len = strlen(str);
-
- retval = strtol(str, NULL, 0);
- if (str_len > 0)
- {
- switch (str[str_len-1])
- {
- case 'k':
- case 'K': retval *= 1024;
- break;
- case 'm':
- case 'M': retval *= 1048576;
- break;
- }
- }
- return retval;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void zend_str_tolower(char *str, unsigned int length)
- {
- register char *p = str, *end = p + length;
-
- while (p < end)
- {
- if (*p >= 'A' && *p <= 'Z') *p = (*p)+32;
- p++;
- }
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
- {
- register unsigned char *str = (unsigned char *)source;
- register unsigned char *result = (unsigned char *)dest;
- register unsigned char *end = str + length;
-
- while (str < end) *result++ = tolower((int)*str++);
- *result = *end;
-
- return dest;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int zend_binary_strcmp(char *s1, uint len1, char *s2, uint len2)
- {
- int retval;
-
- retval = memcmp(s1, s2, MIN(len1, len2));
- if (!retval) return (len1 - len2);
- else return retval;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int zend_binary_strncmp(char *s1, uint len1, char *s2, uint len2, uint length)
- {
- int retval;
-
- retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
- if (!retval) return (MIN(length, len1) - MIN(length, len2));
- else return retval;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int zend_binary_strcasecmp(char *s1, uint len1, char *s2, uint len2)
- {
- int len;
- int c1, c2;
-
- len = MIN(len1, len2);
-
- while (len--)
- {
- c1 = tolower(*s1++);
- c2 = tolower(*s2++);
- if (c1 != c2) return c1 - c2;
- }
- return len1 - len2;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int zend_binary_strncasecmp(char *s1, uint len1, char *s2, uint len2, uint length)
- {
- int len;
- int c1, c2;
-
- len = MIN(length, MIN(len1, len2));
-
- while (len--)
- {
- c1 = tolower(*s1++);
- c2 = tolower(*s2++);
- if (c1 != c2) return c1 - c2;
- }
- return MIN(length, len1) - MIN(length, len2);
- }
-
- // copied from zend_operators.c and beautified
- 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);
- }
-
- // copied from zend_operators.c and beautified
- 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);
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2)
- {
- return zend_binary_strcasecmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len);
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3)
- {
- return zend_binary_strncasecmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len, s3->value.lval);
- }
-
- // copied from zend_operators.c, slightly modified and beautified
- ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2)
- {
- int ret1, ret2;
- long lval1, lval2;
- double dval1, dval2;
-
- 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)
- {
- if (ret1 != IS_DOUBLE) dval1 = strtod(s1->value.str.val, NULL);
- else if (ret2 != IS_DOUBLE) dval2 = strtod(s2->value.str.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_binary_zval_strcmp(s1, s2);
- result->value.lval = ZEND_NORMALIZE_BOOL(result->value.lval);
- result->type = IS_LONG;
- }
- return;
- }
-
- // copied from zend_operators.c, slightly modified and beautified
- int hash_zval_compare_function(const zval **z1, const zval **z2 TSRMLS_DC)
- {
- zval result;
-
- if (compare_function(&result, (zval *)*z1, (zval *)*z2 TSRMLS_CC) == FAILURE) return 1;
- return result.value.lval;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC)
- {
- result->type = IS_LONG;
- result->value.lval = zend_hash_compare(ht1, ht2, (compare_func_t)hash_zval_compare_function, 0 TSRMLS_CC);
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC)
- {
- zend_compare_symbol_tables(result, a1->value.ht, a2->value.ht TSRMLS_CC);
- }
-
- // copied from zend_operators.c
- ZEND_API int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC)
- {
- return zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC)
- {
- /* OBJECTS_FIXME */
- if (Z_OBJCE_P(o1) != Z_OBJCE_P(o2))
- {
- result->value.lval = 1; /* Comparing objects of different types is pretty much meaningless */
- result->type = IS_LONG;
- return;
- }
- zend_compare_symbol_tables(result, Z_OBJPROP_P(o1), Z_OBJPROP_P(o2) TSRMLS_CC);
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
- {
- zval op1_copy, op2_copy;
- int use_copy1, use_copy2;
-
- zend_make_printable_zval(op1, &op1_copy, &use_copy1);
- zend_make_printable_zval(op2, &op2_copy, &use_copy2);
-
- if (use_copy1) op1 = &op1_copy;
- if (use_copy2) op2 = &op2_copy;
-
- result->value.lval = zend_binary_zval_strcmp(op1, op2);
- result->type = IS_LONG;
-
- if (use_copy1) zval_dtor(op1);
- if (use_copy2) zval_dtor(op2);
-
- return SUCCESS;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
- {
- zval op1_copy, op2_copy;
- int use_copy1, use_copy2;
-
- zend_make_printable_zval(op1, &op1_copy, &use_copy1);
- zend_make_printable_zval(op2, &op2_copy, &use_copy2);
-
- if (use_copy1) op1 = &op1_copy;
- if (use_copy2) op2 = &op2_copy;
-
- result->value.lval = strcoll(op1->value.str.val, op2->value.str.val);
- result->type = IS_LONG;
-
- if (use_copy1) zval_dtor(op1);
- if (use_copy2) zval_dtor(op2);
-
- return SUCCESS;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
- {
- zval op1_copy, op2_copy;
-
- op1_copy = *op1;
- zval_copy_ctor(&op1_copy);
-
- op2_copy = *op2;
- zval_copy_ctor(&op2_copy);
-
- convert_to_double(&op1_copy);
- convert_to_double(&op2_copy);
-
- result->value.lval = ZEND_NORMALIZE_BOOL(op1_copy.value.dval - op2_copy.value.dval);
- result->type = IS_LONG;
-
- return SUCCESS;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
- {
- zval op1_copy, op2_copy;
-
- if ((op1->type == IS_NULL && op2->type == IS_STRING) ||
- (op2->type == IS_NULL && op1->type == IS_STRING))
- {
- if (op1->type == IS_NULL)
- {
- result->type = IS_LONG;
- result->value.lval = zend_binary_strcmp("", 0, op2->value.str.val, op2->value.str.len);
- return SUCCESS;
- }
- else
- {
- result->type = IS_LONG;
- result->value.lval = zend_binary_strcmp(op1->value.str.val, op1->value.str.len, "", 0);
- return SUCCESS;
- }
- }
-
- if (op1->type == IS_STRING && op2->type == IS_STRING)
- {
- zendi_smart_strcmp(result, op1, op2);
- return SUCCESS;
- }
-
- if (op1->type == IS_BOOL || op2->type == IS_BOOL ||
- op1->type == IS_NULL || op2->type == IS_NULL)
- {
- zendi_convert_to_boolean(op1, op1_copy, result);
- zendi_convert_to_boolean(op2, op2_copy, result);
- result->type = IS_LONG;
- result->value.lval = ZEND_NORMALIZE_BOOL(op1->value.lval - op2->value.lval);
- return SUCCESS;
- }
-
- zendi_convert_scalar_to_number(op1, op1_copy, result);
- zendi_convert_scalar_to_number(op2, op2_copy, result);
-
- if (op1->type == IS_LONG && op2->type == IS_LONG) {
- result->type = IS_LONG;
- result->value.lval = op1->value.lval > op2->value.lval ? 1 : (op1->value.lval < op2->value.lval ? -1 : 0);
- return SUCCESS;
- }
- if ((op1->type == IS_DOUBLE || op1->type == IS_LONG) &&
- (op2->type == IS_DOUBLE || op2->type == IS_LONG))
- {
- result->value.dval = (op1->type == IS_LONG ? (double) op1->value.lval : op1->value.dval) -
- (op2->type == IS_LONG ? (double) op2->value.lval : op2->value.dval);
- result->value.lval = ZEND_NORMALIZE_BOOL(result->value.dval);
- result->type = IS_LONG;
- return SUCCESS;
- }
- if (op1->type == IS_ARRAY && op2->type == IS_ARRAY)
- {
- zend_compare_arrays(result, op1, op2 TSRMLS_CC);
- return SUCCESS;
- }
-
- if (op1->type == IS_OBJECT && op2->type == IS_OBJECT)
- {
- zend_compare_objects(result, op1, op2 TSRMLS_CC);
- return SUCCESS;
- }
-
- if (op1->type == IS_ARRAY)
- {
- result->value.lval = 1;
- result->type = IS_LONG;
- return SUCCESS;
- }
- if (op2->type == IS_ARRAY)
- {
- result->value.lval = -1;
- result->type = IS_LONG;
- return SUCCESS;
- }
- if (op1->type == IS_OBJECT)
- {
- result->value.lval = 1;
- result->type = IS_LONG;
- return SUCCESS;
- }
- if (op2->type == IS_OBJECT)
- {
- result->value.lval = -1;
- result->type = IS_LONG;
- return SUCCESS;
- }
-
- ZVAL_BOOL(result, 0);
- return FAILURE;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy)
- {
- if (expr->type == IS_STRING)
- {
- *use_copy = 0;
- return;
- }
- switch (expr->type)
- {
- case IS_NULL:
- expr_copy->value.str.len = 0;
- expr_copy->value.str.val = empty_string;
- break;
-
- case IS_BOOL:
- if (expr->value.lval)
- {
- expr_copy->value.str.len = 1;
- expr_copy->value.str.val = estrndup("1", 1);
- }
- else
- {
- expr_copy->value.str.len = 0;
- expr_copy->value.str.val = empty_string;
- }
- break;
-
- case IS_RESOURCE:
- expr_copy->value.str.val = (char *)emalloc(sizeof("Resource id #") -1 + MAX_LENGTH_OF_LONG);
- expr_copy->value.str.len = sprintf(expr_copy->value.str.val, "Resource id #%ld", expr->value.lval);
- break;
-
- case IS_ARRAY:
- expr_copy->value.str.len = sizeof("Array") - 1;
- expr_copy->value.str.val = estrndup("Array", expr_copy->value.str.len);
- break;
-
- case IS_OBJECT:
- expr_copy->value.str.len = sizeof("Object") - 1;
- expr_copy->value.str.val = estrndup("Object", expr_copy->value.str.len);
- break;
-
- case IS_DOUBLE:
- *expr_copy = *expr;
- zval_copy_ctor(expr_copy);
- zend_locale_sprintf_double(expr_copy ZEND_FILE_LINE_CC);
- break;
-
- default:
- *expr_copy = *expr;
- zval_copy_ctor(expr_copy);
- convert_to_string(expr_copy);
- break;
- }
- expr_copy->type = IS_STRING;
- *use_copy = 1;
- }
-
- // copied from zend_operators.c and beautified
- #ifdef PHP4TS
- ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC)
- {
- double dval = op->value.dval;
-
- TSRMLS_FETCH();
-
- op->value.str.val = (char *)emalloc_rel(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1);
- sprintf(op->value.str.val, "%.*G", (int)EG(precision), dval);
- op->value.str.len = strlen(op->value.str.val);
-
- if (EG(float_separator)[0] != '.')
- {
- char *p = op->value.str.val;
- if ((p = strchr(p, '.'))) *p = EG(float_separator)[0];
- }
- }
- #elif defined(PHP5TS)
- ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC)
- {
- TSRMLS_FETCH();
-
- op->value.str.len = zend_spprintf(&op->value.str.val, 0, "%.*G", (int) EG(precision), (double)op->value.dval);
- }
- #endif
-
- // copied from strlcpy.c and slightly modified
- /*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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.
- */
-
- /*
- * Copy src to string dst of size siz. At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
- ZEND_API size_t php_strlcpy(char *dst, const char *src, size_t siz)
- {
- register char *d = dst;
- register const char *s = src;
- register size_t n = siz;
-
- /* Copy as many bytes as will fit */
- if (n != 0 && --n != 0) {
- do {
- if ((*d++ = *s++) == 0)
- break;
- } while (--n != 0);
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src */
- if (n == 0) {
- if (siz != 0)
- *d = '\0'; /* NUL-terminate dst */
- while (*s++)
- ;
- }
-
- return(s - src - 1); /* count does not include NUL */
- }
-
- // copied from zend_operators.c and beautified
- 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)
- {
- zval *longer, *shorter;
- char *result_str;
- int i, result_len;
-
- if (op1->value.str.len >= op2->value.str.len)
- {
- longer = op1;
- shorter = op2;
- }
- else
- {
- longer = op2;
- shorter = op1;
- }
-
- result->type = IS_STRING;
- 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++)
- {
- result_str[i] &= longer->value.str.val[i];
- }
- if (result == op1)
- {
- STR_FREE(result->value.str.val);
- }
- result->value.str.val = result_str;
- result->value.str.len = result_len;
- return SUCCESS;
- }
-
- zendi_convert_to_long(op1, op1_copy, result);
- zendi_convert_to_long(op2, op2_copy, result);
-
- result->type = IS_LONG;
- result->value.lval = op1->value.lval & op2->value.lval;
- return SUCCESS;
- }
-
- // copied from zend_operators.c and beautified
- ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC)
- {
- zval op1_copy = *op1;
-
- op1 = &op1_copy;
-
- if (op1->type == IS_DOUBLE)
- {
- op1->value.lval = (long)op1->value.dval;
- op1->type = IS_LONG;
- }
- if (op1->type == IS_LONG)
- {
- result->value.lval = ~op1->value.lval;
- result->type = IS_LONG;
- return SUCCESS;
- }
- if (op1->type == IS_STRING)
- {
- int i;
-
- result->type = IS_STRING;
- 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++)
- {
- result->value.str.val[i] = ~op1->value.str.val[i];
- }
- return SUCCESS;
- }
- zend_error(E_ERROR, "Unsupported operand types");
- return FAILURE; /* unknown datatype */
- }
-
- // copied from zend_operators.c and beautified
- 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)
- {
- zval *longer, *shorter;
- char *result_str;
- int i, result_len;
-
- if (op1->value.str.len >= op2->value.str.len)
- {
- longer = op1;
- shorter = op2;
- }…
Large files files are truncated, but you can click here to view the full file