mirror of
https://github.com/php/php-src.git
synced 2024-11-25 10:54:15 +08:00
- Added support for parsing recordsets.
- Fixed a bug that sometimes would corrupt top-level element if it was a scalar one.
This commit is contained in:
parent
3744720899
commit
a2f95abb6d
3
NEWS
3
NEWS
@ -1,6 +1,9 @@
|
||||
PHP 4.0 NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? 200?, Version 4.2.0-dev
|
||||
- Fixed a bug in WDDX deserialization that would sometimes corrupt the root
|
||||
element if it was a scalar one. (Andrei)
|
||||
- Added support for parsing recordsets contained in WDDX packets. (Andrei)
|
||||
- Renamed key_exists tp array_key_exists. (Derick)
|
||||
- Fix ImageColorsForIndex() and ImageColorAt() to work for TrueColor
|
||||
images. (Rasmus)
|
||||
|
142
ext/wddx/wddx.c
142
ext/wddx/wddx.c
@ -31,6 +31,7 @@
|
||||
#include "ext/standard/info.h"
|
||||
#include "ext/standard/php_smart_str.h"
|
||||
#include "ext/standard/html.h"
|
||||
#include "ext/standard/php_string.h"
|
||||
|
||||
#define WDDX_BUF_LEN 256
|
||||
#define PHP_CLASS_NAME_VAR "php_class_name"
|
||||
@ -47,8 +48,10 @@
|
||||
#define EL_STRUCT "struct"
|
||||
#define EL_VALUE "value"
|
||||
#define EL_VAR "var"
|
||||
#define EL_VAR_NAME "name"
|
||||
#define EL_NAME "name"
|
||||
#define EL_VERSION "version"
|
||||
#define EL_RECORDSET "recordset"
|
||||
#define EL_FIELD "field"
|
||||
|
||||
#define php_wddx_deserialize(a,b) \
|
||||
php_wddx_deserialize_ex((a)->value.str.val, (a)->value.str.len, (b))
|
||||
@ -72,7 +75,9 @@ typedef struct {
|
||||
ST_NUMBER,
|
||||
ST_STRING,
|
||||
ST_BINARY,
|
||||
ST_STRUCT
|
||||
ST_STRUCT,
|
||||
ST_RECORDSET,
|
||||
ST_FIELD
|
||||
} type;
|
||||
char *varname;
|
||||
} st_entry;
|
||||
@ -80,6 +85,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
int top, max;
|
||||
char *varname;
|
||||
zend_bool done;
|
||||
void **elements;
|
||||
} wddx_stack;
|
||||
|
||||
@ -129,6 +135,7 @@ static int wddx_stack_init(wddx_stack *stack)
|
||||
} else {
|
||||
stack->max = STACK_BLOCK_SIZE;
|
||||
stack->varname = NULL;
|
||||
stack->done = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
@ -382,7 +389,7 @@ static void php_wddx_serialize_string(wddx_packet *packet, zval *var)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (iscntrl((int)*p)) {
|
||||
if (iscntrl((int)*p) && *p != '\n') {
|
||||
FLUSH_BUF();
|
||||
sprintf(control_buf, WDDX_CHAR, *p);
|
||||
php_wddx_add_chunk(packet, control_buf);
|
||||
@ -712,12 +719,14 @@ static void php_wddx_push_element(void *user_data, const char *name, const char
|
||||
wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
|
||||
} else if (!strcmp(name, EL_CHAR)) {
|
||||
int i;
|
||||
char tmp_buf[2];
|
||||
|
||||
for (i=0; atts[i]; i++) {
|
||||
if (!strcmp(atts[i], EL_CHAR_CODE) && atts[i+1]) {
|
||||
sprintf(tmp_buf, "%c", (char)strtol(atts[i+1], NULL, 16));
|
||||
for (i = 0; atts[i]; i++) {
|
||||
if (!strcmp(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) {
|
||||
char tmp_buf[2];
|
||||
|
||||
sprintf(tmp_buf, "%c", (char)strtol(atts[i], NULL, 16));
|
||||
php_wddx_process_data(user_data, tmp_buf, strlen(tmp_buf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(name, EL_NUMBER)) {
|
||||
@ -731,8 +740,8 @@ static void php_wddx_push_element(void *user_data, const char *name, const char
|
||||
} else if (!strcmp(name, EL_BOOLEAN)) {
|
||||
int i;
|
||||
|
||||
for (i=0; atts[i]; i++) {
|
||||
if (!strcmp(atts[i], EL_VALUE) && atts[i+1]) {
|
||||
for (i = 0; atts[i]; i++) {
|
||||
if (!strcmp(atts[i], EL_VALUE) && atts[++i] && atts[i][0]) {
|
||||
ent.type = ST_BOOLEAN;
|
||||
SET_STACK_VARNAME;
|
||||
|
||||
@ -740,7 +749,8 @@ static void php_wddx_push_element(void *user_data, const char *name, const char
|
||||
INIT_PZVAL(ent.data);
|
||||
Z_TYPE_P(ent.data) = IS_BOOL;
|
||||
wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
|
||||
php_wddx_process_data(user_data, atts[i+1], strlen(atts[i+1]));
|
||||
php_wddx_process_data(user_data, atts[i], strlen(atts[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(name, EL_NULL)) {
|
||||
@ -771,14 +781,83 @@ static void php_wddx_push_element(void *user_data, const char *name, const char
|
||||
} else if (!strcmp(name, EL_VAR)) {
|
||||
int i;
|
||||
|
||||
for (i=0; atts[i]; i++) {
|
||||
if (!strcmp(atts[i], EL_VAR_NAME) && atts[i+1]) {
|
||||
char *decoded_value;
|
||||
for (i = 0; atts[i]; i++) {
|
||||
if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
|
||||
char *decoded;
|
||||
int decoded_len;
|
||||
decoded_value = xml_utf8_decode(atts[i+1],strlen(atts[i+1]),&decoded_len,"ISO-8859-1");
|
||||
stack->varname = decoded_value;
|
||||
decoded = xml_utf8_decode(atts[i], strlen(atts[i]), &decoded_len, "ISO-8859-1");
|
||||
stack->varname = decoded;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(name, EL_RECORDSET)) {
|
||||
int i;
|
||||
|
||||
ent.type = ST_RECORDSET;
|
||||
SET_STACK_VARNAME;
|
||||
MAKE_STD_ZVAL(ent.data);
|
||||
array_init(ent.data);
|
||||
|
||||
for (i = 0; atts[i]; i++) {
|
||||
if (!strcmp(atts[i], "fieldNames") && atts[++i] && atts[i][0]) {
|
||||
zval *tmp;
|
||||
char *key;
|
||||
char *p1, *p2, *endp;
|
||||
char *decoded;
|
||||
int decoded_len;
|
||||
|
||||
decoded = xml_utf8_decode(atts[i], strlen(atts[i]), &decoded_len, "ISO-8859-1");
|
||||
endp = (char *)decoded + decoded_len;
|
||||
p1 = (char *)decoded;
|
||||
while ((p2 = php_memnstr(p1, ",", sizeof(",")-1, endp)) != NULL) {
|
||||
key = estrndup(p1, p2 - p1);
|
||||
MAKE_STD_ZVAL(tmp);
|
||||
array_init(tmp);
|
||||
add_assoc_zval_ex(ent.data, key, p2 - p1 + 1, tmp);
|
||||
p1 = p2 + sizeof(",")-1;
|
||||
efree(key);
|
||||
}
|
||||
|
||||
if (p1 <= endp) {
|
||||
MAKE_STD_ZVAL(tmp);
|
||||
array_init(tmp);
|
||||
add_assoc_zval_ex(ent.data, p1, endp - p1 + 1, tmp);
|
||||
}
|
||||
|
||||
efree(decoded);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
|
||||
} else if (!strcmp(name, EL_FIELD)) {
|
||||
int i;
|
||||
st_entry ent;
|
||||
|
||||
ent.type = ST_FIELD;
|
||||
ent.varname = NULL;
|
||||
ent.data = NULL;
|
||||
|
||||
for (i = 0; atts[i]; i++) {
|
||||
if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
|
||||
char *decoded;
|
||||
int decoded_len;
|
||||
st_entry *recordset;
|
||||
zval **field;
|
||||
|
||||
decoded = xml_utf8_decode(atts[i], strlen(atts[i]), &decoded_len, "ISO-8859-1");
|
||||
if (wddx_stack_top(stack, (void**)&recordset) == SUCCESS &&
|
||||
recordset->type == ST_RECORDSET &&
|
||||
zend_hash_find(Z_ARRVAL_P(recordset->data), decoded, decoded_len+1, (void**)&field) == SUCCESS) {
|
||||
ent.data = *field;
|
||||
}
|
||||
|
||||
efree(decoded);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@ -802,7 +881,7 @@ static void php_wddx_pop_element(void *user_data, const char *name)
|
||||
if (!strcmp(name, EL_STRING) || !strcmp(name, EL_NUMBER) ||
|
||||
!strcmp(name, EL_BOOLEAN) || !strcmp(name, EL_NULL) ||
|
||||
!strcmp(name, EL_ARRAY) || !strcmp(name, EL_STRUCT) ||
|
||||
!strcmp(name, EL_BINARY)) {
|
||||
!strcmp(name, EL_RECORDSET) || !strcmp(name, EL_BINARY)) {
|
||||
wddx_stack_top(stack, (void**)&ent1);
|
||||
|
||||
if (!strcmp(name, EL_BINARY)) {
|
||||
@ -833,6 +912,14 @@ static void php_wddx_pop_element(void *user_data, const char *name)
|
||||
if (stack->top > 1) {
|
||||
stack->top--;
|
||||
wddx_stack_top(stack, (void**)&ent2);
|
||||
|
||||
/* if non-existent field */
|
||||
if (ent2->type == ST_FIELD && ent2->data == NULL) {
|
||||
zval_ptr_dtor(&ent1->data);
|
||||
efree(ent1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(ent2->data) == IS_ARRAY || Z_TYPE_P(ent2->data) == IS_OBJECT) {
|
||||
target_hash = HASH_OF(ent2->data);
|
||||
|
||||
@ -871,8 +958,7 @@ static void php_wddx_pop_element(void *user_data, const char *name)
|
||||
|
||||
/* Clean up class name var entry */
|
||||
zval_ptr_dtor(&ent1->data);
|
||||
}
|
||||
else
|
||||
} else
|
||||
zend_hash_update(target_hash,
|
||||
ent1->varname, strlen(ent1->varname)+1,
|
||||
&ent1->data, sizeof(zval *), NULL);
|
||||
@ -884,9 +970,15 @@ static void php_wddx_pop_element(void *user_data, const char *name)
|
||||
}
|
||||
}
|
||||
efree(ent1);
|
||||
}
|
||||
} else
|
||||
stack->done = 1;
|
||||
} else if (!strcmp(name, EL_VAR) && stack->varname) {
|
||||
efree(stack->varname);
|
||||
} else if (!strcmp(name, EL_FIELD)) {
|
||||
st_entry *ent;
|
||||
wddx_stack_top(stack, (void **)&ent);
|
||||
efree(ent);
|
||||
stack->top--;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@ -897,28 +989,28 @@ static void php_wddx_process_data(void *user_data, const char *s, int len)
|
||||
{
|
||||
st_entry *ent;
|
||||
wddx_stack *stack = (wddx_stack *)user_data;
|
||||
char *decoded_value;
|
||||
char *decoded;
|
||||
int decoded_len;
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (!wddx_stack_is_empty(stack)) {
|
||||
if (!wddx_stack_is_empty(stack) && !stack->done) {
|
||||
wddx_stack_top(stack, (void**)&ent);
|
||||
switch (Z_TYPE_P(ent)) {
|
||||
case ST_STRING:
|
||||
decoded_value = xml_utf8_decode(s,len,&decoded_len,"ISO-8859-1");
|
||||
decoded = xml_utf8_decode(s, len, &decoded_len, "ISO-8859-1");
|
||||
|
||||
if (Z_STRLEN_P(ent->data) == 0) {
|
||||
Z_STRVAL_P(ent->data) = estrndup(decoded_value, decoded_len);
|
||||
Z_STRVAL_P(ent->data) = estrndup(decoded, decoded_len);
|
||||
Z_STRLEN_P(ent->data) = decoded_len;
|
||||
} else {
|
||||
Z_STRVAL_P(ent->data) = erealloc(Z_STRVAL_P(ent->data),
|
||||
Z_STRLEN_P(ent->data) + decoded_len + 1);
|
||||
strncpy(Z_STRVAL_P(ent->data)+Z_STRLEN_P(ent->data), decoded_value, decoded_len);
|
||||
strncpy(Z_STRVAL_P(ent->data)+Z_STRLEN_P(ent->data), decoded, decoded_len);
|
||||
Z_STRLEN_P(ent->data) += decoded_len;
|
||||
Z_STRVAL_P(ent->data)[Z_STRLEN_P(ent->data)] = '\0';
|
||||
}
|
||||
|
||||
efree(decoded_value);
|
||||
efree(decoded);
|
||||
break;
|
||||
|
||||
case ST_BINARY:
|
||||
|
Loading…
Reference in New Issue
Block a user