Issues (4967)

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.

src/wp-includes/compat.php (7 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
 * WordPress implementation for PHP functions either missing from older PHP versions or not included by default.
4
 *
5
 * @package PHP
6
 * @access private
7
 */
8
9
// If gettext isn't available
10
if ( !function_exists('_') ) {
11
	function _($string) {
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
This method's name is shorter than the configured minimum length of 3 characters.

Even though PHP does not care about the name of your methods, it is generally a good practice to choose method names which can be easily understood by other human readers.

Loading history...
12
		return $string;
13
	}
14
}
15
16
/**
17
 * Returns whether PCRE/u (PCRE_UTF8 modifier) is available for use.
18
 *
19
 * @ignore
20
 * @since 4.2.2
21
 * @access private
22
 *
23
 * @staticvar string $utf8_pcre
24
 *
25
 * @param bool $set - Used for testing only
26
 *             null   : default - get PCRE/u capability
27
 *             false  : Used for testing - return false for future calls to this function
28
 *             'reset': Used for testing - restore default behavior of this function
29
 */
30
function _wp_can_use_pcre_u( $set = null ) {
0 ignored issues
show
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
31
	static $utf8_pcre = 'reset';
32
33
	if ( null !== $set ) {
34
		$utf8_pcre = $set;
35
	}
36
37
	if ( 'reset' === $utf8_pcre ) {
38
		$utf8_pcre = @preg_match( '/^./u', 'a' );
39
	}
40
41
	return $utf8_pcre;
42
}
43
44
if ( ! function_exists( 'mb_substr' ) ) :
45
	/**
46
	 * Compat function to mimic mb_substr().
47
	 *
48
	 * @ignore
49
	 * @since 3.2.0
50
	 *
51
	 * @see _mb_substr()
52
	 *
53
	 * @param string      $str      The string to extract the substring from.
54
	 * @param int         $start    Position to being extraction from in `$str`.
55
	 * @param int|null    $length   Optional. Maximum number of characters to extract from `$str`.
56
	 *                              Default null.
57
	 * @param string|null $encoding Optional. Character encoding to use. Default null.
58
	 * @return string Extracted substring.
59
	 */
60
	function mb_substr( $str, $start, $length = null, $encoding = null ) {
61
		return _mb_substr( $str, $start, $length, $encoding );
62
	}
63
endif;
64
65
/**
66
 * Internal compat function to mimic mb_substr().
67
 *
68
 * Only understands UTF-8 and 8bit.  All other character sets will be treated as 8bit.
69
 * For $encoding === UTF-8, the $str input is expected to be a valid UTF-8 byte sequence.
70
 * The behavior of this function for invalid inputs is undefined.
71
 *
72
 * @ignore
73
 * @since 3.2.0
74
 *
75
 * @param string      $str      The string to extract the substring from.
76
 * @param int         $start    Position to being extraction from in `$str`.
77
 * @param int|null    $length   Optional. Maximum number of characters to extract from `$str`.
78
 *                              Default null.
79
 * @param string|null $encoding Optional. Character encoding to use. Default null.
80
 * @return string Extracted substring.
81
 */
82
function _mb_substr( $str, $start, $length = null, $encoding = null ) {
83
	if ( null === $encoding ) {
84
		$encoding = get_option( 'blog_charset' );
85
	}
86
87
	/*
88
	 * The solution below works only for UTF-8, so in case of a different
89
	 * charset just use built-in substr().
90
	 */
91
	if ( ! in_array( $encoding, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) {
92
		return is_null( $length ) ? substr( $str, $start ) : substr( $str, $start, $length );
93
	}
94
95
	if ( _wp_can_use_pcre_u() ) {
96
		// Use the regex unicode support to separate the UTF-8 characters into an array.
97
		preg_match_all( '/./us', $str, $match );
98
		$chars = is_null( $length ) ? array_slice( $match[0], $start ) : array_slice( $match[0], $start, $length );
99
		return implode( '', $chars );
100
	}
101
102
	$regex = '/(
103
		  [\x00-\x7F]                  # single-byte sequences   0xxxxxxx
104
		| [\xC2-\xDF][\x80-\xBF]       # double-byte sequences   110xxxxx 10xxxxxx
105
		| \xE0[\xA0-\xBF][\x80-\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
106
		| [\xE1-\xEC][\x80-\xBF]{2}
107
		| \xED[\x80-\x9F][\x80-\xBF]
108
		| [\xEE-\xEF][\x80-\xBF]{2}
109
		| \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
110
		| [\xF1-\xF3][\x80-\xBF]{3}
111
		| \xF4[\x80-\x8F][\x80-\xBF]{2}
112
	)/x';
113
114
	// Start with 1 element instead of 0 since the first thing we do is pop.
115
	$chars = array( '' );
116
	do {
117
		// We had some string left over from the last round, but we counted it in that last round.
118
		array_pop( $chars );
119
120
		/*
121
		 * Split by UTF-8 character, limit to 1000 characters (last array element will contain
122
		 * the rest of the string).
123
		 */
124
		$pieces = preg_split( $regex, $str, 1000, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
125
126
		$chars = array_merge( $chars, $pieces );
127
128
	// If there's anything left over, repeat the loop.
129
	} while ( count( $pieces ) > 1 && $str = array_pop( $pieces ) );
130
131
	return join( '', array_slice( $chars, $start, $length ) );
132
}
133
134
if ( ! function_exists( 'mb_strlen' ) ) :
135
	/**
136
	 * Compat function to mimic mb_strlen().
137
	 *
138
	 * @ignore
139
	 * @since 4.2.0
140
	 *
141
	 * @see _mb_strlen()
142
	 *
143
	 * @param string      $str      The string to retrieve the character length from.
144
	 * @param string|null $encoding Optional. Character encoding to use. Default null.
145
	 * @return int String length of `$str`.
146
	 */
147
	function mb_strlen( $str, $encoding = null ) {
148
		return _mb_strlen( $str, $encoding );
149
	}
150
endif;
151
152
/**
153
 * Internal compat function to mimic mb_strlen().
154
 *
155
 * Only understands UTF-8 and 8bit.  All other character sets will be treated as 8bit.
156
 * For $encoding === UTF-8, the `$str` input is expected to be a valid UTF-8 byte
157
 * sequence. The behavior of this function for invalid inputs is undefined.
158
 *
159
 * @ignore
160
 * @since 4.2.0
161
 *
162
 * @param string      $str      The string to retrieve the character length from.
163
 * @param string|null $encoding Optional. Character encoding to use. Default null.
164
 * @return int String length of `$str`.
165
 */
166
function _mb_strlen( $str, $encoding = null ) {
167
	if ( null === $encoding ) {
168
		$encoding = get_option( 'blog_charset' );
169
	}
170
171
	/*
172
	 * The solution below works only for UTF-8, so in case of a different charset
173
	 * just use built-in strlen().
174
	 */
175
	if ( ! in_array( $encoding, array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) ) ) {
176
		return strlen( $str );
177
	}
178
179
	if ( _wp_can_use_pcre_u() ) {
180
		// Use the regex unicode support to separate the UTF-8 characters into an array.
181
		preg_match_all( '/./us', $str, $match );
182
		return count( $match[0] );
183
	}
184
185
	$regex = '/(?:
186
		  [\x00-\x7F]                  # single-byte sequences   0xxxxxxx
187
		| [\xC2-\xDF][\x80-\xBF]       # double-byte sequences   110xxxxx 10xxxxxx
188
		| \xE0[\xA0-\xBF][\x80-\xBF]   # triple-byte sequences   1110xxxx 10xxxxxx * 2
189
		| [\xE1-\xEC][\x80-\xBF]{2}
190
		| \xED[\x80-\x9F][\x80-\xBF]
191
		| [\xEE-\xEF][\x80-\xBF]{2}
192
		| \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences   11110xxx 10xxxxxx * 3
193
		| [\xF1-\xF3][\x80-\xBF]{3}
194
		| \xF4[\x80-\x8F][\x80-\xBF]{2}
195
	)/x';
196
197
	// Start at 1 instead of 0 since the first thing we do is decrement.
198
	$count = 1;
199
	do {
200
		// We had some string left over from the last round, but we counted it in that last round.
201
		$count--;
202
203
		/*
204
		 * Split by UTF-8 character, limit to 1000 characters (last array element will contain
205
		 * the rest of the string).
206
		 */
207
		$pieces = preg_split( $regex, $str, 1000 );
208
209
		// Increment.
210
		$count += count( $pieces );
211
212
	// If there's anything left over, repeat the loop.
213
	} while ( $str = array_pop( $pieces ) );
214
215
	// Fencepost: preg_split() always returns one extra item in the array.
216
	return --$count;
217
}
218
219
if ( !function_exists('hash_hmac') ):
220
/**
221
 * Compat function to mimic hash_hmac().
222
 *
223
 * @ignore
224
 * @since 3.2.0
225
 *
226
 * @see _hash_hmac()
227
 *
228
 * @param string $algo       Hash algorithm. Accepts 'md5' or 'sha1'.
229
 * @param string $data       Data to be hashed.
230
 * @param string $key        Secret key to use for generating the hash.
231
 * @param bool   $raw_output Optional. Whether to output raw binary data (true),
232
 *                           or lowercase hexits (false). Default false.
233
 * @return string|false The hash in output determined by `$raw_output`. False if `$algo`
234
 *                      is unknown or invalid.
235
 */
236
function hash_hmac($algo, $data, $key, $raw_output = false) {
237
	return _hash_hmac($algo, $data, $key, $raw_output);
238
}
239
endif;
240
241
/**
242
 * Internal compat function to mimic hash_hmac().
243
 *
244
 * @ignore
245
 * @since 3.2.0
246
 *
247
 * @param string $algo       Hash algorithm. Accepts 'md5' or 'sha1'.
248
 * @param string $data       Data to be hashed.
249
 * @param string $key        Secret key to use for generating the hash.
250
 * @param bool   $raw_output Optional. Whether to output raw binary data (true),
251
 *                           or lowercase hexits (false). Default false.
252
 * @return string|false The hash in output determined by `$raw_output`. False if `$algo`
253
 *                      is unknown or invalid.
254
 */
255
function _hash_hmac($algo, $data, $key, $raw_output = false) {
256
	$packs = array('md5' => 'H32', 'sha1' => 'H40');
257
258
	if ( !isset($packs[$algo]) )
259
		return false;
260
261
	$pack = $packs[$algo];
262
263
	if (strlen($key) > 64)
264
		$key = pack($pack, $algo($key));
265
266
	$key = str_pad($key, 64, chr(0));
267
268
	$ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));
269
	$opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));
270
271
	$hmac = $algo($opad . pack($pack, $algo($ipad . $data)));
272
273
	if ( $raw_output )
274
		return pack( $pack, $hmac );
275
	return $hmac;
276
}
277
278
if ( !function_exists('json_encode') ) {
279
	function json_encode( $string ) {
280
		global $wp_json;
281
282 View Code Duplication
		if ( ! ( $wp_json instanceof Services_JSON ) ) {
283
			require_once( ABSPATH . WPINC . '/class-json.php' );
284
			$wp_json = new Services_JSON();
285
		}
286
287
		return $wp_json->encodeUnsafe( $string );
288
	}
289
}
290
291
if ( !function_exists('json_decode') ) {
292
	/**
293
	 * @global Services_JSON $wp_json
294
	 * @param string $string
295
	 * @param bool   $assoc_array
296
	 * @return object|array
0 ignored issues
show
Should the return type not be boolean|null|integer|double|string|array|stdClass? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
297
	 */
298
	function json_decode( $string, $assoc_array = false ) {
299
		global $wp_json;
300
301 View Code Duplication
		if ( ! ($wp_json instanceof Services_JSON ) ) {
302
			require_once( ABSPATH . WPINC . '/class-json.php' );
303
			$wp_json = new Services_JSON();
304
		}
305
306
		$res = $wp_json->decode( $string );
307
		if ( $assoc_array )
308
			$res = _json_decode_object_helper( $res );
309
		return $res;
310
	}
311
312
	/**
313
	 * @param object $data
314
	 * @return array
315
	 */
316
	function _json_decode_object_helper($data) {
317
		if ( is_object($data) )
318
			$data = get_object_vars($data);
319
		return is_array($data) ? array_map(__FUNCTION__, $data) : $data;
320
	}
321
}
322
323
if ( ! function_exists( 'hash_equals' ) ) :
324
/**
325
 * Timing attack safe string comparison
326
 *
327
 * Compares two strings using the same time whether they're equal or not.
328
 *
329
 * This function was added in PHP 5.6.
330
 *
331
 * Note: It can leak the length of a string when arguments of differing length are supplied.
332
 *
333
 * @since 3.9.2
334
 *
335
 * @param string $a Expected string.
336
 * @param string $b Actual, user supplied, string.
337
 * @return bool Whether strings are equal.
338
 */
339
function hash_equals( $a, $b ) {
340
	$a_length = strlen( $a );
341
	if ( $a_length !== strlen( $b ) ) {
342
		return false;
343
	}
344
	$result = 0;
345
346
	// Do not attempt to "optimize" this.
347
	for ( $i = 0; $i < $a_length; $i++ ) {
348
		$result |= ord( $a[ $i ] ) ^ ord( $b[ $i ] );
349
	}
350
351
	return $result === 0;
352
}
353
endif;
354
355
// JSON_PRETTY_PRINT was introduced in PHP 5.4
356
// Defined here to prevent a notice when using it with wp_json_encode()
357
if ( ! defined( 'JSON_PRETTY_PRINT' ) ) {
358
	define( 'JSON_PRETTY_PRINT', 128 );
359
}
360
361
if ( ! function_exists( 'json_last_error_msg' ) ) :
362
	/**
363
	 * Retrieves the error string of the last json_encode() or json_decode() call.
364
	 *
365
	 * @since 4.4.0
366
	 *
367
	 * @internal This is a compatibility function for PHP <5.5
368
	 *
369
	 * @return bool|string Returns the error message on success, "No Error" if no error has occurred,
0 ignored issues
show
Consider making the return type a bit more specific; maybe use false|string.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
370
	 *                     or false on failure.
371
	 */
372
	function json_last_error_msg() {
373
		// See https://core.trac.wordpress.org/ticket/27799.
374
		if ( ! function_exists( 'json_last_error' ) ) {
375
			return false;
376
		}
377
378
		$last_error_code = json_last_error();
379
380
		// Just in case JSON_ERROR_NONE is not defined.
381
		$error_code_none = defined( 'JSON_ERROR_NONE' ) ? JSON_ERROR_NONE : 0;
382
383
		switch ( true ) {
384
			case $last_error_code === $error_code_none:
385
				return 'No error';
386
387
			case defined( 'JSON_ERROR_DEPTH' ) && JSON_ERROR_DEPTH === $last_error_code:
388
				return 'Maximum stack depth exceeded';
389
390
			case defined( 'JSON_ERROR_STATE_MISMATCH' ) && JSON_ERROR_STATE_MISMATCH === $last_error_code:
391
				return 'State mismatch (invalid or malformed JSON)';
392
393
			case defined( 'JSON_ERROR_CTRL_CHAR' ) && JSON_ERROR_CTRL_CHAR === $last_error_code:
394
				return 'Control character error, possibly incorrectly encoded';
395
396
			case defined( 'JSON_ERROR_SYNTAX' ) && JSON_ERROR_SYNTAX === $last_error_code:
397
				return 'Syntax error';
398
399
			case defined( 'JSON_ERROR_UTF8' ) && JSON_ERROR_UTF8 === $last_error_code:
400
				return 'Malformed UTF-8 characters, possibly incorrectly encoded';
401
402
			case defined( 'JSON_ERROR_RECURSION' ) && JSON_ERROR_RECURSION === $last_error_code:
403
				return 'Recursion detected';
404
405
			case defined( 'JSON_ERROR_INF_OR_NAN' ) && JSON_ERROR_INF_OR_NAN === $last_error_code:
406
				return 'Inf and NaN cannot be JSON encoded';
407
408
			case defined( 'JSON_ERROR_UNSUPPORTED_TYPE' ) && JSON_ERROR_UNSUPPORTED_TYPE === $last_error_code:
409
				return 'Type is not supported';
410
411
			default:
412
				return 'An unknown error occurred';
413
		}
414
	}
415
endif;
416
417
if ( ! interface_exists( 'JsonSerializable' ) ) {
418
	define( 'WP_JSON_SERIALIZE_COMPATIBLE', true );
419
	/**
420
	 * JsonSerializable interface.
421
	 *
422
	 * Compatibility shim for PHP <5.4
423
	 *
424
	 * @link https://secure.php.net/jsonserializable
425
	 *
426
	 * @since 4.4.0
427
	 */
428
	interface JsonSerializable {
429
		public function jsonSerialize();
0 ignored issues
show
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
430
	}
431
}
432
433
// random_int was introduced in PHP 7.0
434
if ( ! function_exists( 'random_int' ) ) {
435
	require ABSPATH . WPINC . '/random_compat/random.php';
436
}
437
438
if ( ! function_exists( 'array_replace_recursive' ) ) :
439
	/**
440
	 * PHP-agnostic version of {@link array_replace_recursive()}.
441
	 *
442
	 * The array_replace_recursive() function is a PHP 5.3 function. WordPress
443
	 * currently supports down to PHP 5.2, so this method is a workaround
444
	 * for PHP 5.2.
445
	 *
446
	 * Note: array_replace_recursive() supports infinite arguments, but for our use-
447
	 * case, we only need to support two arguments.
448
	 *
449
	 * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement.
450
	 *
451
	 * @since 4.5.3
452
	 *
453
	 * @see https://secure.php.net/manual/en/function.array-replace-recursive.php#109390
454
	 *
455
	 * @param  array $base         Array with keys needing to be replaced.
456
	 * @param  array $replacements Array with the replaced keys.
457
	 *
458
	 * @return array
459
	 */
460
	function array_replace_recursive( $base = array(), $replacements = array() ) {
0 ignored issues
show
The parameter $replacements is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
461
		foreach ( array_slice( func_get_args(), 1 ) as $replacements ) {
462
			$bref_stack = array( &$base );
463
			$head_stack = array( $replacements );
464
465
			do {
466
				end( $bref_stack );
467
468
				$bref = &$bref_stack[ key( $bref_stack ) ];
469
				$head = array_pop( $head_stack );
470
471
				unset( $bref_stack[ key( $bref_stack ) ] );
472
473
				foreach ( array_keys( $head ) as $key ) {
474
					if ( isset( $key, $bref ) &&
475
					     isset( $bref[ $key ] ) && is_array( $bref[ $key ] ) &&
476
					     isset( $head[ $key ] ) && is_array( $head[ $key ] )
477
					) {
478
						$bref_stack[] = &$bref[ $key ];
479
						$head_stack[] = $head[ $key ];
480
					} else {
481
						$bref[ $key ] = $head[ $key ];
482
					}
483
				}
484
			} while ( count( $head_stack ) );
485
		}
486
487
		return $base;
488
	}
489
endif;
490
491
// SPL can be disabled on PHP 5.2
492
if ( ! function_exists( 'spl_autoload_register' ) ):
493
	$_wp_spl_autoloaders = array();
494
495
	/**
496
	 * Autoloader compatibility callback.
497
	 *
498
	 * @since 4.6.0
499
	 *
500
	 * @param string $classname Class to attempt autoloading.
501
	 */
502
	function __autoload( $classname ) {
503
		global $_wp_spl_autoloaders;
504
		foreach ( $_wp_spl_autoloaders as $autoloader ) {
505
			if ( ! is_callable( $autoloader ) ) {
506
				// Avoid the extra warning if the autoloader isn't callable.
507
				continue;
508
			}
509
510
			call_user_func( $autoloader, $classname );
511
512
			// If it has been autoloaded, stop processing.
513
			if ( class_exists( $classname, false ) ) {
514
				return;
515
			}
516
		}
517
	}
518
519
	/**
520
	 * Registers a function to be autoloaded.
521
	 *
522
	 * @since 4.6.0
523
	 *
524
	 * @param callable $autoload_function The function to register.
525
	 * @param bool     $throw             Optional. Whether the function should throw an exception
526
	 *                                    if the function isn't callable. Default true.
527
	 * @param bool     $prepend           Whether the function should be prepended to the stack.
528
	 *                                    Default false.
529
	 */
530
	function spl_autoload_register( $autoload_function, $throw = true, $prepend = false ) {
531
		if ( $throw && ! is_callable( $autoload_function ) ) {
532
			// String not translated to match PHP core.
533
			throw new Exception( 'Function not callable' );
534
		}
535
536
		global $_wp_spl_autoloaders;
537
538
		// Don't allow multiple registration.
539
		if ( in_array( $autoload_function, $_wp_spl_autoloaders ) ) {
540
			return;
541
		}
542
543
		if ( $prepend ) {
544
			array_unshift( $_wp_spl_autoloaders, $autoload_function );
545
		} else {
546
			$_wp_spl_autoloaders[] = $autoload_function;
547
		}
548
	}
549
550
	/**
551
	 * Unregisters an autoloader function.
552
	 *
553
	 * @since 4.6.0
554
	 *
555
	 * @param callable $function The function to unregister.
556
	 * @return bool True if the function was unregistered, false if it could not be.
557
	 */
558
	function spl_autoload_unregister( $function ) {
559
		global $_wp_spl_autoloaders;
560
		foreach ( $_wp_spl_autoloaders as &$autoloader ) {
561
			if ( $autoloader === $function ) {
562
				unset( $autoloader );
563
				return true;
564
			}
565
		}
566
567
		return false;
568
	}
569
570
	/**
571
	 * Retrieves the registered autoloader functions.
572
	 *
573
	 * @since 4.6.0
574
	 *
575
	 * @return array List of autoloader functions.
576
	 */
577
	function spl_autoload_functions() {
578
		return $GLOBALS['_wp_spl_autoloaders'];
579
	}
580
endif;
581