Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

include/nusoap/class.nusoap_base.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
5
Modification information for LGPL compliance
6
7
r57813 - 2010-08-19 10:34:44 -0700 (Thu, 19 Aug 2010) - kjing - Author: John Mertic <[email protected]>
8
    Bug 39085 - When loading the opposite search panel via ajax on the ListViews, call the index action instead of the ListView action to avoid touching pre-MVC code by accident.
9
10
r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync
11
12
r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover
13
14
r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex
15
16
r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3  tags and updated the build system 
17
18
r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development
19
20
r51516 - 2009-10-14 10:22:42 -0700 (Wed, 14 Oct 2009) - jmertic - More fallout fixes from the PHP 5.3 ereg to preg changes.
21
22
r51443 - 2009-10-12 13:34:36 -0700 (Mon, 12 Oct 2009) - jmertic - Bug 33332 - Made application PHP 5.3 compliant with E_DEPRECATED warnings on by:
23
- Changing all ereg function to either preg or simple string based ones
24
- No more references to magic quotes.
25
- Change all the session_unregister() functions to just unset() the correct session variable instead.
26
27
r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372
28
29
r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm
30
31
r14701 - 2006-07-17 13:37:26 -0700 (Mon, 17 Jul 2006) - roger - RRS: bug 5801
32
33
r13782 - 2006-06-06 10:58:55 -0700 (Tue, 06 Jun 2006) - majed - changes entry point code
34
35
r11115 - 2006-01-17 14:54:45 -0800 (Tue, 17 Jan 2006) - majed - add entry point validation
36
37
r8846 - 2005-10-31 11:01:12 -0800 (Mon, 31 Oct 2005) - majed - new version of nusoap
38
39
r5462 - 2005-05-25 13:50:11 -0700 (Wed, 25 May 2005) - majed - upgraded nusoap to .6.9
40
41
r573 - 2004-09-04 13:03:32 -0700 (Sat, 04 Sep 2004) - sugarclint - undoing copyrights added in inadvertantly.  --clint
42
43
r546 - 2004-09-03 11:49:38 -0700 (Fri, 03 Sep 2004) - sugarmsi - removed echo count
44
45
r354 - 2004-08-02 23:00:37 -0700 (Mon, 02 Aug 2004) - sugarjacob - Adding Soap
46
47
48
*/
49
50
51
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
52
53
/*
54
$Id: class.nusoap_base.php 57813 2010-08-19 17:34:44Z kjing $
55
56
NuSOAP - Web Services Toolkit for PHP
57
58
Copyright (c) 2002 NuSphere Corporation
59
60
This library is free software; you can redistribute it and/or
61
modify it under the terms of the GNU Lesser General Public
62
License as published by the Free Software Foundation; either
63
version 2.1 of the License, or (at your option) any later version.
64
65
This library is distributed in the hope that it will be useful,
66
but WITHOUT ANY WARRANTY; without even the implied warranty of
67
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
68
Lesser General Public License for more details.
69
70
You should have received a copy of the GNU Lesser General Public
71
License along with this library; if not, write to the Free Software
72
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
73
74
The NuSOAP project home is:
75
http://sourceforge.net/projects/nusoap/
76
77
The primary support for NuSOAP is the Help forum on the project home page.
78
79
If you have any questions or comments, please email:
80
81
Dietrich Ayala
82
[email protected]
83
http://dietrich.ganx4.com/nusoap
84
85
NuSphere Corporation
86
http://www.nusphere.com
87
88
*/
89
90
/*
91
 *	Some of the standards implmented in whole or part by NuSOAP:
92
 *
93
 *	SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
94
 *	WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
95
 *	SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
96
 *	XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
97
 *	Namespaces in XML 1.0 (http://www.w3.org/TR/2006/REC-xml-names-20060816/)
98
 *	XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
99
 *	RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
100
 *	RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
101
 *	RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
102
 */
103
104
/* load classes
105
106
// necessary classes
107
require_once('class.soapclient.php');
108
require_once('class.soap_val.php');
109
require_once('class.soap_parser.php');
110
require_once('class.soap_fault.php');
111
112
// transport classes
113
require_once('class.soap_transport_http.php');
114
115
// optional add-on classes
116
require_once('class.xmlschema.php');
117
require_once('class.wsdl.php');
118
119
// server class
120
require_once('class.soap_server.php');*/
121
122
// class variable emulation
123
// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
124
$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = 9;
125
126
/**
127
*
128
* nusoap_base
129
*
130
* @author   Dietrich Ayala <[email protected]>
131
* @author   Scott Nichol <[email protected]>
132
133
* @access   public
134
*/
135
class nusoap_base {
136
	/**
137
	 * Identification for HTTP headers.
138
	 *
139
	 * @var string
140
	 * @access private
141
	 */
142
	var $title = 'NuSOAP';
143
	/**
144
	 * Version for HTTP headers.
145
	 *
146
	 * @var string
147
	 * @access private
148
	 */
149
	var $version = '0.9.5';
150
	/**
151
	 * CVS revision for HTTP headers.
152
	 *
153
	 * @var string
154
	 * @access private
155
	 */
156
	var $revision = '$Revision: 57813 $';
157
    /**
158
     * Current error string (manipulated by getError/setError)
159
	 *
160
	 * @var string
161
	 * @access private
162
	 */
163
	var $error_str = '';
164
    /**
165
     * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
166
	 *
167
	 * @var string
168
	 * @access private
169
	 */
170
    var $debug_str = '';
171
    /**
172
	 * toggles automatic encoding of special characters as entities
173
	 * (should always be true, I think)
174
	 *
175
	 * @var boolean
176
	 * @access private
177
	 */
178
	var $charencoding = true;
179
	/**
180
	 * the debug level for this instance
181
	 *
182
	 * @var	integer
183
	 * @access private
184
	 */
185
	var $debugLevel;
186
187
    /**
188
	* set schema version
189
	*
190
	* @var      string
191
	* @access   public
192
	*/
193
	var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
194
	
195
    /**
196
	* charset encoding for outgoing messages
197
	*
198
	* @var      string
199
	* @access   public
200
	*/
201
    //var $soap_defencoding = 'ISO-8859-1';
202
	var $soap_defencoding = 'UTF-8';
203
204
	/**
205
	* namespaces in an array of prefix => uri
206
	*
207
	* this is "seeded" by a set of constants, but it may be altered by code
208
	*
209
	* @var      array
210
	* @access   public
211
	*/
212
	var $namespaces = array(
213
		'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
214
		'xsd' => 'http://www.w3.org/2001/XMLSchema',
215
		'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
216
		'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
217
		);
218
219
	/**
220
	* namespaces used in the current context, e.g. during serialization
221
	*
222
	* @var      array
223
	* @access   private
224
	*/
225
	var $usedNamespaces = array();
226
227
	/**
228
	* XML Schema types in an array of uri => (array of xml type => php type)
229
	* is this legacy yet?
230
	* no, this is used by the nusoap_xmlschema class to verify type => namespace mappings.
231
	* @var      array
232
	* @access   public
233
	*/
234
	var $typemap = array(
235
	'http://www.w3.org/2001/XMLSchema' => array(
236
		'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
237
		'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
238
		'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
239
		// abstract "any" types
240
		'anyType'=>'string','anySimpleType'=>'string',
241
		// derived datatypes
242
		'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
243
		'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
244
		'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
245
		'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
246
	'http://www.w3.org/2000/10/XMLSchema' => array(
247
		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
248
		'float'=>'double','dateTime'=>'string',
249
		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
250
	'http://www.w3.org/1999/XMLSchema' => array(
251
		'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
252
		'float'=>'double','dateTime'=>'string',
253
		'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
254
	'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
255
	'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
256
    'http://xml.apache.org/xml-soap' => array('Map')
257
	);
258
259
	/**
260
	* XML entities to convert
261
	*
262
	* @var      array
263
	* @access   public
264
	* @deprecated
265
	* @see	expandEntities
266
	*/
267
	var $xmlEntities = array('quot' => '"','amp' => '&',
268
		'lt' => '<','gt' => '>','apos' => "'");
269
270
	/**
271
	* constructor
272
	*
273
	* @access	public
274
	*/
275
	function nusoap_base() {
276
		$this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
277
	}
278
279
	/**
280
	* gets the global debug level, which applies to future instances
281
	*
282
	* @return	integer	Debug level 0-9, where 0 turns off
283
	* @access	public
284
	*/
285
	function getGlobalDebugLevel() {
286
		return $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
287
	}
288
289
	/**
290
	* sets the global debug level, which applies to future instances
291
	*
292
	* @param	int	$level	Debug level 0-9, where 0 turns off
293
	* @access	public
294
	*/
295
	function setGlobalDebugLevel($level) {
296
		$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = $level;
297
	}
298
299
	/**
300
	* gets the debug level for this instance
301
	*
302
	* @return	int	Debug level 0-9, where 0 turns off
303
	* @access	public
304
	*/
305
	function getDebugLevel() {
306
		return $this->debugLevel;
307
	}
308
309
	/**
310
	* sets the debug level for this instance
311
	*
312
	* @param	int	$level	Debug level 0-9, where 0 turns off
313
	* @access	public
314
	*/
315
	function setDebugLevel($level) {
316
		$this->debugLevel = $level;
317
	}
318
319
	/**
320
	* adds debug data to the instance debug string with formatting
321
	*
322
	* @param    string $string debug data
323
	* @access   private
324
	*/
325
	function debug($string){
326
		if ($this->debugLevel > 0) {
327
			$this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
328
		}
329
	}
330
331
	/**
332
	* adds debug data to the instance debug string without formatting
333
	*
334
	* @param    string $string debug data
335
	* @access   public
336
	*/
337
	function appendDebug($string){
338
		if ($this->debugLevel > 0) {
339
			// it would be nice to use a memory stream here to use
340
			// memory more efficiently
341
			$this->debug_str .= $string;
342
		}
343
	}
344
345
	/**
346
	* clears the current debug data for this instance
347
	*
348
	* @access   public
349
	*/
350
	function clearDebug() {
351
		// it would be nice to use a memory stream here to use
352
		// memory more efficiently
353
		$this->debug_str = '';
354
	}
355
356
	/**
357
	* gets the current debug data for this instance
358
	*
359
	* @return   debug data
360
	* @access   public
361
	*/
362
	function &getDebug() {
363
		// it would be nice to use a memory stream here to use
364
		// memory more efficiently
365
		return $this->debug_str;
366
	}
367
368
	/**
369
	* gets the current debug data for this instance as an XML comment
370
	* this may change the contents of the debug data
371
	*
372
	* @return   debug data as an XML comment
373
	* @access   public
374
	*/
375
	function &getDebugAsXMLComment() {
376
		// it would be nice to use a memory stream here to use
377
		// memory more efficiently
378
		while (strpos($this->debug_str, '--')) {
379
			$this->debug_str = str_replace('--', '- -', $this->debug_str);
380
		}
381
		$ret = "<!--\n" . $this->debug_str . "\n-->";
382
    	return $ret;
383
	}
384
385
	/**
386
	* expands entities, e.g. changes '<' to '&lt;'.
387
	*
388
	* @param	string	$val	The string in which to expand entities.
389
	* @access	private
390
	*/
391
	function expandEntities($val) {
392
		if ($this->charencoding) {
393
	    	$val = str_replace('&', '&amp;', $val);
394
	    	$val = str_replace("'", '&apos;', $val);
395
	    	$val = str_replace('"', '&quot;', $val);
396
	    	$val = str_replace('<', '&lt;', $val);
397
	    	$val = str_replace('>', '&gt;', $val);
398
	    }
399
	    return $val;
400
	}
401
402
	/**
403
	* returns error string if present
404
	*
405
	* @return   mixed error string or false
406
	* @access   public
407
	*/
408
	function getError(){
409
		if($this->error_str != ''){
410
			return $this->error_str;
411
		}
412
		return false;
413
	}
414
415
	/**
416
	* sets error string
417
	*
418
	* @return   boolean $string error string
419
	* @access   private
420
	*/
421
	function setError($str){
422
		$this->error_str = $str;
423
	}
424
425
	/**
426
	* detect if array is a simple array or a struct (associative array)
427
	*
428
	* @param	mixed	$val	The PHP array
429
	* @return	string	(arraySimple|arrayStruct)
430
	* @access	private
431
	*/
432
	function isArraySimpleOrStruct($val) {
433
        $keyList = array_keys($val);
434
		foreach ($keyList as $keyListValue) {
435
			if (!is_int($keyListValue)) {
436
				return 'arrayStruct';
437
			}
438
		}
439
		return 'arraySimple';
440
	}
441
442
	/**
443
	* serializes PHP values in accordance w/ section 5. Type information is
444
	* not serialized if $use == 'literal'.
445
	*
446
	* @param	mixed	$val	The value to serialize
447
	* @param	string	$name	The name (local part) of the XML element
448
	* @param	string	$type	The XML schema type (local part) for the element
449
	* @param	string	$name_ns	The namespace for the name of the XML element
450
	* @param	string	$type_ns	The namespace for the type of the element
451
	* @param	array	$attributes	The attributes to serialize as name=>value pairs
452
	* @param	string	$use	The WSDL "use" (encoded|literal)
453
	* @param	boolean	$soapval	Whether this is called from soapval.
454
	* @return	string	The serialized element, possibly with child elements
455
    * @access	public
456
	*/
457
	function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false) {
458
		$this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
459
		$this->appendDebug('value=' . $this->varDump($val));
460
		$this->appendDebug('attributes=' . $this->varDump($attributes));
461
		
462
    	if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
463
    		$this->debug("serialize_val: serialize soapval");
464
        	$xml = $val->serialize($use);
465
			$this->appendDebug($val->getDebug());
466
			$val->clearDebug();
467
			$this->debug("serialize_val of soapval returning $xml");
468
			return $xml;
469
        }
470
		// force valid name if necessary
471
		if (is_numeric($name)) {
472
			$name = '__numeric_' . $name;
473
		} elseif (! $name) {
474
			$name = 'noname';
475
		}
476
		// if name has ns, add ns prefix to name
477
		$xmlns = '';
478
        if($name_ns){
479
			$prefix = 'nu'.rand(1000,9999);
480
			$name = $prefix.':'.$name;
481
			$xmlns .= " xmlns:$prefix=\"$name_ns\"";
482
		}
483
		// if type is prefixed, create type prefix
484
		if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
485
			// need to fix this. shouldn't default to xsd if no ns specified
486
		    // w/o checking against typemap
487
			$type_prefix = 'xsd';
488
		} elseif($type_ns){
489
			$type_prefix = 'ns'.rand(1000,9999);
490
			$xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
491
		}
492
		// serialize attributes if present
493
		$atts = '';
494
		if($attributes){
495
			foreach($attributes as $k => $v){
496
				$atts .= " $k=\"".$this->expandEntities($v).'"';
497
			}
498
		}
499
		// serialize null value
500
		if (is_null($val)) {
501
    		$this->debug("serialize_val: serialize null");
502
			if ($use == 'literal') {
503
				// TODO: depends on minOccurs
504
				$xml = "<$name$xmlns$atts/>";
505
				$this->debug("serialize_val returning $xml");
506
	        	return $xml;
507
        	} else {
508
				if (isset($type) && isset($type_prefix)) {
509
					$type_str = " xsi:type=\"$type_prefix:$type\"";
510
				} else {
511
					$type_str = '';
512
				}
513
				$xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
514
				$this->debug("serialize_val returning $xml");
515
	        	return $xml;
516
        	}
517
		}
518
        // serialize if an xsd built-in primitive type
519
        if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
520
    		$this->debug("serialize_val: serialize xsd built-in primitive type");
521
        	if (is_bool($val)) {
522
        		if ($type == 'boolean') {
523
	        		$val = $val ? 'true' : 'false';
524
	        	} elseif (! $val) {
525
	        		$val = 0;
526
	        	}
527
			} else if (is_string($val)) {
528
				$val = $this->expandEntities($val);
529
			}
530
			if ($use == 'literal') {
531
				$xml = "<$name$xmlns$atts>$val</$name>";
532
				$this->debug("serialize_val returning $xml");
533
	        	return $xml;
534
        	} else {
535
				$xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
536
				$this->debug("serialize_val returning $xml");
537
	        	return $xml;
538
        	}
539
        }
540
		// detect type and serialize
541
		$xml = '';
542
		switch(true) {
543
			case (is_bool($val) || $type == 'boolean'):
544
		   		$this->debug("serialize_val: serialize boolean");
545
        		if ($type == 'boolean') {
546
	        		$val = $val ? 'true' : 'false';
547
	        	} elseif (! $val) {
548
	        		$val = 0;
549
	        	}
550
				if ($use == 'literal') {
551
					$xml .= "<$name$xmlns$atts>$val</$name>";
552
				} else {
553
					$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
554
				}
555
				break;
556
			case (is_int($val) || is_long($val) || $type == 'int'):
557
		   		$this->debug("serialize_val: serialize int");
558
				if ($use == 'literal') {
559
					$xml .= "<$name$xmlns$atts>$val</$name>";
560
				} else {
561
					$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
562
				}
563
				break;
564
			case (is_float($val)|| is_double($val) || $type == 'float'):
565
		   		$this->debug("serialize_val: serialize float");
566
				if ($use == 'literal') {
567
					$xml .= "<$name$xmlns$atts>$val</$name>";
568
				} else {
569
					$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
570
				}
571
				break;
572
			case (is_string($val) || $type == 'string'):
573
		   		$this->debug("serialize_val: serialize string");
574
				$val = $this->expandEntities($val);
0 ignored issues
show
It seems like $val can also be of type array or object; however, nusoap_base::expandEntities() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
575
				if ($use == 'literal') {
576
					$xml .= "<$name$xmlns$atts>$val</$name>";
577
				} else {
578
					$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
579
				}
580
				break;
581
			case is_object($val):
582
		   		$this->debug("serialize_val: serialize object");
583
		    	if (get_class($val) == 'soapval') {
584
		    		$this->debug("serialize_val: serialize soapval object");
585
		        	$pXml = $val->serialize($use);
586
					$this->appendDebug($val->getDebug());
587
					$val->clearDebug();
588
		        } else {
589
					if (! $name) {
590
						$name = get_class($val);
591
						$this->debug("In serialize_val, used class name $name as element name");
592
					} else {
593
						$this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
594
					}
595
					foreach(get_object_vars($val) as $k => $v){
596
						$pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
597
					}
598
				}
599
				if(isset($type) && isset($type_prefix)){
600
					$type_str = " xsi:type=\"$type_prefix:$type\"";
601
				} else {
602
					$type_str = '';
603
				}
604
				if ($use == 'literal') {
605
					$xml .= "<$name$xmlns$atts>$pXml</$name>";
606
				} else {
607
					$xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
608
				}
609
				break;
610
			break;
0 ignored issues
show
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
611
			case (is_array($val) || $type):
612
				// detect if struct or array
613
				$valueType = $this->isArraySimpleOrStruct($val);
614
                if($valueType=='arraySimple' || preg_match('/^ArrayOf/',$type)){
615
			   		$this->debug("serialize_val: serialize array");
616
					$i = 0;
617
					if(is_array($val) && count($val)> 0){
618
						foreach($val as $v){
619
	                    	if(is_object($v) && get_class($v) ==  'soapval'){
620
								$tt_ns = $v->type_ns;
621
								$tt = $v->type;
622
							} elseif (is_array($v)) {
623
								$tt = $this->isArraySimpleOrStruct($v);
624
							} else {
625
								$tt = gettype($v);
626
	                        }
627
							$array_types[$tt] = 1;
628
							// TODO: for literal, the name should be $name
629
							$xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
630
							++$i;
631
						}
632
						if(count($array_types) > 1){
633
							$array_typename = 'xsd:anyType';
634
						} elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
635
							if ($tt == 'integer') {
636
								$tt = 'int';
637
							}
638
							$array_typename = 'xsd:'.$tt;
639
						} elseif(isset($tt) && $tt == 'arraySimple'){
640
							$array_typename = 'SOAP-ENC:Array';
641
						} elseif(isset($tt) && $tt == 'arrayStruct'){
642
							$array_typename = 'unnamed_struct_use_soapval';
643
						} else {
644
							// if type is prefixed, create type prefix
645
							if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
646
								 $array_typename = 'xsd:' . $tt;
647
							} elseif ($tt_ns) {
648
								$tt_prefix = 'ns' . rand(1000, 9999);
649
								$array_typename = "$tt_prefix:$tt";
650
								$xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
651
							} else {
652
								$array_typename = $tt;
653
							}
654
						}
655
						$array_type = $i;
656
						if ($use == 'literal') {
657
							$type_str = '';
658
						} else if (isset($type) && isset($type_prefix)) {
659
							$type_str = " xsi:type=\"$type_prefix:$type\"";
660
						} else {
661
							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
662
						}
663
					// empty array
664
					} else {
665
						if ($use == 'literal') {
666
							$type_str = '';
667
						} else if (isset($type) && isset($type_prefix)) {
668
							$type_str = " xsi:type=\"$type_prefix:$type\"";
669
						} else {
670
							$type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
671
						}
672
					}
673
					// TODO: for array in literal, there is no wrapper here
674
					$xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
675
				} else {
676
					// got a struct
677
			   		$this->debug("serialize_val: serialize struct");
678
					if(isset($type) && isset($type_prefix)){
679
						$type_str = " xsi:type=\"$type_prefix:$type\"";
680
					} else {
681
						$type_str = '';
682
					}
683
					if ($use == 'literal') {
684
						$xml .= "<$name$xmlns$atts>";
685
					} else {
686
						$xml .= "<$name$xmlns$type_str$atts>";
687
					}
688
					foreach($val as $k => $v){
689
						// Apache Map
690
						if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
691
							$xml .= '<item>';
692
							$xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
693
							$xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
694
							$xml .= '</item>';
695
						} else {
696
							$xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
697
						}
698
					}
699
					$xml .= "</$name>";
700
				}
701
				break;
702
			default:
703
		   		$this->debug("serialize_val: serialize unknown");
704
				$xml .= 'not detected, got '.gettype($val).' for '.$val;
705
				break;
706
		}
707
		$this->debug("serialize_val returning $xml");
708
		return $xml;
709
	}
710
711
    /**
712
    * serializes a message
713
    *
714
    * @param string $body the XML of the SOAP body
715
    * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
716
    * @param array $namespaces optional the namespaces used in generating the body and headers
717
    * @param string $style optional (rpc|document)
718
    * @param string $use optional (encoded|literal)
719
    * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
720
    * @return string the message
721
    * @access public
722
    */
723
    function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
724
    // TODO: add an option to automatically run utf8_encode on $body and $headers
725
    // if $this->soap_defencoding is UTF-8.  Not doing this automatically allows
726
    // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
727
728
	$this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
729
	$this->debug("headers:");
730
	$this->appendDebug($this->varDump($headers));
731
	$this->debug("namespaces:");
732
	$this->appendDebug($this->varDump($namespaces));
733
734
	// serialize namespaces
735
    $ns_string = '';
736
	foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
737
		$ns_string .= " xmlns:$k=\"$v\"";
738
	}
739
	if($encodingStyle) {
740
		$ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
741
	}
742
743
	// serialize headers
744
	if($headers){
745
		if (is_array($headers)) {
746
			$xml = '';
747
			foreach ($headers as $k => $v) {
748
				if (is_object($v) && get_class($v) == 'soapval') {
749
					$xml .= $this->serialize_val($v, false, false, false, false, false, $use);
750
				} else {
751
					$xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
752
				}
753
			}
754
			$headers = $xml;
755
			$this->debug("In serializeEnvelope, serialized array of headers to $headers");
756
		}
757
		$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
758
	}
759
	// serialize envelope
760
	return
761
	'<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
762
	'<SOAP-ENV:Envelope'.$ns_string.">".
763
	$headers.
764
	"<SOAP-ENV:Body>".
765
		$body.
766
	"</SOAP-ENV:Body>".
767
	"</SOAP-ENV:Envelope>";
768
    }
769
770
	/**
771
	 * formats a string to be inserted into an HTML stream
772
	 *
773
	 * @param string $str The string to format
774
	 * @return string The formatted string
775
	 * @access public
776
	 * @deprecated
777
	 */
778
    function formatDump($str){
779
		$str = htmlspecialchars($str);
780
		return nl2br($str);
781
    }
782
783
	/**
784
	* contracts (changes namespace to prefix) a qualified name
785
	*
786
	* @param    string $qname qname
787
	* @return	string contracted qname
788
	* @access   private
789
	*/
790
	function contractQname($qname){
791
		// get element namespace
792
		//$this->xdebug("Contract $qname");
793
		if (strrpos($qname, ':')) {
794
			// get unqualified name
795
			$name = substr($qname, strrpos($qname, ':') + 1);
796
			// get ns
797
			$ns = substr($qname, 0, strrpos($qname, ':'));
798
			$p = $this->getPrefixFromNamespace($ns);
799
			if ($p) {
800
				return $p . ':' . $name;
801
			}
802
			return $qname;
803
		} else {
804
			return $qname;
805
		}
806
	}
807
808
	/**
809
	* expands (changes prefix to namespace) a qualified name
810
	*
811
	* @param    string $qname qname
812
	* @return	string expanded qname
813
	* @access   private
814
	*/
815
	function expandQname($qname){
816
		// get element prefix
817
		if(strpos($qname,':') && !preg_match('/^http:\/\//',$qname)){
818
			// get unqualified name
819
			$name = substr(strstr($qname,':'),1);
820
			// get ns prefix
821
			$prefix = substr($qname,0,strpos($qname,':'));
822
			if(isset($this->namespaces[$prefix])){
823
				return $this->namespaces[$prefix].':'.$name;
824
			} else {
825
				return $qname;
826
			}
827
		} else {
828
			return $qname;
829
		}
830
	}
831
832
    /**
833
    * returns the local part of a prefixed string
834
    * returns the original string, if not prefixed
835
    *
836
    * @param string $str The prefixed string
837
    * @return string The local part
838
    * @access public
839
    */
840
	function getLocalPart($str){
841
		if($sstr = strrchr($str,':')){
842
			// get unqualified name
843
			return substr( $sstr, 1 );
844
		} else {
845
			return $str;
846
		}
847
	}
848
849
	/**
850
    * returns the prefix part of a prefixed string
851
    * returns false, if not prefixed
852
    *
853
    * @param string $str The prefixed string
854
    * @return mixed The prefix or false if there is no prefix
855
    * @access public
856
    */
857
	function getPrefix($str){
858
		if($pos = strrpos($str,':')){
859
			// get prefix
860
			return substr($str,0,$pos);
861
		}
862
		return false;
863
	}
864
865
	/**
866
    * pass it a prefix, it returns a namespace
867
    *
868
    * @param string $prefix The prefix
869
    * @return mixed The namespace, false if no namespace has the specified prefix
870
    * @access public
871
    */
872
	function getNamespaceFromPrefix($prefix){
873
		if (isset($this->namespaces[$prefix])) {
874
			return $this->namespaces[$prefix];
875
		}
876
		//$this->setError("No namespace registered for prefix '$prefix'");
877
		return false;
878
	}
879
880
	/**
881
    * returns the prefix for a given namespace (or prefix)
882
    * or false if no prefixes registered for the given namespace
883
    *
884
    * @param string $ns The namespace
885
    * @return mixed The prefix, false if the namespace has no prefixes
886
    * @access public
887
    */
888
	function getPrefixFromNamespace($ns) {
889
		foreach ($this->namespaces as $p => $n) {
890
			if ($ns == $n || $ns == $p) {
891
			    $this->usedNamespaces[$p] = $n;
892
				return $p;
893
			}
894
		}
895
		return false;
896
	}
897
898
	/**
899
    * returns the time in ODBC canonical form with microseconds
900
    *
901
    * @return string The time in ODBC canonical form with microseconds
902
    * @access public
903
    */
904
	function getmicrotime() {
905
		if (function_exists('gettimeofday')) {
906
			$tod = gettimeofday();
907
			$sec = $tod['sec'];
908
			$usec = $tod['usec'];
909
		} else {
910
			$sec = time();
911
			$usec = 0;
912
		}
913
		return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
914
	}
915
916
	/**
917
	 * Returns a string with the output of var_dump
918
	 *
919
	 * @param mixed $data The variable to var_dump
920
	 * @return string The output of var_dump
921
	 * @access public
922
	 */
923
    function varDump($data) {
924
		ob_start();
925
		var_dump($data);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($data); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
926
		$ret_val = ob_get_contents();
927
		ob_end_clean();
928
		return $ret_val;
929
	}
930
931
	/**
932
	* represents the object as a string
933
	*
934
	* @return	string
935
	* @access   public
936
	*/
937
	function __toString() {
938
		return $this->varDump($this);
939
	}
940
}
941
942
// XML Schema Datatype Helper Functions
943
944
//xsd:dateTime helpers
945
946
/**
947
* convert unix timestamp to ISO 8601 compliant date string
948
*
949
* @param    int $timestamp Unix time stamp
950
* @param	boolean $utc Whether the time stamp is UTC or local
951
* @return	mixed ISO 8601 date string or false
952
* @access   public
953
*/
954
function timestamp_to_iso8601($timestamp,$utc=true){
955
	$datestr = date('Y-m-d\TH:i:sO',$timestamp);
956
	$pos = strrpos($datestr, "+");
957
	if ($pos === FALSE) {
958
		$pos = strrpos($datestr, "-");
959
	}
960
	if ($pos !== FALSE) {
961
		if (strlen($datestr) == $pos + 5) {
962
			$datestr = substr($datestr, 0, $pos + 3) . ':' . substr($datestr, -2);
963
		}
964
	}
965
	if($utc){
966
		$pattern = '/'.
967
		'([0-9]{4})-'.	// centuries & years CCYY-
968
		'([0-9]{2})-'.	// months MM-
969
		'([0-9]{2})'.	// days DD
970
		'T'.			// separator T
971
		'([0-9]{2}):'.	// hours hh:
972
		'([0-9]{2}):'.	// minutes mm:
973
		'([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
974
		'(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
975
		'/';
976
977
		if(preg_match($pattern,$datestr,$regs)){
978
			return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
979
		}
980
		return false;
981
	} else {
982
		return $datestr;
983
	}
984
}
985
986
/**
987
* convert ISO 8601 compliant date string to unix timestamp
988
*
989
* @param    string $datestr ISO 8601 compliant date string
990
* @return	mixed Unix timestamp (int) or false
991
* @access   public
992
*/
993
function iso8601_to_timestamp($datestr){
994
	$pattern = '/'.
995
	'([0-9]{4})-'.	// centuries & years CCYY-
996
	'([0-9]{2})-'.	// months MM-
997
	'([0-9]{2})'.	// days DD
998
	'T'.			// separator T
999
	'([0-9]{2}):'.	// hours hh:
1000
	'([0-9]{2}):'.	// minutes mm:
1001
	'([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
1002
	'(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
1003
	'/';
1004
	if(preg_match($pattern,$datestr,$regs)){
1005
		// not utc
1006
		if($regs[8] != 'Z'){
1007
			$op = substr($regs[8],0,1);
1008
			$h = substr($regs[8],1,2);
1009
			$m = substr($regs[8],strlen($regs[8])-2,2);
1010
			if($op == '-'){
1011
				$regs[4] = $regs[4] + $h;
1012
				$regs[5] = $regs[5] + $m;
1013
			} elseif($op == '+'){
1014
				$regs[4] = $regs[4] - $h;
1015
				$regs[5] = $regs[5] - $m;
1016
			}
1017
		}
1018
		return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
1019
//		return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
1020
	} else {
1021
		return false;
1022
	}
1023
}
1024
1025
/**
1026
* sleeps some number of microseconds
1027
*
1028
* @param    string $usec the number of microseconds to sleep
1029
* @access   public
1030
* @deprecated
1031
*/
1032
function usleepWindows($usec)
1033
{
1034
	$start = gettimeofday();
1035
	
1036
	do
1037
	{
1038
		$stop = gettimeofday();
1039
		$timePassed = 1000000 * ($stop['sec'] - $start['sec'])
1040
		+ $stop['usec'] - $start['usec'];
1041
	}
1042
	while ($timePassed < $usec);
1043
}
1044
1045
1046
?>