diff options
-rw-r--r-- | Zend/zend_hash.c | 4 | ||||
-rw-r--r-- | Zend/zend_hash.h | 5 | ||||
-rw-r--r-- | ext/json/JSON_parser.c | 166 | ||||
-rw-r--r-- | ext/json/JSON_parser.h | 4 | ||||
-rw-r--r-- | ext/json/json.c | 211 | ||||
-rw-r--r-- | ext/json/tests/unsupported_type_error.phpt | 2 | ||||
-rw-r--r-- | sapi/fpm/fpm/fastcgi.c | 95 | ||||
-rw-r--r-- | sapi/fpm/fpm/fastcgi.h | 2 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_main.c | 73 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_php.c | 39 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_php.h | 2 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_status.c | 22 |
12 files changed, 285 insertions, 340 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index bc882dd8db..3ffdf6ef76 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -66,12 +66,12 @@ static void _zend_is_inconsistent(const HashTable *ht, const char *file, int lin if ((ht)->u.flags >= (3 << 8)) { \ zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");\ } \ - (ht)->u.flags += (1 << 8); \ + ZEND_HASH_INC_APPLY_COUNT(ht); \ } #define HASH_UNPROTECT_RECURSION(ht) \ if ((ht)->u.flags & HASH_FLAG_APPLY_PROTECTION) { \ - (ht)->u.flags -= (1 << 8); \ + ZEND_HASH_DEC_APPLY_COUNT(ht); \ } #define ZEND_HASH_IF_FULL_DO_RESIZE(ht) \ diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 3db7abdf11..56c7b9ade2 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -640,6 +640,11 @@ static inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPositio _key = _p->key; \ _val = _z; +#define ZEND_HASH_APPLY_SHIFT 8 +#define ZEND_HASH_GET_APPLY_COUNT(ht) (ht->u.flags >> ZEND_HASH_APPLY_SHIFT) +#define ZEND_HASH_INC_APPLY_COUNT(ht) (ht->u.flags += (1 << ZEND_HASH_APPLY_SHIFT)) +#define ZEND_HASH_DEC_APPLY_COUNT(ht) (ht->u.flags -= (1 << ZEND_HASH_APPLY_SHIFT)) + #endif /* ZEND_HASH_H */ /* diff --git a/ext/json/JSON_parser.c b/ext/json/JSON_parser.c index dd832a7cbd..3b943fd336 100644 --- a/ext/json/JSON_parser.c +++ b/ext/json/JSON_parser.c @@ -248,7 +248,7 @@ new_JSON_parser(int depth) jp->error_code = PHP_JSON_ERROR_NONE; jp->stack = (int*)ecalloc(depth, sizeof(int)); if (depth > JSON_PARSER_DEFAULT_DEPTH) { - jp->the_zstack = (zval **)safe_emalloc(depth, sizeof(zval), 0); + jp->the_zstack = (zval *) safe_emalloc(depth, sizeof(zval), 0); } else { jp->the_zstack = &jp->the_static_zstack[0]; } @@ -291,23 +291,21 @@ static int dehexchar(char c) } -static void json_create_zval(zval **z, smart_str *buf, int type, int options) +static void json_create_zval(zval *z, smart_str *buf, int type, int options) { - ALLOC_INIT_ZVAL(*z); - if (type == IS_LONG) { zend_bool bigint = 0; - if (buf->c[0] == '-') { - buf->len--; + if (buf->s->val[0] == '-') { + buf->s->len--; } - if (buf->len >= MAX_LENGTH_OF_LONG - 1) { - if (buf->len == MAX_LENGTH_OF_LONG - 1) { - int cmp = strcmp(buf->c + (buf->c[0] == '-'), long_min_digits); + if (buf->s->len >= MAX_LENGTH_OF_LONG - 1) { + if (buf->s->len == MAX_LENGTH_OF_LONG - 1) { + int cmp = strcmp(buf->s->val + (buf->s->val[0] == '-'), long_min_digits); - if (!(cmp < 0 || (cmp == 0 && buf->c[0] == '-'))) { + if (!(cmp < 0 || (cmp == 0 && buf->s->val[0] == '-'))) { bigint = 1; } } else { @@ -318,9 +316,9 @@ static void json_create_zval(zval **z, smart_str *buf, int type, int options) if (bigint) { /* value too large to represent as a long */ if (options & PHP_JSON_BIGINT_AS_STRING) { - if (buf->c[0] == '-') { + if (buf->s->val[0] == '-') { /* Restore last char consumed above */ - buf->len++; + buf->s->len++; } goto use_string; } else { @@ -328,25 +326,31 @@ static void json_create_zval(zval **z, smart_str *buf, int type, int options) } } - ZVAL_LONG(*z, strtol(buf->c, NULL, 10)); + ZVAL_LONG(z, strtol(buf->s->val, NULL, 10)); } else if (type == IS_DOUBLE) { use_double: - ZVAL_DOUBLE(*z, zend_strtod(buf->c, NULL)); + ZVAL_DOUBLE(z, zend_strtod(buf->s->val, NULL)); } else if (type == IS_STRING) { use_string: - ZVAL_STRINGL(*z, buf->c, buf->len, 1); + if (buf->s) { + ZVAL_STRINGL(z, buf->s->val, buf->s->len); + } else { + ZVAL_EMPTY_STRING(z); + } } - else if (type == IS_BOOL) - { - ZVAL_BOOL(*z, (*(buf->c) == 't')); + else if (type == IS_FALSE) { + ZVAL_FALSE(z); + } + else if (type == IS_TRUE) { + ZVAL_TRUE(z); } else /* type == IS_NULL) || type unknown */ { - ZVAL_NULL(*z); + ZVAL_NULL(z); } } @@ -363,18 +367,18 @@ static void utf16_to_utf8(smart_str *buf, unsigned short utf16) smart_str_appendc(buf, 0x80 | (utf16 & 0x3f)); } else if ((utf16 & 0xfc00) == 0xdc00 - && buf->len >= 3 - && ((unsigned char) buf->c[buf->len - 3]) == 0xed - && ((unsigned char) buf->c[buf->len - 2] & 0xf0) == 0xa0 - && ((unsigned char) buf->c[buf->len - 1] & 0xc0) == 0x80) + && buf->s->len >= 3 + && ((unsigned char) buf->s->val[buf->s->len - 3]) == 0xed + && ((unsigned char) buf->s->val[buf->s->len - 2] & 0xf0) == 0xa0 + && ((unsigned char) buf->s->val[buf->s->len - 1] & 0xc0) == 0x80) { /* found surrogate pair */ unsigned long utf32; - utf32 = (((buf->c[buf->len - 2] & 0xf) << 16) - | ((buf->c[buf->len - 1] & 0x3f) << 10) + utf32 = (((buf->s->val[buf->s->len - 2] & 0xf) << 16) + | ((buf->s->val[buf->s->len - 1] & 0x3f) << 10) | (utf16 & 0x3ff)) + 0x10000; - buf->len -= 3; + buf->s->len -= 3; smart_str_appendc(buf, (unsigned char) (0xf0 | (utf32 >> 18))); smart_str_appendc(buf, 0x80 | ((utf32 >> 12) & 0x3f)); @@ -389,10 +393,24 @@ static void utf16_to_utf8(smart_str *buf, unsigned short utf16) } } +static inline void add_assoc_or_property(int assoc, zval *target, smart_str *key, zval *zv TSRMLS_DC) +{ + zend_bool empty_key = !key->s || key->s->len == 0; + if (!assoc) { + add_property_zval_ex(target, empty_key ? "_empty_" : key->s->val, empty_key ? sizeof("_empty_")-1 : key->s->len, zv TSRMLS_CC); + if (Z_REFCOUNTED_P(zv)) Z_DELREF_P(zv); + } else { + add_assoc_zval_ex(target, empty_key ? "" : key->s->val, empty_key ? 0 : key->s->len, zv); + } + if (key->s) { + key->s->len = 0; + } +} + static void attach_zval(JSON_parser jp, int up, int cur, smart_str *key, int assoc TSRMLS_DC) { - zval *root = jp->the_zstack[up]; - zval *child = jp->the_zstack[cur]; + zval *root = &jp->the_zstack[up]; + zval *child = &jp->the_zstack[cur]; int up_mode = jp->stack[up]; if (up_mode == MODE_ARRAY) @@ -401,30 +419,20 @@ static void attach_zval(JSON_parser jp, int up, int cur, smart_str *key, int ass } else if (up_mode == MODE_OBJECT) { - if (!assoc) - { - add_property_zval_ex(root, (key->len ? key->c : "_empty_"), (key->len ? (key->len + 1) : sizeof("_empty_")), child TSRMLS_CC); - Z_DELREF_P(child); - } - else - { - add_assoc_zval_ex(root, (key->len ? key->c : ""), (key->len ? (key->len + 1) : sizeof("")), child); - } - key->len = 0; + add_assoc_or_property(assoc, root, key, child TSRMLS_CC); } } #define FREE_BUFFERS() smart_str_free(&buf); smart_str_free(&key); #define SWAP_BUFFERS(from, to) do { \ - char *t1 = from.c; \ + zend_string *t1 = from.s; \ int t2 = from.a; \ - from.c = to.c; \ + from.s = to.s; \ from.a = to.a; \ - to.c = t1; \ + to.s = t1; \ to.a = t2; \ - to.len = from.len; \ - from.len = 0; \ + if (from.s) { from.s->len = 0; } \ } while(0); #define JSON_RESET_TYPE() type = -1; @@ -519,8 +527,10 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, smart_str_appendc(&buf, next_char); } else if (type < IS_STRING && next_class == C_QUOTE) { type = IS_STRING; - } else if (type < IS_BOOL && ((jp->state == T3 && next_state == OK) || (jp->state == F4 && next_state == OK))) { - type = IS_BOOL; + } else if (type < IS_FALSE && (jp->state == F4 && next_state == OK)) { + type = IS_FALSE; + } else if (type < IS_TRUE && (jp->state == T3 && next_state == OK)) { + type = IS_TRUE; } else if (type < IS_NULL && jp->state == N3 && next_state == OK) { type = IS_NULL; } else if (type != IS_STRING && next_class > C_WHITE) { @@ -544,19 +554,14 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, case -8: if (type != -1 && jp->stack[jp->top] == MODE_OBJECT) { - zval *mval; + zval mval; smart_str_0(&buf); json_create_zval(&mval, &buf, type, options); - if (!assoc) { - add_property_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC); - Z_DELREF_P(mval); - } else { - add_assoc_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval); - } - key.len = 0; - buf.len = 0; + add_assoc_or_property(assoc, &jp->the_zstack[jp->top], &key, &mval TSRMLS_CC); + + if (buf.s) { buf.s->len = 0; } JSON_RESET_TYPE(); } @@ -572,12 +577,12 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, { if (type != -1 && jp->stack[jp->top] == MODE_ARRAY) { - zval *mval; + zval mval; smart_str_0(&buf); json_create_zval(&mval, &buf, type, options); - add_next_index_zval(jp->the_zstack[jp->top], mval); - buf.len = 0; + add_next_index_zval(&jp->the_zstack[jp->top], &mval); + buf.s->len = 0; JSON_RESET_TYPE(); } @@ -597,13 +602,7 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, jp->state = OB; if (jp->top > 0) { - zval *obj; - - if (jp->top == 1) { - obj = z; - } else { - ALLOC_INIT_ZVAL(obj); - } + zval *obj = &jp->the_zstack[jp->top]; if (!assoc) { object_init(obj); @@ -611,7 +610,9 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, array_init(obj); } - jp->the_zstack[jp->top] = obj; + if (jp->top == 1) { + ZVAL_COPY_VALUE(z, obj); + } if (jp->top > 1) { attach_zval(jp, jp->top - 1, jp->top, &key, assoc TSRMLS_CC); @@ -630,16 +631,13 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, jp->state = AR; if (jp->top > 0) { - zval *arr; - - if (jp->top == 1) { - arr = z; - } else { - ALLOC_INIT_ZVAL(arr); - } + zval *arr = &jp->the_zstack[jp->top]; array_init(arr); - jp->the_zstack[jp->top] = arr; + + if (jp->top == 1) { + ZVAL_COPY_VALUE(z, arr); + } if (jp->top > 1) { attach_zval(jp, jp->top - 1, jp->top, &key, assoc TSRMLS_CC); @@ -665,8 +663,12 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, break; case MODE_DONE: if (type == IS_STRING) { - smart_str_0(&buf); - ZVAL_STRINGL(z, buf.c, buf.len, 1); + if (buf.s) { + smart_str_0(&buf); + ZVAL_STRINGL(z, buf.s->val, buf.s->len); + } else { + ZVAL_EMPTY_STRING(z); + } jp->state = OK; break; } @@ -680,7 +682,7 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, /* , */ case -3: { - zval *mval; + zval mval; if (type != -1 && (jp->stack[jp->top] == MODE_OBJECT || @@ -694,20 +696,14 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, case MODE_OBJECT: if (pop(jp, MODE_OBJECT) && push(jp, MODE_KEY)) { if (type != -1) { - if (!assoc) { - add_property_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : "_empty_"), (key.len ? (key.len + 1) : sizeof("_empty_")), mval TSRMLS_CC); - Z_DELREF_P(mval); - } else { - add_assoc_zval_ex(jp->the_zstack[jp->top], (key.len ? key.c : ""), (key.len ? (key.len + 1) : sizeof("")), mval); - } - key.len = 0; + add_assoc_or_property(assoc, &jp->the_zstack[jp->top], &key, &mval TSRMLS_CC); } jp->state = KE; } break; case MODE_ARRAY: if (type != -1) { - add_next_index_zval(jp->the_zstack[jp->top], mval); + add_next_index_zval(&jp->the_zstack[jp->top], &mval); } jp->state = VA; break; @@ -716,7 +712,7 @@ parse_JSON_ex(JSON_parser jp, zval *z, unsigned short utf16_json[], int length, jp->error_code = PHP_JSON_ERROR_SYNTAX; return false; } - buf.len = 0; + buf.s->len = 0; JSON_RESET_TYPE(); } break; diff --git a/ext/json/JSON_parser.h b/ext/json/JSON_parser.h index 8671765b4d..3df999c5f3 100644 --- a/ext/json/JSON_parser.h +++ b/ext/json/JSON_parser.h @@ -15,8 +15,8 @@ typedef struct JSON_parser_struct { int top; int error_code; int* stack; - zval **the_zstack; - zval *the_static_zstack[JSON_PARSER_DEFAULT_DEPTH]; + zval *the_zstack; + zval the_static_zstack[JSON_PARSER_DEFAULT_DEPTH]; } * JSON_parser; enum error_codes { diff --git a/ext/json/json.c b/ext/json/json.c index 71f8cc2d69..528764e17c 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -169,27 +169,19 @@ static PHP_MINFO_FUNCTION(json) static void json_escape_string(smart_str *buf, char *s, int len, int options TSRMLS_DC); -static int json_determine_array_type(zval **val TSRMLS_DC) /* {{{ */ +static int json_determine_array_type(zval *val TSRMLS_DC) /* {{{ */ { int i; - HashTable *myht = HASH_OF(*val); + HashTable *myht = HASH_OF(val); i = myht ? zend_hash_num_elements(myht) : 0; if (i > 0) { - char *key; + zend_string *key; ulong index, idx; - uint key_len; - HashPosition pos; - zend_hash_internal_pointer_reset_ex(myht, &pos); idx = 0; - for (;; zend_hash_move_forward_ex(myht, &pos)) { - i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos); - if (i == HASH_KEY_NON_EXISTENT) { - break; - } - - if (i == HASH_KEY_IS_STRING) { + ZEND_HASH_FOREACH_KEY(myht, index, key) { + if (key) { return PHP_JSON_OUTPUT_OBJECT; } else { if (index != idx) { @@ -197,7 +189,7 @@ static int json_determine_array_type(zval **val TSRMLS_DC) /* {{{ */ } } idx++; - } + } ZEND_HASH_FOREACH_END(); } return PHP_JSON_OUTPUT_ARRAY; @@ -228,20 +220,20 @@ static inline void json_pretty_print_indent(smart_str *buf, int options TSRMLS_D /* }}} */ -static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) /* {{{ */ +static void json_encode_array(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */ { int i, r, need_comma = 0; HashTable *myht; - if (Z_TYPE_PP(val) == IS_ARRAY) { - myht = HASH_OF(*val); + if (Z_TYPE_P(val) == IS_ARRAY) { + myht = HASH_OF(val); r = (options & PHP_JSON_FORCE_OBJECT) ? PHP_JSON_OUTPUT_OBJECT : json_determine_array_type(val TSRMLS_CC); } else { - myht = Z_OBJPROP_PP(val); + myht = Z_OBJPROP_P(val); r = PHP_JSON_OUTPUT_OBJECT; } - if (myht && myht->nApplyCount > 1) { + if (myht && ZEND_HASH_GET_APPLY_COUNT(myht) > 1) { JSON_G(error_code) = PHP_JSON_ERROR_RECURSION; smart_str_appendl(buf, "null", 4); return; @@ -257,28 +249,39 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) i = myht ? zend_hash_num_elements(myht) : 0; - if (i > 0) - { - char *key; - zval **data; + if (i > 0) { + zend_string *key; + zval *data; ulong index; - uint key_len; - HashPosition pos; HashTable *tmp_ht; - zend_hash_internal_pointer_reset_ex(myht, &pos); - for (;; zend_hash_move_forward_ex(myht, &pos)) { - i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos); - if (i == HASH_KEY_NON_EXISTENT) - break; + ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) { + ZVAL_DEREF(data); + tmp_ht = HASH_OF(data); + if (tmp_ht) { + ZEND_HASH_INC_APPLY_COUNT(tmp_ht); + } - if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) == SUCCESS) { - tmp_ht = HASH_OF(*data); - if (tmp_ht) { - tmp_ht->nApplyCount++; + if (r == PHP_JSON_OUTPUT_ARRAY) { + if (need_comma) { + smart_str_appendc(buf, ','); + } else { + need_comma = 1; } - if (r == PHP_JSON_OUTPUT_ARRAY) { + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); + json_pretty_print_indent(buf, options TSRMLS_CC); + php_json_encode(buf, data, options TSRMLS_CC); + } else if (r == PHP_JSON_OUTPUT_OBJECT) { + if (key) { + if (key->val[0] == '\0' && Z_TYPE_P(val) == IS_OBJECT) { + /* Skip protected and private members. */ + if (tmp_ht) { + ZEND_HASH_DEC_APPLY_COUNT(tmp_ht); + } + continue; + } + if (need_comma) { smart_str_appendc(buf, ','); } else { @@ -287,58 +290,38 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) json_pretty_print_char(buf, options, '\n' TSRMLS_CC); json_pretty_print_indent(buf, options TSRMLS_CC); - php_json_encode(buf, *data, options TSRMLS_CC); - } else if (r == PHP_JSON_OUTPUT_OBJECT) { - if (i == HASH_KEY_IS_STRING) { - if (key[0] == '\0' && Z_TYPE_PP(val) == IS_OBJECT) { - /* Skip protected and private members. */ - if (tmp_ht) { - tmp_ht->nApplyCount--; - } - continue; - } - - if (need_comma) { - smart_str_appendc(buf, ','); - } else { - need_comma = 1; - } - json_pretty_print_char(buf, options, '\n' TSRMLS_CC); - json_pretty_print_indent(buf, options TSRMLS_CC); + json_escape_string(buf, key->val, key->len, options & ~PHP_JSON_NUMERIC_CHECK TSRMLS_CC); + smart_str_appendc(buf, ':'); - json_escape_string(buf, key, key_len - 1, options & ~PHP_JSON_NUMERIC_CHECK TSRMLS_CC); - smart_str_appendc(buf, ':'); + json_pretty_print_char(buf, options, ' ' TSRMLS_CC); - json_pretty_print_char(buf, options, ' ' TSRMLS_CC); - - php_json_encode(buf, *data, options TSRMLS_CC); + php_json_encode(buf, data, options TSRMLS_CC); + } else { + if (need_comma) { + smart_str_appendc(buf, ','); } else { - if (need_comma) { - smart_str_appendc(buf, ','); - } else { - need_comma = 1; - } + need_comma = 1; + } - json_pretty_print_char(buf, options, '\n' TSRMLS_CC); - json_pretty_print_indent(buf, options TSRMLS_CC); + json_pretty_print_char(buf, options, '\n' TSRMLS_CC); + json_pretty_print_indent(buf, options TSRMLS_CC); - smart_str_appendc(buf, '"'); - smart_str_append_long(buf, (long) index); - smart_str_appendc(buf, '"'); - smart_str_appendc(buf, ':'); + smart_str_appendc(buf, '"'); + smart_str_append_long(buf, (long) index); + smart_str_appendc(buf, '"'); + smart_str_appendc(buf, ':'); - json_pretty_print_char(buf, options, ' ' TSRMLS_CC); + json_pretty_print_char(buf, options, ' ' TSRMLS_CC); - php_json_encode(buf, *data, options TSRMLS_CC); - } + php_json_encode(buf, data, options TSRMLS_CC); } + } - if (tmp_ht) { - tmp_ht->nApplyCount--; - } + if (tmp_ht) { + ZEND_HASH_DEC_APPLY_COUNT(tmp_ht); } - } + } ZEND_HASH_FOREACH_END(); } if (JSON_G(encoder_depth) > JSON_G(encode_max_depth)) { @@ -559,7 +542,7 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR static void json_encode_serializable_object(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */ { zend_class_entry *ce = Z_OBJCE_P(val); - zval *retval = NULL, fname; + zval retval, fname; HashTable* myht; if (Z_TYPE_P(val) == IS_ARRAY) { @@ -568,54 +551,57 @@ static void json_encode_serializable_object(smart_str *buf, zval *val, int optio myht = Z_OBJPROP_P(val); } - if (myht && myht->nApplyCount > 1) { + if (myht && ZEND_HASH_GET_APPLY_COUNT(myht) > 1) { JSON_G(error_code) = PHP_JSON_ERROR_RECURSION; smart_str_appendl(buf, "null", 4); return; } - ZVAL_STRING(&fname, "jsonSerialize", 0); + ZVAL_STRING(&fname, "jsonSerialize"); - if (FAILURE == call_user_function_ex(EG(function_table), &val, &fname, &retval, 0, NULL, 1, NULL TSRMLS_CC) || !retval) { + if (FAILURE == call_user_function_ex(EG(function_table), val, &fname, &retval, 0, NULL, 1, NULL TSRMLS_CC) || Z_TYPE(retval) == IS_UNDEF) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Failed calling %s::jsonSerialize()", ce->name); smart_str_appendl(buf, "null", sizeof("null") - 1); + zval_ptr_dtor(&fname); return; } if (EG(exception)) { /* Error already raised */ zval_ptr_dtor(&retval); + zval_ptr_dtor(&fname); smart_str_appendl(buf, "null", sizeof("null") - 1); return; } - if ((Z_TYPE_P(retval) == IS_OBJECT) && - (Z_OBJ_HANDLE_P(retval) == Z_OBJ_HANDLE_P(val))) { + if ((Z_TYPE(retval) == IS_OBJECT) && + (Z_OBJ_HANDLE(retval) == Z_OBJ_HANDLE_P(val))) { /* Handle the case where jsonSerialize does: return $this; by going straight to encode array */ json_encode_array(buf, &retval, options TSRMLS_CC); } else { /* All other types, encode as normal */ - php_json_encode(buf, retval, options TSRMLS_CC); + php_json_encode(buf, &retval, options TSRMLS_CC); } zval_ptr_dtor(&retval); + zval_ptr_dtor(&fname); } /* }}} */ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */ { +again: switch (Z_TYPE_P(val)) { case IS_NULL: smart_str_appendl(buf, "null", 4); break; - case IS_BOOL: - if (Z_BVAL_P(val)) { - smart_str_appendl(buf, "true", 4); - } else { - smart_str_appendl(buf, "false", 5); - } + case IS_TRUE: + smart_str_appendl(buf, "true", 4); + break; + case IS_FALSE: + smart_str_appendl(buf, "false", 5); break; case IS_LONG: @@ -650,9 +636,13 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_ } /* fallthrough -- Non-serializable object */ case IS_ARRAY: - json_encode_array(buf, &val, options TSRMLS_CC); + json_encode_array(buf, val, options TSRMLS_CC); break; + case IS_REFERENCE: + val = Z_REFVAL_P(val); + goto again; + default: JSON_G(error_code) = PHP_JSON_ERROR_UNSUPPORTED_TYPE; smart_str_appendl(buf, "null", 4); @@ -666,7 +656,6 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, int options, long depth TSRMLS_DC) /* {{{ */ { int utf16_len; - zval *z; unsigned short *utf16; JSON_parser jp; @@ -687,19 +676,16 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, RETURN_NULL(); } - ALLOC_INIT_ZVAL(z); jp = new_JSON_parser(depth); - if (parse_JSON_ex(jp, z, utf16, utf16_len, options TSRMLS_CC)) { - *return_value = *z; - } - else - { + if (!parse_JSON_ex(jp, return_value, utf16, utf16_len, options TSRMLS_CC)) { double d; int type, overflow_info; long p; char *trim = str; int trim_len = str_len; + zval_dtor(return_value); + /* Increment trimmed string pointer to strip leading whitespace */ /* JSON RFC says to consider as whitespace: space, tab, LF or CR */ while (trim_len && (*trim == ' ' || *trim == '\t' || *trim == '\n' || *trim == '\r')) { @@ -750,7 +736,7 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, if (is_float) { RETVAL_DOUBLE(d); } else { - RETVAL_STRINGL(trim, trim_len, 1); + RETVAL_STRINGL(trim, trim_len); } } else { RETVAL_DOUBLE(d); @@ -761,10 +747,7 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, if (Z_TYPE_P(return_value) != IS_NULL) { jp->error_code = PHP_JSON_ERROR_NONE; } - - zval_dtor(z); } - FREE_ZVAL(z); efree(utf16); JSON_G(error_code) = jp->error_code; free_JSON_parser(jp); @@ -792,12 +775,12 @@ static PHP_FUNCTION(json_encode) php_json_encode(&buf, parameter, options TSRMLS_CC); if (JSON_G(error_code) != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) { + smart_str_free(&buf); ZVAL_FALSE(return_value); } else { - ZVAL_STRINGL(return_value, buf.c, buf.len, 1); + smart_str_0(&buf); /* copy? */ + ZVAL_STR(return_value, buf.s); } - - smart_str_free(&buf); } /* }}} */ @@ -854,25 +837,25 @@ static PHP_FUNCTION(json_last_error_msg) switch(JSON_G(error_code)) { case PHP_JSON_ERROR_NONE: - RETURN_STRING("No error", 1); + RETURN_STRING("No error"); case PHP_JSON_ERROR_DEPTH: - RETURN_STRING("Maximum stack depth exceeded", 1); + RETURN_STRING("Maximum stack depth exceeded"); case PHP_JSON_ERROR_STATE_MISMATCH: - RETURN_STRING("State mismatch (invalid or malformed JSON)", 1); + RETURN_STRING("State mismatch (invalid or malformed JSON)"); case PHP_JSON_ERROR_CTRL_CHAR: - RETURN_STRING("Control character error, possibly incorrectly encoded", 1); + RETURN_STRING("Control character error, possibly incorrectly encoded"); case PHP_JSON_ERROR_SYNTAX: - RETURN_STRING("Syntax error", 1); + RETURN_STRING("Syntax error"); case PHP_JSON_ERROR_UTF8: - RETURN_STRING("Malformed UTF-8 characters, possibly incorrectly encoded", 1); + RETURN_STRING("Malformed UTF-8 characters, possibly incorrectly encoded"); case PHP_JSON_ERROR_RECURSION: - RETURN_STRING("Recursion detected", 1); + RETURN_STRING("Recursion detected"); case PHP_JSON_ERROR_INF_OR_NAN: - RETURN_STRING("Inf and NaN cannot be JSON encoded", 1); + RETURN_STRING("Inf and NaN cannot be JSON encoded"); case PHP_JSON_ERROR_UNSUPPORTED_TYPE: - RETURN_STRING("Type is not supported", 1); + RETURN_STRING("Type is not supported"); default: - RETURN_STRING("Unknown error", 1); + RETURN_STRING("Unknown error"); } } diff --git a/ext/json/tests/unsupported_type_error.phpt b/ext/json/tests/unsupported_type_error.phpt index 45a167a5ac..dd5a7963aa 100644 --- a/ext/json/tests/unsupported_type_error.phpt +++ b/ext/json/tests/unsupported_type_error.phpt @@ -17,7 +17,7 @@ var_dump(json_last_error(), json_last_error_msg()); ?> --EXPECTF-- -resource(5) of type (stream) +resource(%d) of type (stream) bool(false) int(8) string(21) "Type is not supported" diff --git a/sapi/fpm/fpm/fastcgi.c b/sapi/fpm/fpm/fastcgi.c index d77b6f8ca7..8fbdd36a24 100644 --- a/sapi/fpm/fpm/fastcgi.c +++ b/sapi/fpm/fpm/fastcgi.c @@ -479,11 +479,7 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e memcpy(tmp, p, eff_name_len); tmp[eff_name_len] = 0; s = estrndup((char*)p + name_len, val_len); - if (s == NULL) { - ret = 0; - break; - } - zend_hash_update(req->env, tmp, eff_name_len+1, &s, sizeof(char*), NULL); + zend_hash_str_update_ptr(req->env, tmp, eff_name_len, s); p += name_len + val_len; } if (tmp != buf && tmp != NULL) { @@ -492,9 +488,9 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e return ret; } -static void fcgi_free_var(char **s) +static void fcgi_free_var(zval *zv) { - efree(*s); + efree(Z_PTR_P(zv)); } static int fcgi_read_request(fcgi_request *req) @@ -509,7 +505,7 @@ static int fcgi_read_request(fcgi_request *req) req->out_hdr = NULL; req->out_pos = req->out_buf; ALLOC_HASHTABLE(req->env); - zend_hash_init(req->env, 0, NULL, (void (*)(void *)) fcgi_free_var, 0); + zend_hash_init(req->env, 0, NULL, fcgi_free_var, 0); if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) || hdr.version < FCGI_VERSION_1) { @@ -546,15 +542,15 @@ static int fcgi_read_request(fcgi_request *req) switch ((((fcgi_begin_request*)buf)->roleB1 << 8) + ((fcgi_begin_request*)buf)->roleB0) { case FCGI_RESPONDER: val = estrdup("RESPONDER"); - zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL); + zend_hash_str_update_ptr(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), val); break; case FCGI_AUTHORIZER: val = estrdup("AUTHORIZER"); - zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL); + zend_hash_str_update_ptr(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), val); break; case FCGI_FILTER: val = estrdup("FILTER"); - zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL); + zend_hash_str_update_ptr(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), val); break; default: return 0; @@ -593,12 +589,8 @@ static int fcgi_read_request(fcgi_request *req) } } else if (hdr.type == FCGI_GET_VALUES) { unsigned char *p = buf + sizeof(fcgi_header); - HashPosition pos; - char * str_index; - uint str_length; - ulong num_index; - int key_type; - zval ** value; + zend_string *key; + zval *value; if (safe_read(req, buf, len+padding) != len+padding) { req->keep = 0; @@ -610,28 +602,26 @@ static int fcgi_read_request(fcgi_request *req) return 0; } - zend_hash_internal_pointer_reset_ex(req->env, &pos); - while ((key_type = zend_hash_get_current_key_ex(req->env, &str_index, &str_length, &num_index, 0, &pos)) != HASH_KEY_NON_EXISTENT) { + ZEND_HASH_FOREACH_STR_KEY(req->env, key) { int zlen; - zend_hash_move_forward_ex(req->env, &pos); - if (key_type != HASH_KEY_IS_STRING) { + if (!key) { continue; } - if (zend_hash_find(&fcgi_mgmt_vars, str_index, str_length, (void**) &value) != SUCCESS) { + value = zend_hash_find(&fcgi_mgmt_vars, key); + if (!value) { continue; } - --str_length; - zlen = Z_STRLEN_PP(value); - if ((p + 4 + 4 + str_length + zlen) >= (buf + sizeof(buf))) { + zlen = Z_STRLEN_P(value); + if ((p + 4 + 4 + key->len + zlen) >= (buf + sizeof(buf))) { break; } - if (str_length < 0x80) { - *p++ = str_length; + if (key->len < 0x80) { + *p++ = key->len; } else { - *p++ = ((str_length >> 24) & 0xff) | 0x80; - *p++ = (str_length >> 16) & 0xff; - *p++ = (str_length >> 8) & 0xff; - *p++ = str_length & 0xff; + *p++ = ((key->len >> 24) & 0xff) | 0x80; + *p++ = (key->len >> 16) & 0xff; + *p++ = (key->len >> 8) & 0xff; + *p++ = key->len & 0xff; } if (zlen < 0x80) { *p++ = zlen; @@ -641,11 +631,11 @@ static int fcgi_read_request(fcgi_request *req) *p++ = (zlen >> 8) & 0xff; *p++ = zlen & 0xff; } - memcpy(p, str_index, str_length); - p += str_length; - memcpy(p, Z_STRVAL_PP(value), zlen); + memcpy(p, key->val, key->len); + p += key->len; + memcpy(p, Z_STRVAL_P(value), zlen); p += zlen; - } + } ZEND_HASH_FOREACH_END(); len = p - buf - sizeof(fcgi_header); len += fcgi_make_header((fcgi_header*)buf, FCGI_GET_VALUES_RESULT, 0, len); if (safe_write(req, buf, sizeof(fcgi_header)+len) != (int)sizeof(fcgi_header)+len) { @@ -1050,28 +1040,22 @@ int fcgi_finish_request(fcgi_request *req, int force_close) char* fcgi_getenv(fcgi_request *req, const char* var, int var_len) { - char **val; - - if (!req) return NULL; - - if (zend_hash_find(req->env, (char*)var, var_len+1, (void**)&val) == SUCCESS) { - return *val; + if (!req) { + return NULL; } - return NULL; + + return zend_hash_str_find_ptr(req->env, var, var_len); } char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val) { if (var && req) { if (val == NULL) { - zend_hash_del(req->env, var, var_len+1); + zend_hash_str_del(req->env, var, var_len); } else { - char **ret; - val = estrdup(val); - if (zend_hash_update(req->env, var, var_len+1, &val, sizeof(char*), (void**)&ret) == SUCCESS) { - return *ret; - } + zend_hash_str_update_ptr(req->env, var, var_len, val); + return val; } } return NULL; @@ -1079,19 +1063,14 @@ char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val) void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len) { - zval * zvalue; - zvalue = pemalloc(sizeof(*zvalue), 1); - Z_TYPE_P(zvalue) = IS_STRING; - Z_STRVAL_P(zvalue) = pestrndup(value, value_len, 1); - Z_STRLEN_P(zvalue) = value_len; - zend_hash_add(&fcgi_mgmt_vars, name, name_len + 1, &zvalue, sizeof(zvalue), NULL); + zval zvalue; + ZVAL_STR(&zvalue, STR_INIT(value, value_len, 1)); + zend_hash_str_add(&fcgi_mgmt_vars, name, name_len, &zvalue); } -void fcgi_free_mgmt_var_cb(void * ptr) +void fcgi_free_mgmt_var_cb(zval *zv) { - zval ** var = (zval **)ptr; - pefree(Z_STRVAL_PP(var), 1); - pefree(*var, 1); + STR_FREE(Z_STR_P(zv)); } char *fcgi_get_last_client_ip() /* {{{ */ diff --git a/sapi/fpm/fpm/fastcgi.h b/sapi/fpm/fpm/fastcgi.h index 34f9eef9da..5a8aa0e70e 100644 --- a/sapi/fpm/fpm/fastcgi.h +++ b/sapi/fpm/fpm/fastcgi.h @@ -131,7 +131,7 @@ ssize_t fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, i int fcgi_flush(fcgi_request *req, int close); void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len); -void fcgi_free_mgmt_var_cb(void * ptr); +void fcgi_free_mgmt_var_cb(zval *ptr); char *fcgi_get_last_client_ip(); diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index 9b2878dd63..6b9abc859f 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -216,8 +216,9 @@ static php_cgi_globals_struct php_cgi_globals; #define TRANSLATE_SLASHES(path) #endif -static int print_module_info(zend_module_entry *module, void *arg TSRMLS_DC) +static int print_module_info(zval *zv TSRMLS_DC) { + zend_module_entry *module = Z_PTR_P(zv); php_printf("%s\n", module->name); return 0; } @@ -227,19 +228,18 @@ static int module_name_cmp(const void *a, const void *b TSRMLS_DC) Bucket *f = (Bucket *) a; Bucket *s = (Bucket *) b; - return strcasecmp( ((zend_module_entry *)f->xData)->name, - ((zend_module_entry *)s->xData)->name); + return strcasecmp( ((zend_module_entry *) Z_PTR(f->val))->name, + ((zend_module_entry *) Z_PTR(s->val))->name); } static void print_modules(TSRMLS_D) { HashTable sorted_registry; - zend_module_entry tmp; zend_hash_init(&sorted_registry, 50, NULL, NULL, 1); - zend_hash_copy(&sorted_registry, &module_registry, NULL, &tmp, sizeof(zend_module_entry)); + zend_hash_copy(&sorted_registry, &module_registry, NULL); zend_hash_sort(&sorted_registry, zend_qsort, module_name_cmp, 0 TSRMLS_CC); - zend_hash_apply_with_argument(&sorted_registry, (apply_func_arg_t) print_module_info, NULL TSRMLS_CC); + zend_hash_apply(&sorted_registry, print_module_info TSRMLS_CC); zend_hash_destroy(&sorted_registry); } @@ -568,32 +568,23 @@ static char *sapi_cgi_read_cookies(TSRMLS_D) void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC) { fcgi_request *request; - HashPosition pos; - char *var, **val; - uint var_len; - ulong idx; + zend_string *var; + char *val; int filter_arg; - - if (PG(http_globals)[TRACK_VARS_ENV] && - array_ptr != PG(http_globals)[TRACK_VARS_ENV] && - Z_TYPE_P(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && - zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_ENV])) > 0 + if (Z_TYPE(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && + Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) && + zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_ENV])) > 0 ) { zval_dtor(array_ptr); - *array_ptr = *PG(http_globals)[TRACK_VARS_ENV]; - INIT_PZVAL(array_ptr); - zval_copy_ctor(array_ptr); + ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_ENV]); return; - } else if (PG(http_globals)[TRACK_VARS_SERVER] && - array_ptr != PG(http_globals)[TRACK_VARS_SERVER] && - Z_TYPE_P(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && - zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER])) > 0 + } else if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && + Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_SERVER]) && + zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])) > 0 ) { zval_dtor(array_ptr); - *array_ptr = *PG(http_globals)[TRACK_VARS_SERVER]; - INIT_PZVAL(array_ptr); - zval_copy_ctor(array_ptr); + ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_SERVER]); return; } @@ -601,19 +592,16 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC) php_php_import_environment_variables(array_ptr TSRMLS_CC); request = (fcgi_request*) SG(server_context); - filter_arg = (array_ptr == PG(http_globals)[TRACK_VARS_ENV])?PARSE_ENV:PARSE_SERVER; + filter_arg = Z_ARR_P(array_ptr) == Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) + ? PARSE_ENV : PARSE_SERVER; - for (zend_hash_internal_pointer_reset_ex(request->env, &pos); - zend_hash_get_current_key_ex(request->env, &var, &var_len, &idx, 0, &pos) == HASH_KEY_IS_STRING && - zend_hash_get_current_data_ex(request->env, (void **) &val, &pos) == SUCCESS; - zend_hash_move_forward_ex(request->env, &pos) - ) { + ZEND_HASH_FOREACH_STR_KEY_PTR(request->env, var, val) { unsigned int new_val_len; - if (sapi_module.input_filter(filter_arg, var, val, strlen(*val), &new_val_len TSRMLS_CC)) { - php_register_variable_safe(var, *val, new_val_len, array_ptr TSRMLS_CC); + if (var && sapi_module.input_filter(filter_arg, var->val, &val, strlen(val), &new_val_len TSRMLS_CC)) { + php_register_variable_safe(var->val, val, new_val_len, array_ptr TSRMLS_CC); } - } + } ZEND_HASH_FOREACH_END(); } static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC) @@ -695,17 +683,16 @@ static void sapi_cgi_log_message(char *message) static void php_cgi_ini_activate_user_config(char *path, int path_len, const char *doc_root, int doc_root_len, int start TSRMLS_DC) { char *ptr; - user_config_cache_entry *new_entry, *entry; time_t request_time = sapi_get_request_time(TSRMLS_C); + user_config_cache_entry *entry = zend_hash_str_find_ptr(&CGIG(user_config_cache), path, path_len); /* Find cached config entry: If not found, create one */ - if (zend_hash_find(&CGIG(user_config_cache), path, path_len + 1, (void **) &entry) == FAILURE) { - new_entry = pemalloc(sizeof(user_config_cache_entry), 1); - new_entry->expires = 0; - new_entry->user_config = (HashTable *) pemalloc(sizeof(HashTable), 1); - zend_hash_init(new_entry->user_config, 0, NULL, (dtor_func_t) config_zval_dtor, 1); - zend_hash_update(&CGIG(user_config_cache), path, path_len + 1, new_entry, sizeof(user_config_cache_entry), (void **) &entry); - free(new_entry); + if (!entry) { + entry = pemalloc(sizeof(user_config_cache_entry), 1); + entry->expires = 0; + entry->user_config = (HashTable *) pemalloc(sizeof(HashTable), 1); + zend_hash_init(entry->user_config, 0, NULL, (dtor_func_t) config_zval_dtor, 1); + zend_hash_str_update_ptr(&CGIG(user_config_cache), path, path_len, entry); } /* Check whether cache entry has expired and rescan if it is */ @@ -1966,7 +1953,7 @@ fastcgi_request_done: fpm_request_end(TSRMLS_C); fpm_log_write(NULL TSRMLS_CC); - STR_FREE(SG(request_info).path_translated); + efree(SG(request_info).path_translated); SG(request_info).path_translated = NULL; php_request_shutdown((void *) 0); diff --git a/sapi/fpm/fpm/fpm_php.c b/sapi/fpm/fpm/fpm_php.c index cd4d3aef3a..7112cb923b 100644 --- a/sapi/fpm/fpm/fpm_php.c +++ b/sapi/fpm/fpm/fpm_php.c @@ -28,7 +28,7 @@ static int fpm_php_zend_ini_alter_master(char *name, int name_length, char *new_ zend_ini_entry *ini_entry; char *duplicate; - if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE) { + if ((ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length))) { return FAILURE; } @@ -89,7 +89,7 @@ int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */ if (!strcmp(name, "extension") && *value) { zval zv; php_dl(value, MODULE_PERSISTENT, &zv, 1 TSRMLS_CC); - return Z_BVAL(zv) ? 1 : -1; + return Z_TYPE(zv) == IS_TRUE; } if (fpm_php_zend_ini_alter_master(name, name_len+1, value, value_len, mode, PHP_INI_STAGE_ACTIVATE TSRMLS_CC) == FAILURE) { @@ -258,39 +258,30 @@ int fpm_php_limit_extensions(char *path) /* {{{ */ } /* }}} */ -char* fpm_php_get_string_from_table(char *table, char *key TSRMLS_DC) /* {{{ */ +char* fpm_php_get_string_from_table(zend_string *table, char *key TSRMLS_DC) /* {{{ */ { - zval **data, **tmp; - char *string_key; - uint string_len; - ulong num_key; + zval *data, *tmp; + zend_string *str; if (!table || !key) { return NULL; } /* inspired from ext/standard/info.c */ - zend_is_auto_global(table, strlen(table) TSRMLS_CC); + zend_is_auto_global(table TSRMLS_CC); /* find the table and ensure it's an array */ - if (zend_hash_find(&EG(symbol_table), table, strlen(table) + 1, (void **) &data) == SUCCESS && Z_TYPE_PP(data) == IS_ARRAY) { - - /* reset the internal pointer */ - zend_hash_internal_pointer_reset(Z_ARRVAL_PP(data)); - - /* parse the array to look for our key */ - while (zend_hash_get_current_data(Z_ARRVAL_PP(data), (void **) &tmp) == SUCCESS) { - /* ensure the key is a string */ - if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(data), &string_key, &string_len, &num_key, 0, NULL) == HASH_KEY_IS_STRING) { - /* compare to our key */ - if (!strncmp(string_key, key, string_len)) { - return Z_STRVAL_PP(tmp); - } - } - zend_hash_move_forward(Z_ARRVAL_PP(data)); - } + data = zend_hash_find(&EG(symbol_table).ht, table); + if (!data || Z_TYPE_P(data) != IS_ARRAY) { + return NULL; } + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(data), str, tmp) { + if (str && !strncmp(str->val, key, str->len)) { + return Z_STRVAL_P(tmp); + } + } ZEND_HASH_FOREACH_END(); + return NULL; } /* }}} */ diff --git a/sapi/fpm/fpm/fpm_php.h b/sapi/fpm/fpm/fpm_php.h index d6054737d6..20f5a9454b 100644 --- a/sapi/fpm/fpm/fpm_php.h +++ b/sapi/fpm/fpm/fpm_php.h @@ -44,7 +44,7 @@ void fpm_php_soft_quit(); int fpm_php_init_main(); int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode); int fpm_php_limit_extensions(char *path); -char* fpm_php_get_string_from_table(char *table, char *key TSRMLS_DC); +char* fpm_php_get_string_from_table(zend_string *table, char *key TSRMLS_DC); #endif diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index 2363b57f80..e447648462 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -55,6 +55,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ int full, encode; char *short_syntax, *short_post; char *full_pre, *full_syntax, *full_post, *full_separator; + zend_string *_GET_str; if (!SG(request_info).request_uri) { return 0; @@ -126,13 +127,14 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ } /* full status ? */ - full = (fpm_php_get_string_from_table("_GET", "full" TSRMLS_CC) != NULL); + _GET_str = STR_INIT("_GET", sizeof("_GET")-1, 0); + full = (fpm_php_get_string_from_table(_GET_str, "full" TSRMLS_CC) != NULL); short_syntax = short_post = NULL; full_separator = full_pre = full_syntax = full_post = NULL; encode = 0; /* HTML */ - if (fpm_php_get_string_from_table("_GET", "html" TSRMLS_CC)) { + if (fpm_php_get_string_from_table(_GET_str, "html" TSRMLS_CC)) { sapi_add_header_ex(ZEND_STRL("Content-Type: text/html"), 1, 1 TSRMLS_CC); time_format = "%d/%b/%Y:%H:%M:%S %z"; encode = 1; @@ -207,7 +209,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ } /* XML */ - } else if (fpm_php_get_string_from_table("_GET", "xml" TSRMLS_CC)) { + } else if (fpm_php_get_string_from_table(_GET_str, "xml" TSRMLS_CC)) { sapi_add_header_ex(ZEND_STRL("Content-Type: text/xml"), 1, 1 TSRMLS_CC); time_format = "%s"; encode = 1; @@ -259,7 +261,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ } /* JSON */ - } else if (fpm_php_get_string_from_table("_GET", "json" TSRMLS_CC)) { + } else if (fpm_php_get_string_from_table(_GET_str, "json" TSRMLS_CC)) { sapi_add_header_ex(ZEND_STRL("Content-Type: application/json"), 1, 1 TSRMLS_CC); time_format = "%s"; @@ -376,6 +378,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ PUTS(buffer); efree(buffer); + STR_RELEASE(_GET_str); if (short_post) { PUTS(short_post); @@ -384,7 +387,7 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ /* no need to test the var 'full' */ if (full_syntax) { int i, first; - size_t len; + zend_string *tmp_query_string; char *query_string; struct timeval duration, now; #ifdef HAVE_FPM_LQ @@ -413,12 +416,13 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ } query_string = NULL; - len = 0; + tmp_query_string = NULL; if (proc.query_string[0] != '\0') { if (!encode) { query_string = proc.query_string; } else { - query_string = php_escape_html_entities_ex((unsigned char *)proc.query_string, strlen(proc.query_string), &len, 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, 1 TSRMLS_CC); + tmp_query_string = php_escape_html_entities_ex((unsigned char *)proc.query_string, strlen(proc.query_string), 1, ENT_HTML_IGNORE_ERRORS & ENT_COMPAT, NULL, 1 TSRMLS_CC); + query_string = tmp_query_string->val; } } @@ -458,8 +462,8 @@ int fpm_status_handle_request(TSRMLS_D) /* {{{ */ PUTS(buffer); efree(buffer); - if (len > 0 && query_string) { - efree(query_string); + if (tmp_query_string) { + STR_FREE(tmp_query_string); } } |