php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71763 Soap failed if param WAS reference
Submitted: 2016-03-10 02:56 UTC Modified: 2017-01-31 10:58 UTC
Votes:8
Avg. Score:5.0 ± 0.0
Reproduced:8 of 8 (100.0%)
Same Version:7 (87.5%)
Same OS:7 (87.5%)
From: ppbg at andreika dot info Assigned:
Status: Duplicate Package: SOAP related
PHP Version: 7.0.4 OS:
Private report: No CVE-ID: None
 [2016-03-10 02:56 UTC] ppbg at andreika dot info
Description:
------------
I got strange behavour in soap extension but I think it is not soap-related.

If I call soap method with "complex" params I lost some tags in request ( it can be invalid and dropped while wsdl schema validation ? ) if that param was reference

reproduced in ubuntu and centos (remi package) with 7.0.3 and 7.0.4

Test script:
---------------
$client = new \SoapClient('WebStoreWS.xml', [
            'trace' => true,
        ]);
$params = [
  'p' => [
    'param1' => 'OK',
    'param2' => [
      'item' => 1,
      'item2' => 2
    ]
  ]
];

if ( MAKEREF || UNLINKIT || FIXME) {
  // make ref
  $p = &$array['p']['param2'];
  if ( UNLINKIT) {
     //remove ref
     unset($p);
  }
  if (FIXME) {
// "touch" any key of array to fix problem
   $array['p']['param2']['item'] = $array['p']['param2']['item'];
 }
} 



try {
  $client->myFunc($params);
} catch(\Exception $e) {
  echo $client->__getLastRequest();
}

Expected result:
----------------
// it works in php5.6 (all params) and php7.0.4 with !MAKEREF OR FIXME= true
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope ...>
  <p>
    <param1>OK</param1>
    <param2>
      <item>1</item>
      <item2>2</item2>
    </param2>
  </p>
</SOAP-ENV>

Actual result:
--------------
// it fails in php7.0.4 with MAKEREF AND !FIXME
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope ...>
  <p>
    <param1>OK</param1>
  </p>
</SOAP-ENV>

so if we made a reference in subarray of params we got problems even unlink reference. But if we change any param of subarray (even on the same value) the problem will be fixed. 

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-03-10 03:00 UTC] ppbg at andreika dot info
-Operating System: linux +Operating System:
 [2016-03-10 03:00 UTC] ppbg at andreika dot info
/
 [2016-06-14 08:28 UTC] msmit at quovide dot com
I have a similar issue. I present you a complete test case:

<?php

/** Function that is the culprit **/
function filter($o)
{
	if(is_array($o))
	{
		foreach($o as &$v)
		{
			$v = filter($v);
		}
		
		return $o;
	}
	
	return $o;
}

/**
 * Test class
 */
class TestClient extends SoapClient
{

	public function __construct()
	{
		parent::__construct('http://www.ripedev.com/webservices/localtime.asmx?WSDL');
	}

	public function __doRequest($request, $location, $action, $version, $one_way = NULL)
	{
		echo htmlentities($request);
		die();
	}
}

$args = array(
	"ZipCode" => null 
);

/**
 * When commentend (ZipCode not there):
 * <?xml version="1.0" encoding="UTF-8"?>
 * <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.ripedev.com/">
 * <SOAP-ENV:Body>
 * <ns1:LocalTimeByZipCode/>
 * </SOAP-ENV:Body>
 * </SOAP-ENV:Envelope>
 *
 * When uncommented (zipCode is now an empty string??):
 * <?xml version="1.0" encoding="UTF-8"?>
 * <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.ripedev.com/">
 * <SOAP-ENV:Body>
 * <ns1:LocalTimeByZipCode>
 * <ns1:ZipCode></ns1:ZipCode>
 * </ns1:LocalTimeByZipCode>
 * </SOAP-ENV:Body>
 * </SOAP-ENV:Envelope>
 */
// $args = filter($args);

// Both show same var_dump:

// var_dump($args);
// array(1) { ["ZipCode"]=> NULL }
// var_dump(filter($args));
// array(1) { ["ZipCode"]=> NULL }

$client = new TestClient();
$client->LocalTimeByZipCode($args);
 [2016-06-30 13:46 UTC] tero dot tasanen at gmail dot com
We are also having a same problem, but with in SoapServer context. If a variable (array of objects) has a reference the soap action will return an array of empty elements. See the example below. When the reference is removed,  I don't know either if this is soap related, but I was not able to reproduce this with a separate test script. 

I think this is a really critical bug. This was working as it should in all versions before php7.




-------

public function getSalesOrders() {
  $data = [new SalesOrder()];

  foreach($data as &$item) { // ref here breaks the response.
    $data->rows = getRows($item->id);
  }

  return $data;
}
--------
<SOAP-ENV:Envelope>
   <SOAP-ENV:Body>
      <ns1:getSalesOrdersResponse>
         <getSalesOrdersReturn SOAP-ENC:arrayType="ns1:SalesOrder[3]" xsi:type="ns1:SalesOrderArray">
            <item xsi:type="ns1:SalesOrder"/>
            <item xsi:type="ns1:SalesOrder"/>
            <item xsi:type="ns1:SalesOrder"/>
         </getSalesOrdersReturn>
      </ns1:getSalesOrdersResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>


-------

And yes, I know that the reference is not needed in my case, but there might be cases where it was needed. This was just something we noticed when upgrading to php7.
 [2016-06-30 13:55 UTC] tero dot tasanen at gmail dot com
Correction to previous code example. It should of course be:
  $item->rows = getRows($item->id);
 [2017-01-31 10:58 UTC] nikic@php.net
-Status: Open +Status: Duplicate -Package: Arrays related +Package: SOAP related
 [2017-01-31 10:58 UTC] nikic@php.net
Duplicate of bug #73089, which should be fixed in either 7.0.12 or 7.0.15 depending on the particular case.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 17:01:32 2024 UTC