From e201f01ac17243a1e5fb6a3911ed8e21b1619ac1 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Mon, 31 Aug 2015 21:06:03 -0700
Subject: [PATCH] Fix bug #70388 - SOAP serialize_function_call() type
 confusion

---
 ext/soap/soap.c              | 96 ++++++++++++++++++++++++--------------------
 ext/soap/tests/bug70388.phpt | 17 ++++++++
 2 files changed, 69 insertions(+), 44 deletions(-)
 create mode 100644 ext/soap/tests/bug70388.phpt

Index: php5-5.3.3.1/ext/soap/soap.c
===================================================================
--- php5-5.3.3.1.orig/ext/soap/soap.c	2015-10-19 11:11:01.000000000 +0200
+++ php5-5.3.3.1/ext/soap/soap.c	2015-10-19 11:11:01.000000000 +0200
@@ -3093,8 +3093,10 @@
 			}
 			zend_hash_internal_pointer_reset(default_headers);
 			while (zend_hash_get_current_data(default_headers, (void**)&tmp) == SUCCESS) {
-				Z_ADDREF_PP(tmp);
-				zend_hash_next_index_insert(soap_headers, tmp, sizeof(zval *), NULL);
+				if(Z_TYPE_PP(tmp) == IS_OBJECT) {
+					Z_ADDREF_PP(tmp);
+					zend_hash_next_index_insert(soap_headers, tmp, sizeof(zval *), NULL);
+				}
 				zend_hash_move_forward(default_headers);
 			}
 		} else {
@@ -4491,11 +4493,18 @@
 	if (head) {
 		zval** header;
 
-		zend_hash_internal_pointer_reset(soap_headers);
-		while (zend_hash_get_current_data(soap_headers,(void**)&header) == SUCCESS) {
-			HashTable *ht = Z_OBJPROP_PP(header);
+		for(zend_hash_internal_pointer_reset(soap_headers);
+				zend_hash_get_current_data(soap_headers,(void**)&header) == SUCCESS;
+				zend_hash_move_forward(soap_headers)
+			) {
+			HashTable *ht;
 			zval **name, **ns, **tmp;
 
+			if (Z_TYPE_PP(header) != IS_OBJECT) {
+				continue;
+			}
+
+			ht = Z_OBJPROP_PP(header);
 			if (zend_hash_find(ht, "name", sizeof("name"), (void**)&name) == SUCCESS &&
 			    Z_TYPE_PP(name) == IS_STRING &&
 			    zend_hash_find(ht, "namespace", sizeof("namespace"), (void**)&ns) == SUCCESS &&
@@ -4565,7 +4574,6 @@
 					}
 				}
 			}
-			zend_hash_move_forward(soap_headers);
 		}
 	}
 
Index: php5-5.3.3.1/ext/soap/tests/bug70388.phpt
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ php5-5.3.3.1/ext/soap/tests/bug70388.phpt	2015-10-19 11:11:01.000000000 +0200
@@ -0,0 +1,17 @@
+--TEST--
+Bug #70388 (SOAP serialize_function_call() type confusion / RCE)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$dummy = unserialize('O:10:"SoapClient":3:{s:3:"uri";s:1:"X";s:8:"location";s:22:"http://localhost/a.xml";s:17:"__default_headers";a:1:{i:1;s:1337:"'.str_repeat("X", 1337).'";}}');
+try {
+	var_dump($dummy->notexisting());
+} catch(Exception $e) {
+	var_dump($e->getMessage());
+	var_dump(get_class($e));
+}
+?>
+--EXPECTF--
+string(%d) "%s"
+string(9) "SoapFault"
\ No newline at end of file
