stas Wed Feb 23 06:17:52 2005 EDT Modified files: /php-src/ext/standard var.c var_unserializer.c var_unserializer.re Log: Custom object serializer infrastructure - PHP implementation # The detailed announce on the list will follow
http://cvs.php.net/diff.php/php-src/ext/standard/var.c?r1=1.197&r2=1.198&ty=u Index: php-src/ext/standard/var.c diff -u php-src/ext/standard/var.c:1.197 php-src/ext/standard/var.c:1.198 --- php-src/ext/standard/var.c:1.197 Fri Dec 17 09:40:39 2004 +++ php-src/ext/standard/var.c Wed Feb 23 06:17:52 2005 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var.c,v 1.197 2004/12/17 14:40:39 derick Exp $ */ +/* $Id: var.c,v 1.198 2005/02/23 11:17:52 stas Exp $ */ /* {{{ includes @@ -671,6 +671,31 @@ zval fname; int res; + if(Z_OBJCE_PP(struc)->serialize != NULL) { + /* has custom handler */ + unsigned char *serialized_data = NULL; + zend_uint serialized_length; + + if(Z_OBJCE_PP(struc)->serialize(*struc, &serialized_data, &serialized_length, (zend_serialize_data *)var_hash TSRMLS_CC) == SUCCESS) { + smart_str_appendl(buf, "C:", 2); + smart_str_append_long(buf, Z_OBJCE_PP(struc)->name_length); + smart_str_appendl(buf, ":\"", 2); + smart_str_appendl(buf, Z_OBJCE_PP(struc)->name, Z_OBJCE_PP(struc)->name_length); + smart_str_appendl(buf, "\":", 2); + + smart_str_append_long(buf, serialized_length); + smart_str_appendl(buf, ":{", 2); + smart_str_appendl(buf, serialized_data, serialized_length); + smart_str_appendc(buf, '}'); + } else { + smart_str_appendl(buf, "N;", 2); + } + if(serialized_data) { + efree(serialized_data); + } + return; + } + if(Z_OBJCE_PP(struc) != PHP_IC_ENTRY) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 0); http://cvs.php.net/diff.php/php-src/ext/standard/var_unserializer.c?r1=1.53&r2=1.54&ty=u Index: php-src/ext/standard/var_unserializer.c diff -u php-src/ext/standard/var_unserializer.c:1.53 php-src/ext/standard/var_unserializer.c:1.54 --- php-src/ext/standard/var_unserializer.c:1.53 Mon Feb 14 16:03:09 2005 +++ php-src/ext/standard/var_unserializer.c Wed Feb 23 06:17:52 2005 @@ -1,5 +1,5 @@ -/* Generated by re2c 0.9.4 on Mon Feb 14 21:57:21 2005 */ -#line 1 "/usr/src/php-cvs/ext/standard/var_unserializer.re" +/* Generated by re2c 0.5 on Tue Feb 22 15:14:56 2005 */ +#line 1 "/php5/ext/standard/var_unserializer.re" /* +----------------------------------------------------------------------+ | PHP Version 5 | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.c,v 1.53 2005/02/14 21:03:09 helly Exp $ */ +/* $Id: var_unserializer.c,v 1.54 2005/02/23 11:17:52 stas Exp $ */ #include "php.h" #include "ext/standard/php_var.h" @@ -147,7 +147,7 @@ #define YYMARKER marker -#line 154 "/usr/src/php-cvs/ext/standard/var_unserializer.re" +#line 155 @@ -277,6 +277,33 @@ return 0; } +static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) +{ + int datalen; + + if(ce->unserialize == NULL) { + zend_error(E_WARNING, "Class %s has no unserializer", ce->name); + return 0; + } + + datalen = parse_iv2((*p) + 2, p); + + (*p) += 2; + + if((*p) + datalen >= max) { + zend_error(E_WARNING, "Unsifficient data for unserializing - %d required, %d present", datalen, max - (*p)); + return 0; + } + + if(ce->unserialize(rval, *p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) { + return 0; + } + + (*p) += datalen; + + return finish_nested_data(UNSERIALIZE_PASSTHRU); +} + static inline int object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce) { int elements; @@ -326,8 +353,6 @@ - -#line 7 "<stdout>" { YYCTYPE yych; unsigned int yyaccept; @@ -370,29 +395,30 @@ yy0: if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; - if(yych <= 'd'){ - if(yych <= 'R'){ - if(yych <= 'N'){ - if(yych <= 'M') goto yy16; - goto yy6; + if(yych <= 'c'){ + if(yych <= 'O'){ + if(yych <= 'C'){ + if(yych <= 'B') goto yy16; + goto yy13; } else { - if(yych <= 'O') goto yy13; - if(yych <= 'Q') goto yy16; - goto yy3; + if(yych <= 'M') goto yy16; + if(yych <= 'N') goto yy6; + goto yy13; } } else { - if(yych <= 'a'){ - if(yych <= '`') goto yy16; - goto yy11; + if(yych <= '`'){ + if(yych == 'R') goto yy3; + goto yy16; } else { + if(yych <= 'a') goto yy11; if(yych <= 'b') goto yy7; - if(yych <= 'c') goto yy16; - goto yy9; + goto yy16; } } } else { if(yych <= 'q'){ if(yych <= 'i'){ + if(yych <= 'd') goto yy9; if(yych <= 'h') goto yy16; goto yy8; } else { @@ -406,8 +432,7 @@ goto yy16; } else { if(yych <= '}') goto yy14; - if(yych <= 0xBF) goto yy16; - goto yy2; + if(yych <= '\277') goto yy16; } } } @@ -418,11 +443,9 @@ yy3: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if(yych == ':') goto yy87; - goto yy4; yy4: -#line 581 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ return 0; } -#line 102 "<stdout>" +#line 620 + { return 0; } yy5: yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if(yych == ':') goto yy81; @@ -458,51 +481,49 @@ yych = *(YYMARKER = ++YYCURSOR); if(yych == ':') goto yy17; goto yy4; -yy14: ++YYCURSOR; - goto yy15; +yy14: yych = *++YYCURSOR; yy15: -#line 575 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 614 + { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } -#line 147 "<stdout>" yy16: yych = *++YYCURSOR; goto yy4; yy17: yych = *++YYCURSOR; if(yybm[0+yych] & 128) goto yy19; if(yych != '+') goto yy2; - goto yy18; yy18: yych = *++YYCURSOR; if(yybm[0+yych] & 128) goto yy19; goto yy2; yy19: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy20; yy20: if(yybm[0+yych] & 128) goto yy19; if(yych != ':') goto yy2; - goto yy21; yy21: yych = *++YYCURSOR; if(yych != '"') goto yy2; - goto yy22; -yy22: ++YYCURSOR; - goto yy23; +yy22: yych = *++YYCURSOR; yy23: -#line 475 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 503 + { size_t len, len2, len3, maxlen; int elements; char *class_name; zend_class_entry *ce; zend_class_entry **pce; int incomplete_class = 0; - + int custom_object = 0; +/* */ zval *user_func; zval *retval_ptr; zval **args[1]; zval *arg_func_name; + + if(*start == 'C') { + custom_object = 1; + } INIT_PZVAL(*rval); len2 = len = parse_uiv(start + 2); @@ -579,8 +600,14 @@ zval_ptr_dtor(&arg_func_name); break; } while (1); - + *p = YYCURSOR; + + if(custom_object) { + efree(class_name); + return object_custom(UNSERIALIZE_PASSTHRU, ce); + } + elements = object_common1(UNSERIALIZE_PASSTHRU, ce); if (incomplete_class) { @@ -590,11 +617,9 @@ return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 271 "<stdout>" yy24: yych = *++YYCURSOR; if(yych <= ','){ if(yych != '+') goto yy2; - goto yy25; } else { if(yych <= '-') goto yy25; if(yych <= '/') goto yy2; @@ -604,30 +629,24 @@ yy25: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych >= ':') goto yy2; - goto yy26; yy26: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy27; yy27: if(yych <= '/') goto yy2; if(yych <= '9') goto yy26; if(yych >= ';') goto yy2; - goto yy28; yy28: yych = *++YYCURSOR; if(yych != '"') goto yy2; - goto yy29; -yy29: ++YYCURSOR; - goto yy30; +yy29: yych = *++YYCURSOR; yy30: -#line 467 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 495 + { INIT_PZVAL(*rval); return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 309 "<stdout>" yy31: yych = *++YYCURSOR; if(yych == '+') goto yy32; if(yych <= '/') goto yy2; @@ -636,23 +655,18 @@ yy32: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych >= ':') goto yy2; - goto yy33; yy33: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy34; yy34: if(yych <= '/') goto yy2; if(yych <= '9') goto yy33; if(yych >= ';') goto yy2; - goto yy35; yy35: yych = *++YYCURSOR; if(yych != '{') goto yy2; - goto yy36; -yy36: ++YYCURSOR; - goto yy37; +yy36: yych = *++YYCURSOR; yy37: -#line 449 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 477 + { int elements = parse_iv(start + 2); *p = YYCURSOR; @@ -669,7 +683,6 @@ return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 352 "<stdout>" yy38: yych = *++YYCURSOR; if(yych == '+') goto yy39; if(yych <= '/') goto yy2; @@ -678,23 +691,18 @@ yy39: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych >= ':') goto yy2; - goto yy40; yy40: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy41; yy41: if(yych <= '/') goto yy2; if(yych <= '9') goto yy40; if(yych >= ';') goto yy2; - goto yy42; yy42: yych = *++YYCURSOR; if(yych != '"') goto yy2; - goto yy43; -yy43: ++YYCURSOR; - goto yy44; +yy43: yych = *++YYCURSOR; yy44: -#line 421 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 449 + { size_t len, maxlen; char *str; @@ -721,7 +729,6 @@ ZVAL_STRINGL(*rval, str, len, 1); return 1; } -#line 405 "<stdout>" yy45: yych = *++YYCURSOR; if(yych <= '/'){ if(yych <= ','){ @@ -739,7 +746,6 @@ goto yy48; } else { if(yych != 'N') goto yy2; - goto yy46; } } yy46: yych = *++YYCURSOR; @@ -752,7 +758,6 @@ } else { if(yych <= '9') goto yy50; if(yych != 'I') goto yy2; - goto yy48; } yy48: yych = *++YYCURSOR; if(yych == 'N') goto yy64; @@ -761,11 +766,9 @@ if(yych == '.') goto yy52; if(yych <= '/') goto yy2; if(yych >= ':') goto yy2; - goto yy50; yy50: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy51; yy51: if(yych <= ':'){ if(yych <= '.'){ if(yych <= '-') goto yy2; @@ -788,16 +791,13 @@ yy52: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych >= ':') goto yy2; - goto yy53; yy53: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy54; yy54: if(yych <= ';'){ if(yych <= '/') goto yy2; if(yych <= '9') goto yy53; if(yych <= ':') goto yy2; - goto yy55; } else { if(yych <= 'E'){ if(yych <= 'D') goto yy2; @@ -807,21 +807,18 @@ goto yy2; } } -yy55: ++YYCURSOR; - goto yy56; +yy55: yych = *++YYCURSOR; yy56: -#line 414 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 442 + { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_DOUBLE(*rval, zend_strtod(start + 2, NULL)); return 1; } -#line 503 "<stdout>" yy57: yych = *++YYCURSOR; if(yych <= ','){ if(yych != '+') goto yy2; - goto yy58; } else { if(yych <= '-') goto yy58; if(yych <= '/') goto yy2; @@ -836,12 +833,10 @@ if(yych <= '-') goto yy61; if(yych <= '/') goto yy2; if(yych >= ':') goto yy2; - goto yy59; } yy59: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy60; yy60: if(yych <= '/') goto yy2; if(yych <= '9') goto yy59; if(yych == ';') goto yy55; @@ -853,7 +848,6 @@ yy62: ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; - goto yy63; yy63: if(yych <= ';'){ if(yych <= '/') goto yy2; if(yych <= '9') goto yy62; @@ -870,15 +864,12 @@ } yy64: yych = *++YYCURSOR; if(yych != 'F') goto yy2; - goto yy65; yy65: yych = *++YYCURSOR; if(yych != ';') goto yy2; - goto yy66; -yy66: ++YYCURSOR; - goto yy67; +yy66: yych = *++YYCURSOR; yy67: -#line 399 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 427 + { *p = YYCURSOR; INIT_PZVAL(*rval); @@ -892,14 +883,12 @@ return 1; } -#line 580 "<stdout>" yy68: yych = *++YYCURSOR; if(yych == 'N') goto yy65; goto yy2; yy69: yych = *++YYCURSOR; if(yych <= ','){ if(yych != '+') goto yy2; - goto yy70; } else { if(yych <= '-') goto yy70; if(yych <= '/') goto yy2; @@ -909,59 +898,47 @@ yy70: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych >= ':') goto yy2; - goto yy71; yy71: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy72; yy72: if(yych <= '/') goto yy2; if(yych <= '9') goto yy71; if(yych != ';') goto yy2; - goto yy73; -yy73: ++YYCURSOR; - goto yy74; +yy73: yych = *++YYCURSOR; yy74: -#line 392 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 420 + { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } -#line 617 "<stdout>" yy75: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych >= '2') goto yy2; - goto yy76; yy76: yych = *++YYCURSOR; if(yych != ';') goto yy2; - goto yy77; -yy77: ++YYCURSOR; - goto yy78; +yy77: yych = *++YYCURSOR; yy78: -#line 385 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 413 + { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } -#line 635 "<stdout>" -yy79: ++YYCURSOR; - goto yy80; +yy79: yych = *++YYCURSOR; yy80: -#line 378 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 406 + { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } -#line 646 "<stdout>" yy81: yych = *++YYCURSOR; if(yych <= ','){ if(yych != '+') goto yy2; - goto yy82; } else { if(yych <= '-') goto yy82; if(yych <= '/') goto yy2; @@ -971,20 +948,16 @@ yy82: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych >= ':') goto yy2; - goto yy83; yy83: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy84; yy84: if(yych <= '/') goto yy2; if(yych <= '9') goto yy83; if(yych != ';') goto yy2; - goto yy85; -yy85: ++YYCURSOR; - goto yy86; +yy85: yych = *++YYCURSOR; yy86: -#line 355 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 383 + { int id; *p = YYCURSOR; @@ -1006,11 +979,9 @@ return 1; } -#line 696 "<stdout>" yy87: yych = *++YYCURSOR; if(yych <= ','){ if(yych != '+') goto yy2; - goto yy88; } else { if(yych <= '-') goto yy88; if(yych <= '/') goto yy2; @@ -1020,20 +991,16 @@ yy88: yych = *++YYCURSOR; if(yych <= '/') goto yy2; if(yych >= ':') goto yy2; - goto yy89; yy89: ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy90; yy90: if(yych <= '/') goto yy2; if(yych <= '9') goto yy89; if(yych != ';') goto yy2; - goto yy91; -yy91: ++YYCURSOR; - goto yy92; +yy91: yych = *++YYCURSOR; yy92: -#line 334 "/usr/src/php-cvs/ext/standard/var_unserializer.re" -{ +#line 362 + { int id; *p = YYCURSOR; @@ -1053,9 +1020,8 @@ return 1; } -#line 744 "<stdout>" } -#line 583 "/usr/src/php-cvs/ext/standard/var_unserializer.re" +#line 622 return 0; http://cvs.php.net/diff.php/php-src/ext/standard/var_unserializer.re?r1=1.41&r2=1.42&ty=u Index: php-src/ext/standard/var_unserializer.re diff -u php-src/ext/standard/var_unserializer.re:1.41 php-src/ext/standard/var_unserializer.re:1.42 --- php-src/ext/standard/var_unserializer.re:1.41 Mon Feb 14 15:58:22 2005 +++ php-src/ext/standard/var_unserializer.re Wed Feb 23 06:17:52 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.re,v 1.41 2005/02/14 20:58:22 helly Exp $ */ +/* $Id: var_unserializer.re,v 1.42 2005/02/23 11:17:52 stas Exp $ */ #include "php.h" #include "ext/standard/php_var.h" @@ -151,6 +151,7 @@ nv = [+-]? ([0-9]* "." [0-9]+|[0-9]+ "." [0-9]*); nvexp = (iv | nv) [eE] [+-]? iv; any = [\000-\277]; +object = [OC]; */ @@ -280,6 +281,33 @@ return 0; } +static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) +{ + int datalen; + + if(ce->unserialize == NULL) { + zend_error(E_WARNING, "Class %s has no unserializer", ce->name); + return 0; + } + + datalen = parse_iv2((*p) + 2, p); + + (*p) += 2; + + if((*p) + datalen >= max) { + zend_error(E_WARNING, "Unsifficient data for unserializing - %d required, %d present", datalen, max - (*p)); + return 0; + } + + if(ce->unserialize(rval, *p, datalen, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) { + return 0; + } + + (*p) += datalen; + + return finish_nested_data(UNSERIALIZE_PASSTHRU); +} + static inline int object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce) { int elements; @@ -472,18 +500,24 @@ object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -"O:" uiv ":" ["] { +object ":" uiv ":" ["] { size_t len, len2, len3, maxlen; int elements; char *class_name; zend_class_entry *ce; zend_class_entry **pce; int incomplete_class = 0; - + + int custom_object = 0; + zval *user_func; zval *retval_ptr; zval **args[1]; zval *arg_func_name; + + if(*start == 'C') { + custom_object = 1; + } INIT_PZVAL(*rval); len2 = len = parse_uiv(start + 2); @@ -560,8 +594,14 @@ zval_ptr_dtor(&arg_func_name); break; } while (1); - + *p = YYCURSOR; + + if(custom_object) { + efree(class_name); + return object_custom(UNSERIALIZE_PASSTHRU, ce); + } + elements = object_common1(UNSERIALIZE_PASSTHRU, ce); if (incomplete_class) {
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php