|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2018-11-19 16:38 UTC] php at zsxsoft dot com
 Description:
------------
When try to `serialize` a class, `serialize` will try to get all properties of the class by `zend_get_properties_for`. Then it will get the count of the properties by `zend_array_count` without checking nullptr. 
`com` and `com_safearray_proxy` will always returns NULL in `com_properties_get` so it will crash on `zend_array_count`.
Affect code
------------------------
ext/standard/var.c
static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash) /* {{{ */
[...]
incomplete_class = php_var_serialize_class_name(buf, struc);
myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_SERIALIZE);
> i = zend_array_count(myht); // Crash here because myht == NULL
if (i > 0 && incomplete_class) {
  --i;
}
ext/com_dotnet/com_handlers.c
static HashTable *com_properties_get(zval *object)
{
	/* TODO: use type-info to get all the names and values ?
	 * DANGER: if we do that, there is a strong possibility for
	 * infinite recursion when the hash is displayed via var_dump().
	 * Perhaps it is best to leave it un-implemented.
	 */
	return NULL;
}
Test script:
---------------
<?php
$a = new COM("WScript.Shell");
serialize($a);
Expected result:
----------------
Nothing happened
Actual result:
--------------
Crash
Patchespaxsk (last revision 2022-02-17 07:25 UTC by jaky0306 at qq dot com)patch (last revision 2020-11-27 02:32 UTC by 920768504 at qq dot com) newtest0292 (last revision 2020-01-18 16:30 UTC by dadaguo at 126 dot com) Pull Requests
Pull requests: 
 HistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 01:00:01 2025 UTC | 
After fuzzing, I found `unserialize` those classes can crash php: - variant - com - dotnet unserialize('O:7:"variant":0:{}'); unserialize('O:3:"com":0:{}'); unserialize('O:6:"dotnet":0:{}');