diff options
| author | Nikita Popov <nikic@php.net> | 2017-01-01 14:13:29 +0100 |
|---|---|---|
| committer | Nikita Popov <nikic@php.net> | 2017-01-01 14:13:29 +0100 |
| commit | 878b8f046593085365466f20c756a2d429164707 (patch) | |
| tree | 02d3be09cfda20dfbffbe4c6d2405a7f066f4149 | |
| parent | 2a340423236938b8c6962f245f0ba99a6345d2f3 (diff) | |
| parent | 9f560baef5eacbe3fdb6a23a2d4e1996a30a2d2c (diff) | |
| download | php-git-878b8f046593085365466f20c756a2d429164707.tar.gz | |
Merge branch 'PHP-7.0' into PHP-7.1
| -rw-r--r-- | NEWS | 6 | ||||
| -rw-r--r-- | ext/standard/tests/serialize/bug70213.phpt | 30 | ||||
| -rw-r--r-- | ext/standard/var_unserializer.c | 20 | ||||
| -rw-r--r-- | ext/standard/var_unserializer.re | 2 |
4 files changed, 47 insertions, 11 deletions
@@ -53,8 +53,10 @@ PHP NEWS set). (cmb) - Standard: - . Fixed bug #73594 (dns_get_record does not populate $additional out parameter). - (Bruce Weirdan) + . Fixed bug #73594 (dns_get_record does not populate $additional out + parameter). (Bruce Weirdan) + . Fixed bug #70213 (Unserialize context shared on double class lookup). + (Taoguang Chen) - Zlib . Fixed bug #73373 (deflate_add does not verify that output was not truncated). diff --git a/ext/standard/tests/serialize/bug70213.phpt b/ext/standard/tests/serialize/bug70213.phpt new file mode 100644 index 0000000000..c01d362be0 --- /dev/null +++ b/ext/standard/tests/serialize/bug70213.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #70213: Unserialize context shared on double class lookup +--FILE-- +<?php + +ini_set('unserialize_callback_func', 'evil'); + +function evil() { + function __autoload($arg) { + var_dump(unserialize('R:1;')); + } +} + +var_dump(unserialize('a:2:{i:0;i:42;i:1;O:4:"evil":0:{}}')); + +?> +--EXPECTF-- +Notice: unserialize(): Error at offset 4 of 4 bytes in %s on line %d +bool(false) + +Warning: unserialize(): Function evil() hasn't defined the class it was called for in %s on line %d +array(2) { + [0]=> + int(42) + [1]=> + object(__PHP_Incomplete_Class)#1 (1) { + ["__PHP_Incomplete_Class_Name"]=> + string(4) "evil" + } +} diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index f3b997a6ef..4e2bee3c9e 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -647,7 +647,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER) yy2: ++YYCURSOR; yy3: -#line 959 "ext/standard/var_unserializer.re" +#line 961 "ext/standard/var_unserializer.re" { return 0; } #line 653 "ext/standard/var_unserializer.c" yy4: @@ -696,7 +696,7 @@ yy14: goto yy3; yy15: ++YYCURSOR; -#line 953 "ext/standard/var_unserializer.re" +#line 955 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data"); @@ -1240,11 +1240,13 @@ yy82: } /* The callback function may have defined the class */ + BG(serialize_lock)++; if ((ce = zend_lookup_class(class_name)) == NULL) { php_error_docref(NULL, E_WARNING, "Function %s() hasn't defined the class it was called for", Z_STRVAL(user_func)); incomplete_class = 1; ce = PHP_IC_ENTRY; } + BG(serialize_lock)--; zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); @@ -1274,7 +1276,7 @@ yy82: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 1278 "ext/standard/var_unserializer.c" +#line 1280 "ext/standard/var_unserializer.c" yy84: ++YYCURSOR; #line 743 "ext/standard/var_unserializer.re" @@ -1311,7 +1313,7 @@ yy84: ZVAL_STR(rval, str); return 1; } -#line 1315 "ext/standard/var_unserializer.c" +#line 1317 "ext/standard/var_unserializer.c" yy86: ++YYCURSOR; #line 777 "ext/standard/var_unserializer.re" @@ -1338,7 +1340,7 @@ yy86: return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 1342 "ext/standard/var_unserializer.c" +#line 1344 "ext/standard/var_unserializer.c" yy88: yych = *++YYCURSOR; if (yych <= ',') { @@ -1370,7 +1372,7 @@ yy92: return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 1374 "ext/standard/var_unserializer.c" +#line 1376 "ext/standard/var_unserializer.c" yy94: ++YYCURSOR; #line 711 "ext/standard/var_unserializer.re" @@ -1405,7 +1407,7 @@ yy94: ZVAL_STRINGL(rval, str, len); return 1; } -#line 1409 "ext/standard/var_unserializer.c" +#line 1411 "ext/standard/var_unserializer.c" yy96: yych = *++YYCURSOR; if (yych <= '/') goto yy18; @@ -1429,9 +1431,9 @@ yy97: return 1; } -#line 1433 "ext/standard/var_unserializer.c" +#line 1435 "ext/standard/var_unserializer.c" } -#line 961 "ext/standard/var_unserializer.re" +#line 963 "ext/standard/var_unserializer.re" return 0; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 6d53cb6249..4f127773ef 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -915,11 +915,13 @@ object ":" uiv ":" ["] { } /* The callback function may have defined the class */ + BG(serialize_lock)++; if ((ce = zend_lookup_class(class_name)) == NULL) { php_error_docref(NULL, E_WARNING, "Function %s() hasn't defined the class it was called for", Z_STRVAL(user_func)); incomplete_class = 1; ce = PHP_IC_ENTRY; } + BG(serialize_lock)--; zval_ptr_dtor(&user_func); zval_ptr_dtor(&args[0]); |
