diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Zend/tests/bug70121.phpt | 9 | ||||
-rw-r--r-- | Zend/zend_exceptions.c | 45 | ||||
-rw-r--r-- | ext/date/php_date.c | 140 | ||||
-rw-r--r-- | ext/date/tests/bug53437_var3.phpt | 12 | ||||
-rw-r--r-- | ext/date/tests/bug53437_var5.phpt | 12 | ||||
-rwxr-xr-x | ext/openssl/openssl.c | 6 | ||||
-rw-r--r-- | ext/phar/phar_internal.h | 13 | ||||
-rw-r--r-- | ext/phar/phar_object.c | 50 | ||||
-rw-r--r-- | ext/phar/tests/bug70019.phpt | 22 | ||||
-rw-r--r-- | ext/phar/tests/bug70019.zip | bin | 0 -> 184 bytes | |||
-rw-r--r-- | ext/soap/php_http.c | 23 | ||||
-rw-r--r-- | ext/spl/spl_array.c | 93 | ||||
-rw-r--r-- | ext/spl/spl_dllist.c | 25 | ||||
-rw-r--r-- | ext/spl/spl_observer.c | 68 | ||||
-rw-r--r-- | ext/spl/tests/bug70068.phpt | 9 | ||||
-rw-r--r-- | ext/spl/tests/bug70166.phpt | 29 | ||||
-rw-r--r-- | ext/spl/tests/bug70168.phpt | 36 | ||||
-rw-r--r-- | ext/spl/tests/bug70169.phpt | 30 | ||||
-rw-r--r-- | ext/standard/tests/serialize/bug69152.phpt | 1 | ||||
-rw-r--r-- | ext/standard/tests/serialize/bug69793.phpt | 17 |
21 files changed, 444 insertions, 198 deletions
diff --git a/.gitignore b/.gitignore index 32d6ae03f8..46cddfb00a 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ *.tgz *.tar.gz *.tar.bz2 +*.tar.gz.asc +*.tar.bz2.asc .FBCIndex .FBCLockFolder .deps diff --git a/Zend/tests/bug70121.phpt b/Zend/tests/bug70121.phpt new file mode 100644 index 0000000000..9f8b7d6055 --- /dev/null +++ b/Zend/tests/bug70121.phpt @@ -0,0 +1,9 @@ +--TEST-- +Bug #70121 (unserialize() could lead to unexpected methods execution / NULL pointer deref) +--FILE-- +<?php +unserialize('O:12:"DateInterval":1:{s:4:"days";O:9:"Exception":7:{s:10:"'."\0".'*'."\0".'message";s:1:"x";s:17:"'."\0".'Exception'."\0".'string";s:1:"A";s:7:"'."\0".'*'."\0".'code";i:0;s:7:"'."\0".'*'."\0".'file";s:1:"a";s:7:"'."\0".'*'."\0".'line";i:1337;s:16:"'."\0".'Exception'."\0".'trace";a:0:{}s:19:"'."\0".'Exception'."\0".'previous";O:8:"stdClass":0:{}}}'); +?> +OK +--EXPECT-- +OK diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 06be9885d5..82b777a958 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -41,7 +41,7 @@ void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC) if (exception == add_previous || !add_previous || !exception) { return; } - if (Z_TYPE_P(add_previous) != IS_OBJECT && !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) { + if (Z_TYPE_P(add_previous) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) { zend_error(E_ERROR, "Cannot set non exception as previous exception"); return; } @@ -218,6 +218,33 @@ ZEND_METHOD(exception, __construct) } /* }}} */ +/* {{{ proto Exception::__wakeup() + Exception unserialize checks */ +#define CHECK_EXC_TYPE(name, type) \ + value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 0 TSRMLS_CC); \ + if(value && Z_TYPE_P(value) != type) { \ + zval *tmp; \ + MAKE_STD_ZVAL(tmp); \ + ZVAL_STRINGL(tmp, name, sizeof(name)-1, 1); \ + Z_OBJ_HANDLER_P(object, unset_property)(object, tmp, 0 TSRMLS_CC); \ + zval_ptr_dtor(&tmp); \ + } + +ZEND_METHOD(exception, __wakeup) +{ + zval *value; + zval *object = getThis(); + HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC); + CHECK_EXC_TYPE("message", IS_STRING); + CHECK_EXC_TYPE("string", IS_STRING); + CHECK_EXC_TYPE("code", IS_LONG); + CHECK_EXC_TYPE("file", IS_STRING); + CHECK_EXC_TYPE("line", IS_LONG); + CHECK_EXC_TYPE("trace", IS_ARRAY); + CHECK_EXC_TYPE("previous", IS_OBJECT); +} +/* }}} */ + /* {{{ proto ErrorException::__construct(string message, int code, int severity [, string filename [, int lineno [, Exception previous]]]) ErrorException constructor */ ZEND_METHOD(error_exception, __construct) @@ -586,7 +613,7 @@ ZEND_METHOD(exception, getTraceAsString) int res_len = 0, *len = &res_len, num = 0; DEFAULT_0_PARAMS; - + trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC); if(Z_TYPE_P(trace) != IS_ARRAY) { RETURN_FALSE; @@ -602,8 +629,8 @@ ZEND_METHOD(exception, getTraceAsString) TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); efree(s_tmp); - res[res_len] = '\0'; - RETURN_STRINGL(res, res_len, 0); + res[res_len] = '\0'; + RETURN_STRINGL(res, res_len, 0); } /* }}} */ @@ -640,15 +667,15 @@ ZEND_METHOD(exception, __toString) int len = 0; zend_fcall_info fci; zval fname; - + DEFAULT_0_PARAMS; - + str = estrndup("", 0); exception = getThis(); ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 1); - while (exception && Z_TYPE_P(exception) == IS_OBJECT) { + while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), default_exception_ce TSRMLS_CC)) { prev_str = str; _default_exception_get_entry(exception, "message", sizeof("message")-1, &message TSRMLS_CC); _default_exception_get_entry(exception, "file", sizeof("file")-1, &file TSRMLS_CC); @@ -658,6 +685,7 @@ ZEND_METHOD(exception, __toString) convert_to_string(&file); convert_to_long(&line); + trace = NULL; fci.size = sizeof(fci); fci.function_table = &Z_OBJCE_P(exception)->function_table; fci.function_name = &fname; @@ -670,7 +698,7 @@ ZEND_METHOD(exception, __toString) zend_call_function(&fci, NULL TSRMLS_CC); - if (Z_TYPE_P(trace) != IS_STRING) { + if (trace && Z_TYPE_P(trace) != IS_STRING) { zval_ptr_dtor(&trace); trace = NULL; } @@ -727,6 +755,7 @@ ZEND_END_ARG_INFO() const static zend_function_entry default_exception_functions[] = { ZEND_ME(exception, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_ME(exception, __construct, arginfo_exception___construct, ZEND_ACC_PUBLIC) + ZEND_ME(exception, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(exception, getMessage, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(exception, getCode, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(exception, getFile, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 08bfd0899b..dcd1b74fe4 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -548,7 +548,7 @@ static zend_object_handlers date_object_handlers_period; #define DATE_SET_CONTEXT \ zval *object; \ object = getThis(); \ - + #define DATE_FETCH_OBJECT \ php_date_obj *obj; \ DATE_SET_CONTEXT; \ @@ -715,7 +715,7 @@ PHP_RSHUTDOWN_FUNCTION(date) * RFC2822, Section 3.3: http://www.ietf.org/rfc/rfc2822.txt * FWS = ([*WSP CRLF] 1*WSP) / ; Folding white space * CFWS = *([FWS] comment) (([FWS] comment) / FWS) - * + * * date-time = [ day-of-week "," ] date FWS time [CFWS] * day-of-week = ([FWS] day-name) * day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun" @@ -737,19 +737,19 @@ PHP_RSHUTDOWN_FUNCTION(date) * date-fullyear = 4DIGIT * date-month = 2DIGIT ; 01-12 * date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on month/year - * + * * time-hour = 2DIGIT ; 00-23 * time-minute = 2DIGIT ; 00-59 * time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second rules - * + * * time-secfrac = "." 1*DIGIT * time-numoffset = ("+" / "-") time-hour ":" time-minute * time-offset = "Z" / time-numoffset - * + * * partial-time = time-hour ":" time-minute ":" time-second [time-secfrac] * full-date = date-fullyear "-" date-month "-" date-mday * full-time = partial-time time-offset - * + * * date-time = full-date "T" full-time */ #define DATE_FORMAT_RFC3339 "Y-m-d\\TH:i:sP" @@ -839,7 +839,7 @@ PHP_MSHUTDOWN_FUNCTION(date) PHP_MINFO_FUNCTION(date) { const timelib_tzdb *tzdb = DATE_TIMEZONEDB; - + php_info_print_table_start(); php_info_print_table_row(2, "date/time support", "enabled"); php_info_print_table_row(2, "\"Olson\" Timezone Database Version", tzdb->version); @@ -991,8 +991,8 @@ char *php_date_full_day_name(timelib_sll y, timelib_sll m, timelib_sll d) timelib_sll day_of_week = timelib_day_of_week(y, m, d); if (day_of_week < 0) { return "Unknown"; - } - return day_full_names[day_of_week]; + } + return day_full_names[day_of_week]; } char *php_date_short_day_name(timelib_sll y, timelib_sll m, timelib_sll d) @@ -1000,8 +1000,8 @@ char *php_date_short_day_name(timelib_sll y, timelib_sll m, timelib_sll d) timelib_sll day_of_week = timelib_day_of_week(y, m, d); if (day_of_week < 0) { return "Unknown"; - } - return day_short_names[day_of_week]; + } + return day_short_names[day_of_week]; } /* }}} */ @@ -1033,7 +1033,7 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca offset->leap_secs = 0; offset->is_dst = 0; offset->abbr = malloc(9); /* GMT�xxxx\0 */ - snprintf(offset->abbr, 9, "GMT%c%02d%02d", + snprintf(offset->abbr, 9, "GMT%c%02d%02d", localtime ? ((offset->offset < 0) ? '-' : '+') : '+', localtime ? abs(offset->offset / 3600) : 0, localtime ? abs((offset->offset % 3600) / 60) : 0 ); @@ -1079,7 +1079,7 @@ static char *date_format(char *format, int format_len, timelib_time *t, int loca case 'a': length = slprintf(buffer, 32, "%s", t->h >= 12 ? "pm" : "am"); break; case 'A': length = slprintf(buffer, 32, "%s", t->h >= 12 ? "PM" : "AM"); break; case 'B': { - int retval = (((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10) / 864); + int retval = (((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10) / 864); while (retval < 0) { retval += 1000; } @@ -1179,7 +1179,7 @@ static void php_date(INTERNAL_FUNCTION_PARAMETERS, int localtime) } string = php_format_date(format, format_len, ts, localtime TSRMLS_CC); - + RETVAL_STRING(string, 0); } /* }}} */ @@ -1203,7 +1203,7 @@ PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localt } string = date_format(format, format_len, t, localtime); - + timelib_time_dtor(t); return string; } @@ -1244,7 +1244,7 @@ PHPAPI int php_idate(char format, time_t ts, int localtime TSRMLS_DC) offset->leap_secs = 0; offset->is_dst = t->dst; offset->abbr = malloc(9); /* GMT�xxxx\0 */ - snprintf(offset->abbr, 9, "GMT%c%02d%02d", + snprintf(offset->abbr, 9, "GMT%c%02d%02d", !localtime ? ((offset->offset < 0) ? '-' : '+') : '+', !localtime ? abs(offset->offset / 3600) : 0, !localtime ? abs((offset->offset % 3600) / 60) : 0 ); @@ -1276,7 +1276,7 @@ PHPAPI int php_idate(char format, time_t ts, int localtime TSRMLS_DC) /* Swatch Beat a.k.a. Internet Time */ case 'B': - retval = (((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10) / 864); + retval = (((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10) / 864); while (retval < 0) { retval += 1000; } @@ -1328,7 +1328,7 @@ PHP_FUNCTION(idate) char *format; int format_len; long ts = 0; - int ret; + int ret; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &ts) == FAILURE) { RETURN_FALSE; @@ -1356,7 +1356,7 @@ PHP_FUNCTION(idate) PHPAPI void php_date_set_tzdb(timelib_tzdb *tzdb) { const timelib_tzdb *builtin = timelib_builtin_db(); - + if (php_version_compare(tzdb->version, builtin->version) > 0) { php_date_global_timezone_db = tzdb; php_date_global_timezone_db_enabled = 1; @@ -1428,7 +1428,7 @@ PHP_FUNCTION(strtotime) } if (!time_len) { - timelib_time_dtor(now); + timelib_time_dtor(now); RETURN_FALSE; } @@ -1869,7 +1869,7 @@ static void date_period_it_current_data(zend_object_iterator *iter, zval ***data if (it_time->tz_info) { newdateobj->time->tz_info = it_time->tz_info; } - + *data = &iterator->current; } /* }}} */ @@ -2037,13 +2037,13 @@ static inline zend_object_value date_object_new_date_ex(zend_class_entry *class_ if (ptr) { *ptr = intern; } - + zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - + retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_date, NULL TSRMLS_CC); retval.handlers = &date_object_handlers_date; - + return retval; } @@ -2057,12 +2057,12 @@ static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC) php_date_obj *new_obj = NULL; php_date_obj *old_obj = (php_date_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC); zend_object_value new_ov = date_object_new_date_ex(old_obj->std.ce, &new_obj TSRMLS_CC); - + zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC); if (!old_obj->time) { return new_ov; } - + /* this should probably moved to a new `timelib_time *timelime_time_clone(timelib_time *)` */ new_obj->time = timelib_time_ctor(); *new_obj->time = *old_obj->time; @@ -2072,7 +2072,7 @@ static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC) if (old_obj->time->tz_info) { new_obj->time->tz_info = old_obj->time->tz_info; } - + return new_ov; } @@ -2094,10 +2094,10 @@ static int date_object_compare_date(zval *d1, zval *d2 TSRMLS_DC) if (!o2->time->sse_uptodate) { timelib_update_ts(o2->time, o2->time->tz_info); } - + return (o1->time->sse == o2->time->sse) ? 0 : ((o1->time->sse < o2->time->sse) ? -1 : 1); } - + return 1; } @@ -2174,10 +2174,10 @@ static inline zend_object_value date_object_new_timezone_ex(zend_class_entry *cl zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - + retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_timezone, NULL TSRMLS_CC); retval.handlers = &date_object_handlers_timezone; - + return retval; } @@ -2191,12 +2191,12 @@ static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC) php_timezone_obj *new_obj = NULL; php_timezone_obj *old_obj = (php_timezone_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC); zend_object_value new_ov = date_object_new_timezone_ex(old_obj->std.ce, &new_obj TSRMLS_CC); - + zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC); if (!old_obj->initialized) { return new_ov; } - + new_obj->type = old_obj->type; new_obj->initialized = 1; switch (new_obj->type) { @@ -2212,7 +2212,7 @@ static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC) new_obj->tzi.z.abbr = old_obj->tzi.z.abbr; break; } - + return new_ov; } @@ -2229,10 +2229,10 @@ static inline zend_object_value date_object_new_interval_ex(zend_class_entry *cl zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - + retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_interval, NULL TSRMLS_CC); retval.handlers = &date_object_handlers_interval; - + return retval; } @@ -2246,7 +2246,7 @@ static zend_object_value date_object_clone_interval(zval *this_ptr TSRMLS_DC) php_interval_obj *new_obj = NULL; php_interval_obj *old_obj = (php_interval_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC); zend_object_value new_ov = date_object_new_interval_ex(old_obj->std.ce, &new_obj TSRMLS_CC); - + zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC); /** FIX ME ADD CLONE STUFF **/ @@ -2318,10 +2318,10 @@ static inline zend_object_value date_object_new_period_ex(zend_class_entry *clas zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - + retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_period, NULL TSRMLS_CC); retval.handlers = &date_object_handlers_period; - + return retval; } @@ -2335,7 +2335,7 @@ static zend_object_value date_object_clone_period(zval *this_ptr TSRMLS_DC) php_period_obj *new_obj = NULL; php_period_obj *old_obj = (php_period_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC); zend_object_value new_ov = date_object_new_period_ex(old_obj->std.ce, &new_obj TSRMLS_CC); - + zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC); /** FIX ME ADD CLONE STUFF **/ @@ -2421,7 +2421,7 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int type = TIMELIB_ZONETYPE_ID, new_dst = 0; char *new_abbr = NULL; timelib_sll new_offset; - + if (dateobj->time) { timelib_time_dtor(dateobj->time); } @@ -2710,7 +2710,7 @@ void php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAMETERS, timelib_time * PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(hour, h); PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(minute, i); PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(second, s); - + if (parsed_time->f == -99999) { add_assoc_bool(return_value, "fraction", 0); } else { @@ -2777,7 +2777,7 @@ PHP_FUNCTION(date_parse) int date_len; struct timelib_error_container *error; timelib_time *parsed_time; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &date, &date_len) == FAILURE) { RETURN_FALSE; } @@ -2796,7 +2796,7 @@ PHP_FUNCTION(date_parse_from_format) int date_len, format_len; struct timelib_error_container *error; timelib_time *parsed_time; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &format, &format_len, &date, &date_len) == FAILURE) { RETURN_FALSE; } @@ -3123,7 +3123,7 @@ PHP_FUNCTION(date_isodate_set) memset(&dateobj->time->relative, 0, sizeof(dateobj->time->relative)); dateobj->time->relative.d = timelib_daynr_from_weeknr(y, w, d); dateobj->time->have_relative = 1; - + timelib_update_ts(dateobj->time, NULL); RETURN_ZVAL(object, 1, 0); @@ -3210,15 +3210,15 @@ PHP_FUNCTION(date_diff) static int timezone_initialize(timelib_tzinfo **tzi, /*const*/ char *tz TSRMLS_DC) { char *tzid; - + *tzi = NULL; - + if ((tzid = timelib_timezone_id_from_abbr(tz, -1, 0))) { *tzi = php_date_parse_tzfile(tzid, DATE_TIMEZONEDB TSRMLS_CC); } else { *tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB TSRMLS_CC); } - + if (*tzi) { return SUCCESS; } else { @@ -3260,7 +3260,7 @@ PHP_METHOD(DateTimeZone, __construct) timelib_tzinfo *tzi = NULL; php_timezone_obj *tzobj; zend_error_handling error_handling; - + zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len)) { if (SUCCESS == timezone_initialize(&tzi, tz TSRMLS_CC)) { @@ -3487,7 +3487,7 @@ static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *forma struct timelib_error_container *errors; timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors); - + if (errors->error_count > 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad format (%s)", format); retval = FAILURE; @@ -3646,7 +3646,7 @@ PHP_METHOD(DateInterval, __construct) php_interval_obj *diobj; timelib_rel_time *reltime; zend_error_handling error_handling; - + zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &interval_string, &interval_string_length) == SUCCESS) { if (date_interval_initialize(&reltime, interval_string, interval_string_length TSRMLS_CC) == SUCCESS) { @@ -3669,8 +3669,7 @@ static int php_date_interval_initialize_from_hash(zval **return_value, php_inter #define PHP_DATE_INTERVAL_READ_PROPERTY(element, member, itype, def) \ do { \ zval **z_arg = NULL; \ - if (zend_hash_find(myht, element, strlen(element) + 1, (void**) &z_arg) == SUCCESS) { \ - convert_to_long(*z_arg); \ + if (zend_hash_find(myht, element, strlen(element) + 1, (void**) &z_arg) == SUCCESS && Z_TYPE_PP(z_arg) == IS_LONG) { \ (*intobj)->diff->member = (itype)Z_LVAL_PP(z_arg); \ } else { \ (*intobj)->diff->member = (itype)def; \ @@ -3681,8 +3680,15 @@ static int php_date_interval_initialize_from_hash(zval **return_value, php_inter do { \ zval **z_arg = NULL; \ if (zend_hash_find(myht, element, strlen(element) + 1, (void**) &z_arg) == SUCCESS) { \ - convert_to_string(*z_arg); \ - DATE_A64I((*intobj)->diff->member, Z_STRVAL_PP(z_arg)); \ + if (Z_TYPE_PP(z_arg) == IS_STRING) { \ + DATE_A64I((*intobj)->diff->member, Z_STRVAL_PP(z_arg)); \ + } else if (Z_TYPE_PP(z_arg) == IS_LONG || Z_TYPE_PP(z_arg) == IS_BOOL) { \ + (*intobj)->diff->member = (timelib_sll)Z_LVAL_PP(z_arg); \ + } else if (Z_TYPE_PP(z_arg) == IS_DOUBLE) { \ + (*intobj)->diff->member = (timelib_sll)Z_DVAL_PP(z_arg); \ + } else { \ + (*intobj)->diff->member = -1LL; \ + } \ } else { \ (*intobj)->diff->member = -1LL; \ } \ @@ -3860,7 +3866,7 @@ static int date_period_initialize(timelib_time **st, timelib_time **et, timelib_ struct timelib_error_container *errors; timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors); - + if (errors->error_count > 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad format (%s)", format); retval = FAILURE; @@ -3889,7 +3895,7 @@ PHP_METHOD(DatePeriod, __construct) int isostr_len = 0; timelib_time *clone; zend_error_handling error_handling; - + zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_date, &interval, date_ce_interval, &recurrences, &options) == FAILURE) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_date, &interval, date_ce_interval, &end, date_ce_date, &options) == FAILURE) { @@ -4002,7 +4008,7 @@ PHP_FUNCTION(timezone_identifiers_list) tzdb = DATE_TIMEZONEDB; item_count = tzdb->index_size; table = tzdb->index; - + array_init(return_value); for (i = 0; i < item_count; ++i) { @@ -4036,7 +4042,7 @@ PHP_FUNCTION(timezone_abbreviations_list) { const timelib_tz_lookup_table *table, *entry; zval *element, **abbr_array_pp, *abbr_array; - + table = timelib_timezone_abbreviations_list(); array_init(return_value); entry = table; @@ -4112,11 +4118,11 @@ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, int calc_su timelib_time *t; timelib_tzinfo *tzi; char *retstr; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ldddd", &time, &retformat, &latitude, &longitude, &zenith, &gmt_offset) == FAILURE) { RETURN_FALSE; } - + switch (ZEND_NUM_ARGS()) { case 1: retformat = SUNFUNCS_RET_STRING; @@ -4160,7 +4166,7 @@ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, int calc_su timelib_unixtime2local(t, time); rs = timelib_astro_rise_set_altitude(t, longitude, latitude, altitude, 1, &h_rise, &h_set, &rise, &set, &transit); timelib_time_dtor(t); - + if (rs != 0) { RETURN_FALSE; } @@ -4214,7 +4220,7 @@ PHP_FUNCTION(date_sun_info) timelib_sll rise, set, transit; int dummy; double ddummy; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ldd", &time, &latitude, &longitude) == FAILURE) { RETURN_FALSE; } @@ -4228,7 +4234,7 @@ PHP_FUNCTION(date_sun_info) /* Setup */ t2 = timelib_time_ctor(); array_init(return_value); - + /* Get sun up/down and transit */ rs = timelib_astro_rise_set_altitude(t, longitude, latitude, -35.0/60, 1, &ddummy, &ddummy, &rise, &set, &transit); switch (rs) { @@ -4372,7 +4378,7 @@ static HashTable *date_object_get_properties_period(zval *object TSRMLS_DC) ZVAL_NULL(zv); } zend_hash_update(props, "interval", sizeof("interval"), &zv, sizeof(zv), NULL); - + /* converted to larger type (int->long); must check when unserializing */ MAKE_STD_ZVAL(zv); ZVAL_LONG(zv, (long) period_obj->recurrences); @@ -4454,7 +4460,7 @@ static int php_date_period_initialize_from_hash(php_period_obj *period_obj, Hash } period_obj->initialized = 1; - + return 1; } @@ -4471,7 +4477,7 @@ PHP_METHOD(DatePeriod, __set_state) } myht = Z_ARRVAL_P(array); - + object_init_ex(return_value, date_ce_period); period_obj = zend_object_store_get_object(return_value TSRMLS_CC); if (!php_date_period_initialize_from_hash(period_obj, myht TSRMLS_CC)) { diff --git a/ext/date/tests/bug53437_var3.phpt b/ext/date/tests/bug53437_var3.phpt index 82b90f559b..d3a0652ee6 100644 --- a/ext/date/tests/bug53437_var3.phpt +++ b/ext/date/tests/bug53437_var3.phpt @@ -14,17 +14,17 @@ var_dump($di); --EXPECTF-- object(DateInterval)#%d (15) { ["y"]=> - int(2) + int(-1) ["m"]=> - int(0) + int(-1) ["d"]=> - int(0) + int(-1) ["h"]=> - int(6) + int(-1) ["i"]=> - int(8) + int(-1) ["s"]=> - int(0) + int(-1) ["weekday"]=> int(10) ["weekday_behavior"]=> diff --git a/ext/date/tests/bug53437_var5.phpt b/ext/date/tests/bug53437_var5.phpt index e95fcdae96..e9b3a3cd82 100644 --- a/ext/date/tests/bug53437_var5.phpt +++ b/ext/date/tests/bug53437_var5.phpt @@ -14,17 +14,17 @@ var_dump($di); --EXPECTF-- object(DateInterval)#%d (15) { ["y"]=> - int(2) + int(-1) ["m"]=> - int(0) + int(-1) ["d"]=> - int(0) + int(-1) ["h"]=> - int(6) + int(-1) ["i"]=> - int(8) + int(-1) ["s"]=> - int(0) + int(-1) ["weekday"]=> int(10) ["weekday_behavior"]=> diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 216a56a59f..c0e3d8a981 100755 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -5070,7 +5070,6 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) long buffer_length; unsigned char *buffer = NULL; zval *zstrong_result_returned = NULL; - int strong_result = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z", &buffer_length, &zstrong_result_returned) == FAILURE) { return; @@ -5088,7 +5087,6 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) buffer = emalloc(buffer_length + 1); #ifdef PHP_WIN32 - strong_result = 1; /* random/urandom equivalent on Windows */ if (php_win32_get_random_bytes(buffer, (size_t) buffer_length) == FAILURE) { efree(buffer); @@ -5098,7 +5096,7 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) RETURN_FALSE; } #else - if ((strong_result = RAND_pseudo_bytes(buffer, buffer_length)) < 0) { + if (RAND_bytes(buffer, buffer_length) <= 0) { efree(buffer); if (zstrong_result_returned) { ZVAL_BOOL(zstrong_result_returned, 0); @@ -5111,7 +5109,7 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) RETVAL_STRINGL((char *)buffer, buffer_length, 0); if (zstrong_result_returned) { - ZVAL_BOOL(zstrong_result_returned, strong_result); + ZVAL_BOOL(zstrong_result_returned, 1); } } /* }}} */ diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 84282d2a8f..3d8c8e62ad 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -618,13 +618,16 @@ static inline void phar_set_inode(phar_entry_info *entry TSRMLS_DC) /* {{{ */ { char tmp[MAXPATHLEN]; int tmp_len; - size_t len; + size_t len1, len2; tmp_len = MIN(MAXPATHLEN, entry->filename_len + entry->phar->fname_len); - len = MIN(entry->phar->fname_len, tmp_len); - memcpy(tmp, entry->phar->fname, len); - len = MIN(tmp_len - len, entry->filename_len); - memcpy(tmp + entry->phar->fname_len, entry->filename, len); + + len1 = MIN(entry->phar->fname_len, tmp_len); + memcpy(tmp, entry->phar->fname, len1); + + len2 = MIN(tmp_len - len1, entry->filename_len); + memcpy(tmp + len1, entry->filename, len2); + entry->inode = (unsigned short)zend_get_hash_value(tmp, tmp_len); } /* }}} */ diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 8cfe0c8228..b652181869 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -4200,6 +4200,9 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * char *fullpath; const char *slash; mode_t mode; + cwd_state new_state; + char *filename; + size_t filename_len; if (entry->is_mounted) { /* silently ignore mounted entries */ @@ -4209,8 +4212,39 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * if (entry->filename_len >= sizeof(".phar")-1 && !memcmp(entry->filename, ".phar", sizeof(".phar")-1)) { return SUCCESS; } + /* strip .. from path and restrict it to be under dest directory */ + new_state.cwd = (char*)malloc(2); + new_state.cwd[0] = DEFAULT_SLASH; + new_state.cwd[1] = '\0'; + new_state.cwd_length = 1; + if (virtual_file_ex(&new_state, entry->filename, NULL, CWD_EXPAND TSRMLS_CC) != 0 || + new_state.cwd_length <= 1) { + if (EINVAL == errno && entry->filename_len > 50) { + char *tmp = estrndup(entry->filename, 50); + spprintf(error, 4096, "Cannot extract \"%s...\" to \"%s...\", extracted filename is too long for filesystem", tmp, dest); + efree(tmp); + } else { + spprintf(error, 4096, "Cannot extract \"%s\", internal error", entry->filename); + } + free(new_state.cwd); + return FAILURE; + } + filename = new_state.cwd + 1; + filename_len = new_state.cwd_length - 1; +#ifdef PHP_WIN32 + /* unixify the path back, otherwise non zip formats might be broken */ + { + int cnt = filename_len; + + do { + if ('\\' == filename[cnt]) { + filename[cnt] = '/'; + } + } while (cnt-- >= 0); + } +#endif - len = spprintf(&fullpath, 0, "%s/%s", dest, entry->filename); + len = spprintf(&fullpath, 0, "%s/%s", dest, filename); if (len >= MAXPATHLEN) { char *tmp; @@ -4224,18 +4258,21 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * spprintf(error, 4096, "Cannot extract \"%s\" to \"%s...\", extracted filename is too long for filesystem", entry->filename, fullpath); } efree(fullpath); + free(new_state.cwd); return FAILURE; } if (!len) { spprintf(error, 4096, "Cannot extract \"%s\", internal error", entry->filename); efree(fullpath); + free(new_state.cwd); return FAILURE; } if (PHAR_OPENBASEDIR_CHECKPATH(fullpath)) { spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", openbasedir/safe mode restrictions in effect", entry->filename, fullpath); efree(fullpath); + free(new_state.cwd); return FAILURE; } @@ -4243,14 +4280,15 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * if (!overwrite && SUCCESS == php_stream_stat_path(fullpath, &ssb)) { spprintf(error, 4096, "Cannot extract \"%s\" to \"%s\", path already exists", entry->filename, fullpath); efree(fullpath); + free(new_state.cwd); return FAILURE; } /* perform dirname */ - slash = zend_memrchr(entry->filename, '/', entry->filename_len); + slash = zend_memrchr(filename, '/', filename_len); if (slash) { - fullpath[dest_len + (slash - entry->filename) + 1] = '\0'; + fullpath[dest_len + (slash - filename) + 1] = '\0'; } else { fullpath[dest_len] = '\0'; } @@ -4260,23 +4298,27 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * if (!php_stream_mkdir(fullpath, entry->flags & PHAR_ENT_PERM_MASK, PHP_STREAM_MKDIR_RECURSIVE, NULL)) { spprintf(error, 4096, "Cannot extract \"%s\", could not create directory \"%s\"", entry->filename, fullpath); efree(fullpath); + free(new_state.cwd); return FAILURE; } } else { if (!php_stream_mkdir(fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL)) { spprintf(error, 4096, "Cannot extract \"%s\", could not create directory \"%s\"", entry->filename, fullpath); efree(fullpath); + free(new_state.cwd); return FAILURE; } } } if (slash) { - fullpath[dest_len + (slash - entry->filename) + 1] = '/'; + fullpath[dest_len + (slash - filename) + 1] = '/'; } else { fullpath[dest_len] = '/'; } + filename = NULL; + free(new_state.cwd); /* it is a standalone directory, job done */ if (entry->is_dir) { efree(fullpath); diff --git a/ext/phar/tests/bug70019.phpt b/ext/phar/tests/bug70019.phpt new file mode 100644 index 0000000000..d7976a180d --- /dev/null +++ b/ext/phar/tests/bug70019.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #70019 Files extracted from archive may be placed outside of destination directory +--FILE-- +<?php +$dir = __DIR__."/bug70019"; +$phar = new PharData(__DIR__."/bug70019.zip"); +if(!is_dir($dir)) { + mkdir($dir); +} +$phar->extractTo($dir); +var_dump(file_exists("$dir/ThisIsATestFile.txt")); +?> +===DONE=== +--CLEAN-- +<?php +$dir = __DIR__."/bug70019"; +unlink("$dir/ThisIsATestFile.txt"); +rmdir($dir); +?> +--EXPECTF-- +bool(true) +===DONE=== diff --git a/ext/phar/tests/bug70019.zip b/ext/phar/tests/bug70019.zip Binary files differnew file mode 100644 index 0000000000..faf152df7e --- /dev/null +++ b/ext/phar/tests/bug70019.zip diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 8c5082ca30..8dc6e45ef8 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -313,7 +313,7 @@ int make_http_soap_request(zval *this_ptr, int kind = Z_LVAL_PP(tmp) & SOAP_COMPRESSION_DEFLATE; if (level > 9) {level = 9;} - + if ((Z_LVAL_PP(tmp) & SOAP_COMPRESSION_ACCEPT) != 0) { smart_str_append_const(&soap_headers_z,"Accept-Encoding: gzip, deflate\r\n"); } @@ -372,7 +372,7 @@ int make_http_soap_request(zval *this_ptr, context = php_stream_context_from_zval(*tmp, 0); } - if (context && + if (context && php_stream_context_get_option(context, "http", "max_redirects", &tmp) == SUCCESS) { if (Z_TYPE_PP(tmp) != IS_STRING || !is_numeric_string(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), &redirect_max, NULL, 1)) { if (Z_TYPE_PP(tmp) == IS_LONG) @@ -470,7 +470,7 @@ try_again: add_property_resource(this_ptr, "httpurl", ret); /*zend_list_addref(ret);*/ - if (context && + if (context && php_stream_context_get_option(context, "http", "protocol_version", &tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_DOUBLE && Z_DVAL_PP(tmp) == 1.0) { @@ -528,7 +528,7 @@ try_again: smart_str_appendl(&soap_headers, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); smart_str_append_const(&soap_headers, "\r\n"); } - } else if (context && + } else if (context && php_stream_context_get_option(context, "http", "user_agent", &tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) { if (Z_STRLEN_PP(tmp) > 0) { @@ -670,7 +670,7 @@ try_again: PHP_MD5Update(&md5ctx, (unsigned char*)HA2, 32); PHP_MD5Final(hash, &md5ctx); make_digest(response, hash); - + smart_str_append_const(&soap_headers, "Authorization: Digest username=\""); smart_str_appendl(&soap_headers, Z_STRVAL_PP(login), Z_STRLEN_PP(login)); if (zend_hash_find(Z_ARRVAL_PP(digest), "realm", sizeof("realm"), (void **)&tmp) == SUCCESS && @@ -688,7 +688,7 @@ try_again: smart_str_appends(&soap_headers, phpurl->path); } else { smart_str_appendc(&soap_headers, '/'); - } + } if (phpurl->query) { smart_str_appendc(&soap_headers, '?'); smart_str_appends(&soap_headers, phpurl->query); @@ -759,18 +759,21 @@ try_again: zend_hash_internal_pointer_reset(Z_ARRVAL_PP(cookies)); smart_str_append_const(&soap_headers, "Cookie: "); for (i = 0; i < n; i++) { + ulong numindx; + int res = zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, &numindx, FALSE); zend_hash_get_current_data(Z_ARRVAL_PP(cookies), (void **)&data); - zend_hash_get_current_key(Z_ARRVAL_PP(cookies), &key, NULL, FALSE); - if (Z_TYPE_PP(data) == IS_ARRAY) { + if (res == HASH_KEY_IS_STRING && Z_TYPE_PP(data) == IS_ARRAY) { zval** value; if (zend_hash_index_find(Z_ARRVAL_PP(data), 0, (void**)&value) == SUCCESS && Z_TYPE_PP(value) == IS_STRING) { zval **tmp; if ((zend_hash_index_find(Z_ARRVAL_PP(data), 1, (void**)&tmp) == FAILURE || + Z_TYPE_PP(tmp) != IS_STRING || strncmp(phpurl->path?phpurl->path:"/",Z_STRVAL_PP(tmp),Z_STRLEN_PP(tmp)) == 0) && (zend_hash_index_find(Z_ARRVAL_PP(data), 2, (void**)&tmp) == FAILURE || + Z_TYPE_PP(tmp) != IS_STRING || in_domain(phpurl->host,Z_STRVAL_PP(tmp))) && (use_ssl || zend_hash_index_find(Z_ARRVAL_PP(data), 3, (void**)&tmp) == FAILURE)) { smart_str_appendl(&soap_headers, key, strlen(key)); @@ -997,7 +1000,7 @@ try_again: efree(connection); } } - } + } if (!get_http_body(stream, http_close, http_headers, &http_body, &http_body_size TSRMLS_CC)) { if (request != buf) {efree(request);} @@ -1048,7 +1051,7 @@ try_again: strcat(s, new_url->path); efree(new_url->path); new_url->path = s; - } + } } else { char *s = emalloc(strlen(new_url->path) + 2); s[0] = '/'; s[1] = 0; diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index ec9ce217d3..86608c0d52 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -309,7 +309,7 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object, if (!offset) { return &EG(uninitialized_zval_ptr); } - + if ((type == BP_VAR_W || type == BP_VAR_RW) && (ht->nApplyCount > 0)) { zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited"); return &EG(error_zval_ptr);; @@ -341,8 +341,8 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object, case IS_RESOURCE: zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(offset), Z_LVAL_P(offset)); case IS_DOUBLE: - case IS_BOOL: - case IS_LONG: + case IS_BOOL: + case IS_LONG: if (offset->type == IS_DOUBLE) { index = (long)Z_DVAL_P(offset); } else { @@ -386,7 +386,7 @@ static zval *spl_array_read_dimension_ex(int check_inherited, zval *object, zval } else { SEPARATE_ARG_IF_REF(offset); } - zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_get, "offsetGet", &rv, offset); + zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_get, "offsetGet", &rv, offset); zval_ptr_dtor(&offset); if (rv) { zval_ptr_dtor(&intern->retval); @@ -444,7 +444,7 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval zval_ptr_dtor(&offset); return; } - + if (!offset) { ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); if (ht->nApplyCount > 0) { @@ -467,8 +467,8 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval return; case IS_DOUBLE: case IS_RESOURCE: - case IS_BOOL: - case IS_LONG: + case IS_BOOL: + case IS_LONG: ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); if (ht->nApplyCount > 0) { zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited"); @@ -556,13 +556,13 @@ static void spl_array_unset_dimension_ex(int check_inherited, zval *object, zval obj->std.properties_table[property_info->offset] = NULL; } } - } + } } break; case IS_DOUBLE: case IS_RESOURCE: - case IS_BOOL: - case IS_LONG: + case IS_BOOL: + case IS_LONG: if (offset->type == IS_DOUBLE) { index = (long)Z_DVAL_P(offset); } else { @@ -608,7 +608,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o } return 0; } - + switch(Z_TYPE_P(offset)) { case IS_STRING: { @@ -627,9 +627,9 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o return 0; case IS_DOUBLE: case IS_RESOURCE: - case IS_BOOL: + case IS_BOOL: case IS_LONG: - { + { HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); if (offset->type == IS_DOUBLE) { index = (long)Z_DVAL_P(offset); @@ -727,7 +727,7 @@ void spl_array_iterator_append(zval *object, zval *append_value TSRMLS_DC) /* {{ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and is no longer an array"); return; } - + if (Z_TYPE_P(intern->array) == IS_OBJECT) { php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Cannot append properties to objects, use %s::offsetSet() instead", Z_OBJCE_P(object)->name); return; @@ -771,7 +771,7 @@ SPL_METHOD(Array, getArrayCopy) { zval *object = getThis(), *tmp; spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); - + array_init(return_value); zend_hash_copy(HASH_OF(return_value), spl_array_get_hash_table(intern, 0 TSRMLS_CC), (copy_ctor_func_t) zval_add_ref, &tmp, sizeof(zval*)); } /* }}} */ @@ -990,7 +990,7 @@ static void spl_array_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ efree(iterator); } /* }}} */ - + static int spl_array_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ { spl_array_it *iterator = (spl_array_it *)iter; @@ -1037,7 +1037,7 @@ static int spl_array_it_get_current_key(zend_object_iterator *iter, char **str_k if (spl_array_object_verify_pos_ex(object, aht, "ArrayIterator::current(): " TSRMLS_CC) == FAILURE) { return HASH_KEY_NON_EXISTANT; } - + return zend_hash_get_current_key_ex(aht, str_key, str_key_len, int_key, 1, &object->pos); } } @@ -1057,7 +1057,7 @@ static void spl_array_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::current(): Array was modified outside object and is no longer an array"); return; } - + if ((object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos_ex(object, aht TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::next(): Array was modified outside object and internal position is no longer valid"); } else { @@ -1115,7 +1115,7 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval **a if (just_array) { spl_array_object *other = (spl_array_object*)zend_object_store_get_object(*array TSRMLS_CC); ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK; - } + } ar_flags |= SPL_ARRAY_USE_OTHER; intern->array = *array; } else { @@ -1173,7 +1173,7 @@ zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object, iterator->intern.ce = ce; iterator->intern.value = NULL; iterator->object = array_object; - + return (zend_object_iterator*)iterator; } /* }}} */ @@ -1238,7 +1238,7 @@ SPL_METHOD(Array, getIteratorClass) { zval *object = getThis(); spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1253,11 +1253,11 @@ SPL_METHOD(Array, getFlags) { zval *object = getThis(); spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } - + RETURN_LONG(intern->ar_flags & ~SPL_ARRAY_INT_MASK); } /* }}} */ @@ -1273,7 +1273,7 @@ SPL_METHOD(Array, setFlags) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ar_flags) == FAILURE) { return; } - + intern->ar_flags = (intern->ar_flags & SPL_ARRAY_INT_MASK) | (ar_flags & ~SPL_ARRAY_INT_MASK); } /* }}} */ @@ -1287,7 +1287,7 @@ SPL_METHOD(Array, exchangeArray) array_init(return_value); zend_hash_copy(HASH_OF(return_value), spl_array_get_hash_table(intern, 0 TSRMLS_CC), (copy_ctor_func_t) zval_add_ref, &tmp, sizeof(zval*)); - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &array) == FAILURE) { return; } @@ -1305,7 +1305,7 @@ SPL_METHOD(Array, getIterator) spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); spl_array_object *iterator; HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1328,7 +1328,7 @@ SPL_METHOD(Array, rewind) { zval *object = getThis(); spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1361,9 +1361,9 @@ SPL_METHOD(Array, seek) if (position >= 0) { /* negative values are not supported */ spl_array_rewind(intern TSRMLS_CC); result = SUCCESS; - + while (position-- > 0 && (result = spl_array_next(intern TSRMLS_CC)) == SUCCESS); - + if (result == SUCCESS && zend_hash_has_more_elements_ex(aht, &intern->pos) == SUCCESS) { return; /* ok */ } @@ -1383,7 +1383,7 @@ int static spl_array_object_count_elements_helper(spl_array_object *intern, long } if (Z_TYPE_P(intern->array) == IS_OBJECT) { - /* We need to store the 'pos' since we'll modify it in the functions + /* We need to store the 'pos' since we'll modify it in the functions * we're going to call and which do not support 'pos' as parameter. */ pos = intern->pos; *count = 0; @@ -1427,7 +1427,7 @@ SPL_METHOD(Array, count) { long count; spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1443,11 +1443,11 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); zval *tmp, *arg = NULL; zval *retval_ptr = NULL; - + MAKE_STD_ZVAL(tmp); Z_TYPE_P(tmp) = IS_ARRAY; Z_ARRVAL_P(tmp) = aht; - + if (!use_arg) { aht->nApplyCount++; zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 1, tmp, NULL TSRMLS_CC); @@ -1524,7 +1524,7 @@ SPL_METHOD(Array, current) spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); zval **entry; HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1547,7 +1547,7 @@ SPL_METHOD(Array, key) if (zend_parse_parameters_none() == FAILURE) { return; } - + spl_array_iterator_key(getThis(), return_value TSRMLS_CC); } /* }}} */ @@ -1594,7 +1594,7 @@ SPL_METHOD(Array, next) spl_array_next_no_verify(intern, aht TSRMLS_CC); } -/* }}} */ +/* }}} */ /* {{{ proto bool ArrayIterator::valid() Check whether array contains more entries */ @@ -1623,7 +1623,7 @@ SPL_METHOD(Array, hasChildren) zval *object = getThis(), **entry; spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1647,7 +1647,7 @@ SPL_METHOD(Array, getChildren) zval *object = getThis(), **entry, *flags; spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1687,7 +1687,7 @@ SPL_METHOD(Array, serialize) php_serialize_data_t var_hash; smart_str buf = {0}; zval *flags; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1747,7 +1747,7 @@ SPL_METHOD(Array, unserialize) zval *pmembers, *pflags = NULL; HashTable *aht; long flags; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { return; } @@ -1774,13 +1774,12 @@ SPL_METHOD(Array, unserialize) ALLOC_INIT_ZVAL(pflags); if (!php_var_unserialize(&pflags, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pflags) != IS_LONG) { - zval_ptr_dtor(&pflags); goto outexcept; } + var_push_dtor(&var_hash, &pflags); --p; /* for ';' */ flags = Z_LVAL_P(pflags); - zval_ptr_dtor(&pflags); /* flags needs to be verified and we also need to verify whether the next * thing we get is ';'. After that we require an 'm' or somethign else * where 'm' stands for members and anything else should be an array. If @@ -1802,6 +1801,7 @@ SPL_METHOD(Array, unserialize) if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)) { goto outexcept; } + var_push_dtor(&var_hash, &intern->array); } if (*p != ';') { goto outexcept; @@ -1820,6 +1820,7 @@ SPL_METHOD(Array, unserialize) goto outexcept; } + var_push_dtor(&var_hash, &pmembers); /* copy members */ if (!intern->std.properties) { rebuild_object_properties(&intern->std); @@ -1830,10 +1831,16 @@ SPL_METHOD(Array, unserialize) /* done reading $serialized */ PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + if (pflags) { + zval_ptr_dtor(&pflags); + } return; outexcept: PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + if (pflags) { + zval_ptr_dtor(&pflags); + } zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); return; @@ -1982,7 +1989,7 @@ PHP_MINIT_FUNCTION(spl_array) REGISTER_SPL_IMPLEMENTS(ArrayIterator, Countable); memcpy(&spl_handler_ArrayIterator, &spl_handler_ArrayObject, sizeof(zend_object_handlers)); spl_ce_ArrayIterator->get_iterator = spl_array_get_iterator; - + REGISTER_SPL_SUB_CLASS_EX(RecursiveArrayIterator, ArrayIterator, spl_array_object_new, spl_funcs_RecursiveArrayIterator); REGISTER_SPL_IMPLEMENTS(RecursiveArrayIterator, RecursiveIterator); spl_ce_RecursiveArrayIterator->get_iterator = spl_array_get_iterator; diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index b5ddfc0f59..011d7a6e3c 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -500,7 +500,7 @@ static int spl_dllist_object_count_elements(zval *object, long *count TSRMLS_DC) *count = spl_ptr_llist_count(intern->llist); return SUCCESS; -} +} /* }}} */ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{{ */ @@ -571,7 +571,7 @@ SPL_METHOD(SplDoublyLinkedList, push) spl_ptr_llist_push(intern->llist, value TSRMLS_CC); RETURN_TRUE; -} +} /* }}} */ /* {{{ proto bool SplDoublyLinkedList::unshift(mixed $value) U @@ -614,7 +614,7 @@ SPL_METHOD(SplDoublyLinkedList, pop) } RETURN_ZVAL(value, 1, 1); -} +} /* }}} */ /* {{{ proto mixed SplDoublyLinkedList::shift() U @@ -637,7 +637,7 @@ SPL_METHOD(SplDoublyLinkedList, shift) } RETURN_ZVAL(value, 1, 1); -} +} /* }}} */ /* {{{ proto mixed SplDoublyLinkedList::top() U @@ -1051,7 +1051,7 @@ static void spl_dllist_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* SPL_METHOD(SplDoublyLinkedList, key) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1065,7 +1065,7 @@ SPL_METHOD(SplDoublyLinkedList, key) SPL_METHOD(SplDoublyLinkedList, prev) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1079,7 +1079,7 @@ SPL_METHOD(SplDoublyLinkedList, prev) SPL_METHOD(SplDoublyLinkedList, next) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1093,7 +1093,7 @@ SPL_METHOD(SplDoublyLinkedList, next) SPL_METHOD(SplDoublyLinkedList, valid) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1107,7 +1107,7 @@ SPL_METHOD(SplDoublyLinkedList, valid) SPL_METHOD(SplDoublyLinkedList, rewind) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1122,7 +1122,7 @@ SPL_METHOD(SplDoublyLinkedList, current) { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); spl_ptr_llist_element *element = intern->traverse_pointer; - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1177,7 +1177,7 @@ SPL_METHOD(SplDoublyLinkedList, serialize) } else { RETURN_NULL(); } - + } /* }}} */ /* {{{ proto void SplDoublyLinkedList::unserialize(string serialized) @@ -1190,7 +1190,7 @@ SPL_METHOD(SplDoublyLinkedList, unserialize) int buf_len; const unsigned char *p, *s; php_unserialize_data_t var_hash; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { return; } @@ -1209,6 +1209,7 @@ SPL_METHOD(SplDoublyLinkedList, unserialize) zval_ptr_dtor(&flags); goto error; } + var_push_dtor(&var_hash, &flags); intern->flags = Z_LVAL_P(flags); zval_ptr_dtor(&flags); diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index da9110bf14..5d94a3b7b3 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -99,9 +99,9 @@ void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */ spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object; zend_object_std_dtor(&intern->std TSRMLS_CC); - + zend_hash_destroy(&intern->storage); - + if (intern->debug_info != NULL) { zend_hash_destroy(intern->debug_info); efree(intern->debug_info); @@ -196,7 +196,7 @@ spl_SplObjectStorageElement* spl_object_storage_get(spl_SplObjectStorage *intern void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *this, zval *obj, zval *inf TSRMLS_DC) /* {{{ */ { spl_SplObjectStorageElement *pelement, element; - + int hash_len; char *hash = spl_object_storage_get_hash(intern, this, obj, &hash_len TSRMLS_CC); if (!hash) { @@ -232,7 +232,7 @@ int spl_object_storage_detach(spl_SplObjectStorage *intern, zval *this, zval *ob } ret = zend_hash_del(&intern->storage, hash, hash_len); spl_object_storage_free_hash(intern, hash); - + return ret; } /* }}}*/ @@ -372,7 +372,7 @@ static HashTable *spl_object_storage_get_gc(zval *obj, zval ***table, int *n TSR **gcdata_arr_pp; props = std_object_handlers.get_properties(obj TSRMLS_CC); - + *table = NULL; *n = 0; @@ -492,7 +492,7 @@ SPL_METHOD(SplObjectStorage, getHash) hash = emalloc(33); php_spl_object_hash(obj, hash TSRMLS_CC); - + RETVAL_STRING(hash, 0); } /* }}} */ @@ -621,11 +621,11 @@ SPL_METHOD(SplObjectStorage, contains) SPL_METHOD(SplObjectStorage, count) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } - + RETURN_LONG(zend_hash_num_elements(&intern->storage)); } /* }}} */ @@ -634,11 +634,11 @@ SPL_METHOD(SplObjectStorage, count) SPL_METHOD(SplObjectStorage, rewind) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } - + zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); intern->index = 0; } /* }}} */ @@ -648,11 +648,11 @@ SPL_METHOD(SplObjectStorage, rewind) SPL_METHOD(SplObjectStorage, valid) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } - + RETURN_BOOL(zend_hash_has_more_elements_ex(&intern->storage, &intern->pos) == SUCCESS); } /* }}} */ @@ -661,11 +661,11 @@ SPL_METHOD(SplObjectStorage, valid) SPL_METHOD(SplObjectStorage, key) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } - + RETURN_LONG(intern->index); } /* }}} */ @@ -675,11 +675,11 @@ SPL_METHOD(SplObjectStorage, current) { spl_SplObjectStorageElement *element; spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } - + if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) { return; } @@ -696,7 +696,7 @@ SPL_METHOD(SplObjectStorage, getInfo) if (zend_parse_parameters_none() == FAILURE) { return; } - + if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) { return; } @@ -710,7 +710,7 @@ SPL_METHOD(SplObjectStorage, setInfo) spl_SplObjectStorageElement *element; spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); zval *inf; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &inf) == FAILURE) { return; } @@ -728,11 +728,11 @@ SPL_METHOD(SplObjectStorage, setInfo) SPL_METHOD(SplObjectStorage, next) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } - + zend_hash_move_forward_ex(&intern->storage, &intern->pos); intern->index++; } /* }}} */ @@ -754,7 +754,7 @@ SPL_METHOD(SplObjectStorage, serialize) } PHP_VAR_SERIALIZE_INIT(var_hash); - + /* storage */ smart_str_appendl(&buf, "x:", 2); MAKE_STD_ZVAL(flags); @@ -793,7 +793,7 @@ SPL_METHOD(SplObjectStorage, serialize) } else { RETURN_NULL(); } - + } /* }}} */ /* {{{ proto void SplObjectStorage::unserialize(string serialized) @@ -808,7 +808,7 @@ SPL_METHOD(SplObjectStorage, unserialize) php_unserialize_data_t var_hash; zval *pentry, *pmembers, *pcount = NULL, *pinf; long count; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { return; } @@ -832,14 +832,15 @@ SPL_METHOD(SplObjectStorage, unserialize) goto outexcept; } + var_push_dtor(&var_hash, &pcount); --p; /* for ';' */ count = Z_LVAL_P(pcount); - + while(count-- > 0) { spl_SplObjectStorageElement *pelement; char *hash; int hash_len; - + if (*p != ';') { goto outexcept; } @@ -880,7 +881,7 @@ SPL_METHOD(SplObjectStorage, unserialize) if(pelement->obj) { var_push_dtor(&var_hash, &pelement->obj); } - } + } spl_object_storage_attach(intern, getThis(), pentry, pinf TSRMLS_CC); zval_ptr_dtor(&pentry); zval_ptr_dtor(&pinf); @@ -903,6 +904,7 @@ SPL_METHOD(SplObjectStorage, unserialize) goto outexcept; } + var_push_dtor(&var_hash, &pmembers); /* copy members */ if (!intern->std.properties) { rebuild_object_properties(&intern->std); @@ -1020,7 +1022,7 @@ SPL_METHOD(MultipleIterator, __construct) SPL_METHOD(MultipleIterator, getFlags) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1087,7 +1089,7 @@ SPL_METHOD(MultipleIterator, rewind) zval *it; intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1110,7 +1112,7 @@ SPL_METHOD(MultipleIterator, next) zval *it; intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1134,7 +1136,7 @@ SPL_METHOD(MultipleIterator, valid) long expect, valid; intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1180,7 +1182,7 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_ } array_init_size(return_value, num_elements); - + zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) { it = element->obj; @@ -1242,7 +1244,7 @@ SPL_METHOD(MultipleIterator, current) { spl_SplObjectStorage *intern; intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@ -1257,7 +1259,7 @@ SPL_METHOD(MultipleIterator, key) { spl_SplObjectStorage *intern; intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - + if (zend_parse_parameters_none() == FAILURE) { return; } diff --git a/ext/spl/tests/bug70068.phpt b/ext/spl/tests/bug70068.phpt new file mode 100644 index 0000000000..92a38dfbd6 --- /dev/null +++ b/ext/spl/tests/bug70068.phpt @@ -0,0 +1,9 @@ +--TEST-- +Bug #70068 (Dangling pointer in the unserialization of ArrayObject items) +--FILE-- +<?php +$a = unserialize('a:3:{i:0;C:11:"ArrayObject":20:{x:i:0;r:3;;m:a:0:{};}i:1;d:11;i:2;S:31:"AAAAAAAABBBBCCCC\01\00\00\00\04\00\00\00\00\00\00\00\00\00\00";}'); +?> +OK +--EXPECT-- +OK
\ No newline at end of file diff --git a/ext/spl/tests/bug70166.phpt b/ext/spl/tests/bug70166.phpt new file mode 100644 index 0000000000..51a35965a5 --- /dev/null +++ b/ext/spl/tests/bug70166.phpt @@ -0,0 +1,29 @@ +--TEST-- +SPL: Bug #70166 Use After Free Vulnerability in unserialize() with SPLArrayObject +--FILE-- +<?php +$inner = 'x:i:1;a:0:{};m:a:0:{}'; +$exploit = 'a:2:{i:0;C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}i:1;R:5;}'; + +$data = unserialize($exploit); + +for($i = 0; $i < 5; $i++) { + $v[$i] = 'hi'.$i; +} + +var_dump($data); +?> +===DONE=== +--EXPECTF-- +array(2) { + [0]=> + object(ArrayObject)#%d (1) { + ["storage":"ArrayObject":private]=> + array(0) { + } + } + [1]=> + array(0) { + } +} +===DONE=== diff --git a/ext/spl/tests/bug70168.phpt b/ext/spl/tests/bug70168.phpt new file mode 100644 index 0000000000..e1f7e9f820 --- /dev/null +++ b/ext/spl/tests/bug70168.phpt @@ -0,0 +1,36 @@ +--TEST-- +SPL: Bug #70168 Use After Free Vulnerability in unserialize() with SplObjectStorage +--FILE-- +<?php +$inner = 'x:i:1;O:8:"stdClass":0:{};m:a:0:{}'; +$exploit = 'a:2:{i:0;C:16:"SplObjectStorage":'.strlen($inner).':{'.$inner.'}i:1;R:3;}'; + +$data = unserialize($exploit); + +for($i = 0; $i < 5; $i++) { + $v[$i] = 'hi'.$i; +} + +var_dump($data); +?> +===DONE=== +--EXPECTF-- +array(2) { + [0]=> + object(SplObjectStorage)#%d (1) { + ["storage":"SplObjectStorage":private]=> + array(1) { + ["%s"]=> + array(2) { + ["obj"]=> + object(stdClass)#2 (0) { + } + ["inf"]=> + NULL + } + } + } + [1]=> + int(1) +} +===DONE=== diff --git a/ext/spl/tests/bug70169.phpt b/ext/spl/tests/bug70169.phpt new file mode 100644 index 0000000000..9d814be5fa --- /dev/null +++ b/ext/spl/tests/bug70169.phpt @@ -0,0 +1,30 @@ +--TEST-- +SPL: Bug #70169 Use After Free Vulnerability in unserialize() with SplDoublyLinkedList +--FILE-- +<?php +$inner = 'i:1;'; +$exploit = 'a:2:{i:0;C:19:"SplDoublyLinkedList":'.strlen($inner).':{'.$inner.'}i:1;R:3;}'; + +$data = unserialize($exploit); + +for($i = 0; $i < 5; $i++) { + $v[$i] = 'hi'.$i; +} + +var_dump($data); +?> +===DONE=== +--EXPECTF-- +array(2) { + [0]=> + object(SplDoublyLinkedList)#%d (2) { + ["flags":"SplDoublyLinkedList":private]=> + int(1) + ["dllist":"SplDoublyLinkedList":private]=> + array(0) { + } + } + [1]=> + int(1) +} +===DONE=== diff --git a/ext/standard/tests/serialize/bug69152.phpt b/ext/standard/tests/serialize/bug69152.phpt index 4e741685cc..bc2b302ddb 100644 --- a/ext/standard/tests/serialize/bug69152.phpt +++ b/ext/standard/tests/serialize/bug69152.phpt @@ -9,6 +9,7 @@ $x->test(); ?> --EXPECTF-- +Notice: Undefined property: Exception::$previous in %s on line %d exception 'Exception' in %s:%d Stack trace: #0 {main} diff --git a/ext/standard/tests/serialize/bug69793.phpt b/ext/standard/tests/serialize/bug69793.phpt new file mode 100644 index 0000000000..134b4dd696 --- /dev/null +++ b/ext/standard/tests/serialize/bug69793.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #69793: Remotely triggerable stack exhaustion via recursive method calls +--FILE-- +<?php +$e = unserialize('O:9:"Exception":7:{s:17:"'."\0".'Exception'."\0".'string";s:1:"a";s:7:"'."\0".'*'."\0".'code";i:0;s:7:"'."\0".'*'."\0".'file";R:1;s:7:"'."\0".'*'."\0".'line";i:1337;s:16:"'."\0".'Exception'."\0".'trace";a:0:{}s:19:"'."\0".'Exception'."\0".'previous";i:10;s:10:"'."\0".'*'."\0".'message";N;}'); + +var_dump($e.""); +?> +--EXPECTF-- +Notice: Undefined property: Exception::$message in %s/bug69793.php on line %d + +Notice: Undefined property: Exception::$file in %s/bug69793.php on line %d + +Notice: Undefined property: Exception::$previous in %s/bug69793.php on line %d +string(53) "exception 'Exception' in :1337 +Stack trace: +#0 {main}" |