Repository: WordPress/WordPress-Coding-Standards (php)

Issue:
NonceVerification: ignore unsetting of superglobal values
## Bug Description

When all that's done with a superglobal value is to _unset_ it, no nonceverification should be necessary.

Currently, the sniff will throw a warning for this:
```
 148 | WARNING | Processing form data without nonce verification.
```

## Minimal Code Snippet

```php
// OK.
unset( $_GET['meta-box-loader'] );

// Not okay.
do_something_with( $_GET['meta-box-loader'] );
```

## Error Code
`WordPress.Security.NonceVerification.Recommended`

## Environment

| Question               | Answer
| ------------------------| -------
| PHP version             | any
| PHP_CodeSniffer version | `master`
| WPCS version            | `develop`
| WPCS install type       | N/A
| IDE (if relevant)       | N/A


## Additional Context (optional)
Might be a good idea to check in with the security team to confirm whether they agree with the above.

## Tested Against `develop` branch?
- [x] I have verified the issue still exists in the `develop` branch of WPCS.


Pull request description:
Security/NonceVerification: use PHPCSUtils, modern PHP + other bug fixes
### Security/NonceVerification: rename test case file

... to allow for splitting the test case file up for properly pure tests and for adding additional test case files.

### Security/NonceVerification: move test involving global scope to separate test case file

This prevents tests which involve the global scope from influencing each other (which was happening for an upcoming bug fix).

### Security/NonceVerification: add some extra tests involving global scope

... to raise code coverage.

### Security/NonceVerification: test with empty()

There were plenty of tests which checked the nonce verification in combination with a superglobal being used in `isset()` and `array_key_exists()`, but none in combination with `empty()`, while the sniff does handle that as well and treats it the same as `isset()`/`array_key_exists()`.

This adjusts a few pre-existing tests to make sure that the handling of `empty()` is covered by tests too.

Note: it is important that these have separate tests as `empty()` has its own token.

### Security/NonceVerification: remove redundant function call

The `NonceVerification` sniff extends the WPCS base `Sniff` class, so has access to `$this->tokens`. No need for the call to `$phpcsFile->getTokens()`.

### Security/NonceVerification: remove redundant local variable

No need to store the sub-array if it's only accessed a couple of times.

### Security/NonceVerification: changes to $addedCustomFunctions property

* As the sniff itself now only handles the nonce functions, we don't need a multi-dimensional array (the `'nonce'` subkey).
* To prevent potential conflicts with properties in traits, make the property name more specific.
* And even though the class has not been made `final`, I do think it makes sense to make this property `private`.
    The property is only intended for use by the (`protected`) `mergeFunctionLists()` method. If a child class overloads that method, they are responsible for whatever properties their overloaded method needs.

### Security/NonceVerification: bug fix - $_FILES not $_FILE

PHP does not have a `$_FILE` superglobal...
Ref: https://www.php.net/manual/en/language.variables.superglobals.php

Looks like this typo has been in this sniff from the start:
* WordPress/WordPress-Coding-Standards#325
* 1480350

A similar typo elsewhere was fixed long time ago: WordPress/WordPress-Coding-Standards#368

Adjusted some existing tests now to safeguard this.

### Security/NonceVerification: move results cache to property

No idea why this was made a function local `static` variable, but it makes more sense (and results in cleaner code) if we cache this in a property.

As the cache wasn't previously accessible from child classes anyway, I'm making this a `private` property.

### Security/NonceVerification: improve caching

As things were, the "cache" would only ever contain information about one search.

Now, while this is fine for files which have all code in the global scope òr all code within function scopes, for mixed files, this makes the cache useless as the cache would be reset based on global or function scope and results would not be re-used as intended.

In this commit, I'm changing the cache to a multi-dimensional array, which can hold information about all searches done within a file, which should improve performance for (large) mixed files.

When I then add some debug code, you can see the difference based on the new test file:
**Before**
```
Start: 0
End: 321
----
Cache re-used
----
Cache re-used
----
Start: 113
End: 150
----
Cache re-used
----
Start: 0
End: 188
----
Cache re-used
----
Start: 212
End: 249
----
Cache re-used
----
Start: 0
End: 321
----
Cache re-used
```

**After**
```
Start: 0
End: 321
----
Cache re-used
----
Cache re-used
----
Start: 113
End: 150
----
Cache re-used
----
Cache re-used
----
Cache re-used
----
Start: 212
End: 249
----
Cache re-used
----
Cache re-used
----
Cache re-used
```

### Security/NonceVerification: add cache getter and setter methods

Move the logic for getting and setting the cache to separate methods.

Includes removing the cache "priming", which isn't actually necessary as the cache will be set, no matter what, before the function returns.

Even though the class isn't `final`, as the cache was previously not accessible from child classes anyway, I'm making these methods `private`.

### Security/NonceVerification: implement PHPCSUtils

### Security/NonceVerification: bug fix - ignore OO properties

Properties with the same name as a superglobal should be ignored as these are not the actual superglobal.

Note: I'm not adding a similar check for function parameters as a function parameter with the same name as a superglobal with cause a fatal error since PHP 5.4, so IMO checking for that is not relevant.

Includes tests.

### Security/NonceVerification: bug fix - disregard assignments via list()

Sometimes I hate my brain....

Okay, so, while hopefully not common, assignments to superglobals can also happen via list constructs. As this sniff (correctly) disregards all assignments as safe, we should also disregard list assignments.

This commit makes it so.

Includes tests safeguarding the fix, which would previously lead to false positives.

### Security/NonceVerification: new needs_nonce_check() method

The "does this superglobal use need a nonce ?" check was previously contained in the `process_token()` method and the "must the nonce check be done before or is it allowed after ?" check was done in the `has_nonce_check()` method.

With an eye on expanding the number of checks in this field, I'm moving the logic for these two checks to a new `needs_nonce_check()` method which will either return (string) `'before|after'` or `false` when no nonce check is needed.

As the class isn't `final`, I'm making this a `protected` method (instead of `private`) to allow some flexibility for child classes.

Note: I'm deliberately _not_ moving the (new) "is OO property" check to the `needs_nonce_check()` method as in that case it isn't a superglobal in the first place, so not a variable this sniff should look at.

### Security/NonceVerification: efficiency fix - check for being in a nonce verification method early

As things were, if the superglobal being examined was _in_ a call to one of the nonce verification functions, the sniff would still loop from the start of the scope (start of the function/file) to the current token before coming to that conclusion.
This is, of course, highly inefficient for long functions/large files.

I've been in two minds about whether to add this check to the `needs_nonce_check()` method or the `has_nonce_check()` method.
For optimal efficiency, the best place is at the start of the `needs_nonce_check()` method as it will prevent having to do all the other "is in type check, is in sanitization function" checks, which are redundant if the call is a nonce check itself.
And after all, if the current superglobal is _in_ a nonce check, it doesn't _need_ a nonce check as it already has one.

To allow for caching the found nonce check, the gathering of the basic information needed for the caching has to be moved to the `process_token()` method though, so both the `needs_nonce_check()` method, as well as the `has_nonce_check()` method now get an extra `$cache_keys` parameter.

It also means that the lists of custom and known nonce verification functions have to be merged earlier, so the call to `$this->mergeFunctionLists()` has been moved up.

### Security/NonceVerification: bug fix - allow unsetting of superglobal key without nonce verification

If all that's being done is to unset a value, there is no risk, so let the sniff stay silent.

Includes tests.

Note: I've checked in with the security team to confirm this is the correct behaviour.

Fixes #1981

### Security/NonceVerification: add test with PHP 7.0+ null coalesce operator

This is already being handled correctly as the WPCS `VariableHelper::is_comparison()` method (optionally) treats null coalesce the same as other comparison operators.

This behaviour is now safeguarded with a test.

### Security/NonceVerification: support PHP 7.4+ null coalesce equals

Assignments to a superglobal using the PHP 7.4 null coalesce equals operator should be treated the same as if the variable was used in an `isset()` or with a `??` (PHP 7.0 null coalesce) operator. I.e. as long as there is a nonce check _before_ or _after_, it's fine.

As things were, null coalesce equals was treated the same as an assignment (which does not need nonce verification), even though the value of the superglobal key may not be overwritten due to the use of null coalescence.

To fix this, I'm adding a new `$include_coalesce` parameter to the `VariableHelper::is_assignment()` method to allow the method to include/exclude the null coalesce equal operator based on the value passed to that parameter.
The default value of the parameter is `true` which maintains the pre-existing behaviour of the function.

This mirrors the similar method signature and behaviour in the `VariableHelper::is_comparison()` method.

The `NonceVerificationSniff::needs_nonce_check()` method will now call that method twice, once to exclude variable assignments (with the exception of null coalesce assignments) and once to allow null coalesce equals assignments to set the expectation for the nonce verification to "after".

This may seem inefficient (and is in a way), but the footprint of the `VariableHelper::is_assignment()` method is small and the duplicate code we'd need to handle this differently not worth the effort.

Includes tests safeguarding the change.

### Security/NonceVerification: disregard PHP 7.4 arrow function when determining search scope

As arrow functions are "open", we should not limit a search for a nonce verification to the scope of the arrow function.

Includes tests documenting the behaviour.

### Security/NonceVerification: disregard nonce check in PHP 7.4 arrow function when searching

As an arrow function is a callback and we don't trace whether a callback is called, any nonce check found within an arrow function should be disregarded.
This mirrors the sniff behaviour with regards to closures, meaning nonce checks in nested arrow functions and in nested closures will now be treated the same.

Includes test.

### Security/NonceVerification: add test with PHP 8.0+ match construct

This just adds a test documenting the behaviour in combination with `match` constructs.

The use of `$_POST` in the `default` branch should realistically be flagged as the nonce check will not have been executed (as it is executed conditionally, only for `'value'`.

However, this is a structural flaw in the sniff as a whole, as it doesn't check at all whether a nonce check is done conditionally or not.

Example:
```php
function test() {
	if ( $foo ) {
		wp_verify_nonce( $_POST['nonce'] );
	} else {
		echo $_POST['key']; // Should be flagged as nonce check will definitely not have run, but isn't.
	}

	echo $_POST['key']; // Should potentially be flagged, depending on value of $foo, but isn't.
}
```

If would be very hard to fix this as a lot of conditions involve variables and we don't have access to runtime values, so it would, in most cases, be very hard to determine whether a conditionally run nonce check will have run.

With that in mind, I think allowing the sniff to treat `match` the same as other conditional constructs are currently treated is the correct behaviour for now.

If/when at some point in the future someone would attempt to make the conditionally run nonce check more precise, `match` should be handled the same as all other control structures.

### Security/NonceVerification: add test with PHP 8.1+ nested enum

Just like other nested constructs, the search for a nonce check should limit itself to the current scope and skip over nested closed scopes/not look outside the current scope.

This is already handled correctly for enums due to the sniff using the PHPCSUtils `Collections::closedScopes()` method.

This just adds tests to safeguard this.

### Security/NonceVerification: various documentation tweaks 

Patch:
diff --git a/WordPress/Helpers/VariableHelper.php b/WordPress/Helpers/VariableHelper.php
index dc3c7a87..0fb6720a 100644
--- a/WordPress/Helpers/VariableHelper.php
+++ b/WordPress/Helpers/VariableHelper.php
@@ -201,15 +201,22 @@ final class VariableHelper {
 	 * @since 3.0.0 - Moved from the Sniff class to this class.
 	 *              - Visibility is now `public` (was `protected`) and the method `static`.
 	 *              - The `$phpcsFile` parameter was added.
+	 *              - The `$include_coalesce` parameter was added.
 	 *
-	 * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
-	 * @param int                         $stackPtr  The index of the token in the stack.
-	 *                                               This must point to either a T_VARIABLE or
-	 *                                               T_CLOSE_SQUARE_BRACKET token.
+	 * @param \PHP_CodeSniffer\Files\File $phpcsFile        The file being scanned.
+	 * @param int                         $stackPtr         The index of the token in the stack.
+	 *                                                      This must point to either a T_VARIABLE or
+	 *                                                      T_CLOSE_SQUARE_BRACKET token.
+	 * @param bool                        $include_coalesce Optional. Whether or not to regard the null
+	 *                                                      coalesce operator - ?? - as a comparison operator.
+	 *                                                      Defaults to true.
+	 *                                                      Null coalesce is a special comparison operator in this
+	 *                                                      sense as it doesn't compare a variable to whatever is
+	 *                                                      on the other side of the comparison operator.
 	 *
 	 * @return bool Whether the token is a variable being assigned a value.
 	 */
-	public static function is_assignment( File $phpcsFile, $stackPtr ) {
+	public static function is_assignment( File $phpcsFile, $stackPtr, $include_coalesce = true ) {
 		$tokens = $phpcsFile->getTokens();
 		if ( isset( $tokens[ $stackPtr ] ) === false ) {
 			return false;
@@ -232,8 +239,13 @@ final class VariableHelper {
 			return false;
 		}
 
+		$assignmentTokens = Tokens::$assignmentTokens;
+		if ( false === $include_coalesce ) {
+			unset( $assignmentTokens[ \T_COALESCE_EQUAL ] );
+		}
+
 		// If the next token is an assignment, that's all we need to know.
-		if ( isset( Tokens::$assignmentTokens[ $tokens[ $next_non_empty ]['code'] ] ) ) {
+		if ( isset( $assignmentTokens[ $tokens[ $next_non_empty ]['code'] ] ) ) {
 			return true;
 		}
 
@@ -241,7 +253,7 @@ final class VariableHelper {
 		if ( \T_OPEN_SQUARE_BRACKET === $tokens[ $next_non_empty ]['code']
 			&& isset( $tokens[ $next_non_empty ]['bracket_closer'] )
 		) {
-			return self::is_assignment( $phpcsFile, $tokens[ $next_non_empty ]['bracket_closer'] );
+			return self::is_assignment( $phpcsFile, $tokens[ $next_non_empty ]['bracket_closer'], $include_coalesce );
 		}
 
 		return false;
diff --git a/WordPress/Sniffs/Security/NonceVerificationSniff.php b/WordPress/Sniffs/Security/NonceVerificationSniff.php
index 13c77332..2d460606 100644
--- a/WordPress/Sniffs/Security/NonceVerificationSniff.php
+++ b/WordPress/Sniffs/Security/NonceVerificationSniff.php
@@ -9,8 +9,12 @@
 
 namespace WordPressCS\WordPress\Sniffs\Security;
 
-use PHP_CodeSniffer\Util\Tokens;
+use PHPCSUtils\Tokens\Collections;
+use PHPCSUtils\Utils\Conditions;
+use PHPCSUtils\Utils\Context;
+use PHPCSUtils\Utils\Lists;
 use PHPCSUtils\Utils\MessageHelper;
+use PHPCSUtils\Utils\Scopes;
 use WordPressCS\WordPress\Helpers\ContextHelper;
 use WordPressCS\WordPress\Helpers\RulesetPropertyHelper;
 use WordPressCS\WordPress\Helpers\UnslashingFunctionsHelper;
@@ -27,6 +31,7 @@ use WordPressCS\WordPress\Sniff;
  * @since   0.5.0
  * @since   0.13.0 Class name changed: this class is now namespaced.
  * @since   1.0.0  This sniff has been moved from the `CSRF` category to the `Security` category.
+ * @since   3.0.0  This sniff has received significant updates to its logic and structure.
  *
  * @uses    \WordPressCS\WordPress\Helpers\SanitizingFunctionsTrait::$customSanitizingFunctions
  * @uses    \WordPressCS\WordPress\Helpers\SanitizingFunctionsTrait::$customUnslashingSanitizingFunctions
@@ -44,7 +49,7 @@ class NonceVerificationSniff extends Sniff {
 	 */
 	protected $superglobals = array(
 		'$_POST'    => true,
-		'$_FILE'    => true,
+		'$_FILES'   => true,
 		'$_GET'     => false,
 		'$_REQUEST' => false,
 	);
@@ -58,6 +63,22 @@ class NonceVerificationSniff extends Sniff {
 	 */
 	public $customNonceVerificationFunctions = array();
 
+	/**
+	 * List of the functions which verify nonces.
+	 *
+	 * @since 0.5.0
+	 * @since 0.11.0 Changed from public static to protected non-static.
+	 * @since 3.0.0  - Moved from the generic `Sniff` class to this class.
+	 *               - Visibility changed from `protected` to `private.
+	 *
+	 * @var array
+	 */
+	private $nonceVerificationFunctions = array(
+		'wp_verify_nonce'     => true,
+		'check_admin_referer' => true,
+		'check_ajax_referer'  => true,
+	);
+
 	/**
 	 * Cache of previously added custom functions.
 	 *
@@ -66,28 +87,36 @@ class NonceVerificationSniff extends Sniff {
 	 * @since 0.5.0
 	 * @since 0.11.0 - Changed from public static to protected non-static.
 	 *               - Changed the format from simple bool to array.
+	 * @since 3.0.0  - Property rename from `$addedCustomFunctions` to `$addedCustomNonceFunctions`.
+	 *               - Visibility changed from `protected` to `private.
+	 *               - Format changed from a multi-dimensional array to a single-dimensional array.
 	 *
 	 * @var array
 	 */
-	protected $addedCustomFunctions = array(
-		'nonce' => array(),
-	);
+	private $addedCustomNonceFunctions = array();
 
 	/**
-	 * List of the functions which verify nonces.
+	 * Information on the all scopes that were checked to find a nonce verification in a particular file.
 	 *
-	 * @since 0.5.0
-	 * @since 0.11.0 Changed from public static to protected non-static.
-	 * @since 3.0.0  - Moved from the generic `Sniff` class to this class.
-	 *               - Visibility changed from `protected` to `private.
+	 * The array will be in the following format:
+	 * ```
+	 * array(
+	 *   'file'  => (string) The name of the file.
+	 *   'cache' => (array) array(
+	 *     # => array(             The key is the token pointer to the "start" position.
+	 *       'end'   => (int)      The token pointer to the "end" position.
+	 *       'nonce' => (int|bool) The token pointer where n nonce check
+	 *                             was found, or false if none was found.
+	 *     )
+	 *   )
+	 * )
+	 * ```
 	 *
-	 * @var array
+	 * @since 3.0.0
+	 *
+	 * @var array<string, mixed>
 	 */
-	private $nonceVerificationFunctions = array(
-		'wp_verify_nonce'     => true,
-		'check_admin_referer' => true,
-		'check_ajax_referer'  => true,
-	);
+	private $cached_results;
 
 	/**
 	 * Returns an array of tokens this test wants to listen for.
@@ -95,10 +124,10 @@ class NonceVerificationSniff extends Sniff {
 	 * @return array
 	 */
 	public function register() {
+		$targets  = array( \T_VARIABLE => \T_VARIABLE );
+		$targets += Collections::listOpenTokensBC(); // We need to skip over lists.
 
-		return array(
-			\T_VARIABLE,
-		);
+		return $targets;
 	}
 
 	/**
@@ -106,153 +135,181 @@ class NonceVerificationSniff extends Sniff {
 	 *
 	 * @param int $stackPtr The position of the current token in the stack.
 	 *
-	 * @return void
+	 * @return int|void Integer stack pointer to skip forward or void to continue
+	 *                  normal file processing.
 	 */
 	public function process_token( $stackPtr ) {
+		// Skip over lists as whatever is in those will always be assignments.
+		if ( isset( Collections::listOpenTokensBC()[ $this->tokens[ $stackPtr ]['code'] ] ) ) {
+			$open_close = Lists::getOpenClose( $this->phpcsFile, $stackPtr );
+			$skip_to    = $stackPtr;
+			if ( false !== $open_close ) {
+				$skip_to = $open_close['closer'];
+			}
 
-		$instance = $this->tokens[ $stackPtr ];
+			return $skip_to;
+		}
 
-		if ( ! isset( $this->superglobals[ $instance['content'] ] ) ) {
+		if ( ! isset( $this->superglobals[ $this->tokens[ $stackPtr ]['content'] ] ) ) {
 			return;
 		}
 
-		if ( VariableHelper::is_assignment( $this->phpcsFile, $stackPtr ) ) {
+		if ( Scopes::isOOProperty( $this->phpcsFile, $stackPtr ) ) {
+			// Property with the same name as a superglobal. Not our target.
 			return;
 		}
 
+		// Determine the cache keys for this item.
+		$cache_keys = array(
+			'file'  => $this->phpcsFile->getFilename(),
+			'start' => 0,
+			'end'   => $stackPtr,
+		);
+
+		// If we're in a function, only look inside of it.
+		// This doesn't take arrow functions into account as those are "open".
+		$functionPtr = Conditions::getLastCondition( $this->phpcsFile, $stackPtr, array( \T_FUNCTION, \T_CLOSURE ) );
+		if ( false !== $functionPtr ) {
+			$cache_keys['start'] = $this->tokens[ $functionPtr ]['scope_opener'];
+		}
+
 		$this->mergeFunctionLists();
 
-		if ( $this->has_nonce_check( $stackPtr ) ) {
+		$needs_nonce = $this->needs_nonce_check( $stackPtr, $cache_keys );
+		if ( false === $needs_nonce ) {
 			return;
 		}
 
+		if ( $this->has_nonce_check( $stackPtr, $cache_keys, ( 'after' === $needs_nonce ) ) ) {
+			return;
+		}
+
+		// If we're still here, no nonce-verification function was found.
 		$error_code = 'Missing';
-		if ( false === $this->superglobals[ $instance['content'] ] ) {
+		if ( false === $this->superglobals[ $this->tokens[ $stackPtr ]['content'] ] ) {
 			$error_code = 'Recommended';
 		}
 
-		// If we're still here, no nonce-verification function was found.
 		MessageHelper::addMessage(
 			$this->phpcsFile,
 			'Processing form data without nonce verification.',
 			$stackPtr,
-			$this->superglobals[ $instance['content'] ],
+			$this->superglobals[ $this->tokens[ $stackPtr ]['content'] ],
 			$error_code
 		);
 	}
 
 	/**
-	 * Check if this token has an associated nonce check.
+	 * Determine whether or not a nonce check is needed for the current superglobal.
 	 *
-	 * @since 0.5.0
-	 * @since 3.0.0 - Moved from the generic `Sniff` class to this class.
-	 *              - Visibility changed from `protected` to `private.
+	 * @since 3.0.0
 	 *
-	 * @param int $stackPtr The position of the current token in the stack of tokens.
+	 * @param int   $stackPtr   The position of the current token in the stack of tokens.
+	 * @param array $cache_keys The keys for the applicable cache (to potentially set).
 	 *
-	 * @return bool
+	 * @return string|false String "before" or "after" if a nonce check is needed.
+	 *                      FALSE when no nonce check is needed.
 	 */
-	private function has_nonce_check( $stackPtr ) {
-
-		/**
-		 * A cache of the scope that we last checked for nonce verification in.
-		 *
-		 * @var array {
-		 *      @var string   $file        The name of the file.
-		 *      @var int      $start       The index of the token where the scope started.
-		 *      @var int      $end         The index of the token where the scope ended.
-		 *      @var bool|int $nonce_check The index of the token where an nonce check
-		 *                                 was found, or false if none was found.
-		 * }
-		 */
-		static $last;
-
-		$start = 0;
-		$end   = $stackPtr;
-
-		$tokens = $this->phpcsFile->getTokens();
+	protected function needs_nonce_check( $stackPtr, array $cache_keys ) {
+		$in_nonce_check = ContextHelper::is_in_function_call( $this->phpcsFile, $stackPtr, $this->nonceVerificationFunctions );
+		if ( false !== $in_nonce_check ) {
+			// This *is* the nonce check, so bow out, but do store to cache.
+			// @todo Change to use arg unpacking once PHP < 5.6 has been dropped.
+			$this->set_cache( $cache_keys['file'], $cache_keys['start'], $cache_keys['end'], $in_nonce_check );
+			return false;
+		}
 
-		// If we're in a function, only look inside of it.
-		// Once PHPCS 3.5.0 comes out this should be changed to the new Conditions::GetLastCondition() method.
-		if ( isset( $tokens[ $stackPtr ]['conditions'] ) === true ) {
-			$conditions = $tokens[ $stackPtr ]['conditions'];
-			$conditions = array_reverse( $conditions, true );
-			foreach ( $conditions as $tokenPtr => $condition ) {
-				if ( \T_FUNCTION === $condition || \T_CLOSURE === $condition ) {
-					$start = $tokens[ $tokenPtr ]['scope_opener'];
-					break;
-				}
-			}
+		if ( Context::inUnset( $this->phpcsFile, $stackPtr ) ) {
+			// Variable is only being unset, no nonce check needed.
+			return false;
+		}
+
+		if ( VariableHelper::is_assignment( $this->phpcsFile, $stackPtr, false ) ) {
+			// Overwriting the value of a superglobal.
+			return false;
 		}
 
-		$allow_nonce_after = false;
+		$needs_nonce = 'before';
 		if ( ContextHelper::is_in_isset_or_empty( $this->phpcsFile, $stackPtr )
 			|| ContextHelper::is_in_type_test( $this->phpcsFile, $stackPtr )
 			|| VariableHelper::is_comparison( $this->phpcsFile, $stackPtr )
+			|| VariableHelper::is_assignment( $this->phpcsFile, $stackPtr, true )
 			|| ContextHelper::is_in_array_comparison( $this->phpcsFile, $stackPtr )
 			|| ContextHelper::is_in_function_call( $this->phpcsFile, $stackPtr, UnslashingFunctionsHelper::get_functions() ) !== false
 			|| $this->is_only_sanitized( $stackPtr )
 		) {
-			$allow_nonce_after = true;
+			$needs_nonce = 'after';
 		}
 
+		return $needs_nonce;
+	}
+
+	/**
+	 * Check if this token has an associated nonce check.
+	 *
+	 * @since 0.5.0
+	 * @since 3.0.0 - Moved from the generic `Sniff` class to this class.
+	 *              - Visibility changed from `protected` to `private.
+	 *              - New `$cache_keys` parameter.
+	 *              - New `$allow_nonce_after` parameter.
+	 *
+	 * @param int   $stackPtr          The position of the current token in the stack of tokens.
+	 * @param array $cache_keys        The keys for the applicable cache.
+	 * @param bool  $allow_nonce_after Whether the nonce check _must_ be before the $stackPtr or
+	 *                                 is allowed _after_ the $stackPtr.
+	 *
+	 * @return bool
+	 */
+	private function has_nonce_check( $stackPtr, array $cache_keys, $allow_nonce_after = false ) {
+		$start = $cache_keys['start'];
+		$end   = $cache_keys['end'];
+
 		// We allow for certain actions, such as an isset() check to come before the nonce check.
 		// If this superglobal is inside such a check, look for the nonce after it as well,
 		// all the way to the end of the scope.
 		if ( true === $allow_nonce_after ) {
-			$end = ( 0 === $start ) ? $this->phpcsFile->numTokens : $tokens[ $start ]['scope_closer'];
+			$end = ( 0 === $start ) ? $this->phpcsFile->numTokens : $this->tokens[ $start ]['scope_closer'];
 		}
 
-		// Check if we've looked here before.
-		$filename = $this->phpcsFile->getFilename();
-
-		if ( is_array( $last )
-			&& $filename === $last['file']
-			&& $start === $last['start']
-		) {
-
-			if ( false !== $last['nonce_check'] ) {
-				// If we have already found an nonce check in this scope, we just
-				// need to check whether it comes before this token. It is OK if the
-				// check is after the token though, if this was only a isset() check.
-				return ( true === $allow_nonce_after || $last['nonce_check'] < $stackPtr );
-			} elseif ( $end <= $last['end'] ) {
-				// If not, we can still go ahead and return false if we've already
-				// checked to the end of the search area.
-				return false;
-			}
+		// Check against the cache.
+		$current_cache = $this->get_cache( $cache_keys['file'], $start );
+		if ( false !== $current_cache['nonce'] ) {
+			// If we have already found a nonce check in this scope, we just
+			// need to check whether it comes before this token. It is OK if the
+			// check is after the token though, if this was only an isset() check.
+			return ( true === $allow_nonce_after || $current_cache['nonce'] < $stackPtr );
+		} elseif ( $end <= $current_cache['end'] ) {
+			// If not, we can still go ahead and return false if we've already
+			// checked to the end of the search area.
+			return false;
+		}
 
+		$search_start = $start;
+		if ( $current_cache['end'] > $start ) {
 			// We haven't checked this far yet, but we can still save work by
 			// skipping over the part we've already checked.
-			$start = $last['end'];
-		} else {
-			$last = array(
-				'file'  => $filename,
-				'start' => $start,
-				'end'   => $end,
-			);
+			$search_start = $this->cached_results['cache'][ $start ]['end'];
 		}
 
 		// Loop through the tokens looking for nonce verification functions.
-		for ( $i = $start; $i < $end; $i++ ) {
+		for ( $i = $search_start; $i < $end; $i++ ) {
 			// Skip over nested closed scope constructs.
-			if ( \T_FUNCTION === $tokens[ $i ]['code']
-				|| \T_CLOSURE === $tokens[ $i ]['code']
-				|| isset( Tokens::$ooScopeTokens[ $tokens[ $i ]['code'] ] )
+			if ( isset( Collections::closedScopes()[ $this->tokens[ $i ]['code'] ] )
+				|| \T_FN === $this->tokens[ $i ]['code']
 			) {
-				if ( isset( $tokens[ $i ]['scope_closer'] ) ) {
-					$i = $tokens[ $i ]['scope_closer'];
+				if ( isset( $this->tokens[ $i ]['scope_closer'] ) ) {
+					$i = $this->tokens[ $i ]['scope_closer'];
 				}
 				continue;
 			}
 
 			// If this isn't a function name, skip it.
-			if ( \T_STRING !== $tokens[ $i ]['code'] ) {
+			if ( \T_STRING !== $this->tokens[ $i ]['code'] ) {
 				continue;
 			}
 
 			// If this is one of the nonce verification functions, we can bail out.
-			if ( isset( $this->nonceVerificationFunctions[ $tokens[ $i ]['content'] ] ) ) {
+			if ( isset( $this->nonceVerificationFunctions[ $this->tokens[ $i ]['content'] ] ) ) {
 				/*
 				 * Now, make sure it is a call to a global function.
 				 */
@@ -264,17 +321,86 @@ class NonceVerificationSniff extends Sniff {
 					continue;
 				}
 
-				$last['nonce_check'] = $i;
+				$this->set_cache( $cache_keys['file'], $start, $end, $i );
 				return true;
 			}
 		}
 
 		// We're still here, so no luck.
-		$last['nonce_check'] = false;
+		$this->set_cache( $cache_keys['file'], $start, $end, false );
 
 		return false;
 	}
 
+	/**
+	 * Helper function to retrieve results from the cache.
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param string $filename The name of the current file.
+	 * @param int    $start    The stack pointer searches started from.
+	 *
+	 * @return array<string, mixed>
+	 */
+	private function get_cache( $filename, $start ) {
+		if ( is_array( $this->cached_results )
+			&& $filename === $this->cached_results['file']
+			&& isset( $this->cached_results['cache'][ $start ] )
+		) {
+			return $this->cached_results['cache'][ $start ];
+		}
+
+		return array(
+			'end'   => 0,
+			'nonce' => false,
+		);
+	}
+
+	/**
+	 * Helper function to store results to the cache.
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param string   $filename The name of the current file.
+	 * @param int      $start    The stack pointer searches started from.
+	 * @param int      $end      The stack pointer searched stopped at.
+	 * @param int|bool $nonce    Stack pointer to the nonce verification function call or false if none was found.
+	 *
+	 * @return void
+	 */
+	private function set_cache( $filename, $start, $end, $nonce ) {
+		if ( is_array( $this->cached_results ) === false
+			|| $filename !== $this->cached_results['file']
+		) {
+			$this->cached_results = array(
+				'file'  => $filename,
+				'cache' => array(
+					$start => array(
+						'end'   => $end,
+						'nonce' => $nonce,
+					),
+				),
+			);
+			return;
+		}
+
+		// Okay, so we know the current cache is for the current file. Check if we've seen this start pointer before.
+		if ( isset( $this->cached_results['cache'][ $start ] ) === false ) {
+			$this->cached_results['cache'][ $start ] = array(
+				'end'   => $end,
+				'nonce' => $nonce,
+			);
+			return;
+		}
+
+		// Update existing entry.
+		if ( $end > $this->cached_results['cache'][ $start ]['end'] ) {
+			$this->cached_results['cache'][ $start ]['end'] = $end;
+		}
+
+		$this->cached_results['cache'][ $start ]['nonce'] = $nonce;
+	}
+
 	/**
 	 * Merge custom functions provided via a custom ruleset with the defaults, if we haven't already.
 	 *
@@ -283,13 +409,13 @@ class NonceVerificationSniff extends Sniff {
 	 * @return void
 	 */
 	protected function mergeFunctionLists() {
-		if ( $this->customNonceVerificationFunctions !== $this->addedCustomFunctions['nonce'] ) {
+		if ( $this->customNonceVerificationFunctions !== $this->addedCustomNonceFunctions ) {
 			$this->nonceVerificationFunctions = RulesetPropertyHelper::merge_custom_array(
 				$this->customNonceVerificationFunctions,
 				$this->nonceVerificationFunctions
 			);
 
-			$this->addedCustomFunctions['nonce'] = $this->customNonceVerificationFunctions;
+			$this->addedCustomNonceFunctions = $this->customNonceVerificationFunctions;
 		}
 	}
 }


Test patch:
diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.inc b/WordPress/Tests/Security/NonceVerificationUnitTest.1.inc
similarity index 74%
rename from WordPress/Tests/Security/NonceVerificationUnitTest.inc
rename to WordPress/Tests/Security/NonceVerificationUnitTest.1.inc
index d1a865ce..cb8348b4 100644
--- a/WordPress/Tests/Security/NonceVerificationUnitTest.inc
+++ b/WordPress/Tests/Security/NonceVerificationUnitTest.1.inc
@@ -30,7 +30,7 @@ function foo() {
 function process() {
 	do_something( $_POST['foo'] ); // Bad.
 
-	if ( ! isset( $_POST['test'] ) || ! wp_verify_nonce( 'some_action' ) ) {
+	if ( empty( $_POST['test'] ) || ! wp_verify_nonce( 'some_action' ) ) {
 		exit;
 	}
 
@@ -41,7 +41,7 @@ class Some_Class {
 
 	// Bad, needs nonce check.
 	function bar() {
-		if ( ! isset( $_POST['test'] ) ) { // Bad.
+		if ( empty( $_POST['test'] ) ) { // Bad.
 			return;
 		}
 
@@ -91,7 +91,7 @@ function foo_3() {
 
 // We need to account for when there are multiple vars in a single isset().
 function foo_4() {
-	if ( ! isset( $_POST['foo'], $_POST['bar'], $_POST['_wpnonce'] ) ) { // OK.
+	if ( ! isset( $_POST['foo'], $_FILES['bar'], $_POST['_wpnonce'] ) ) { // OK.
 		return;
 	}
 
@@ -111,21 +111,11 @@ function sanitization_allowed() {
 function foo_5() {
 
 	do_something( (int) $_POST['foo'] ); // Bad.
-	do_something( sanitize_key( $_POST['bar'] ) ); // Bad.
+	do_something( sanitize_key( $_FILES['bar'] ) ); // Bad.
 
 	check_ajax_referer( 'something' );
 }
 
-// Test anonymous function - Bad, needs nonce check.
-check_ajax_referer( 'something' ); // Nonce check is not in function scope.
-$b = function () {
-	if ( ! isset( $_POST['abc'] ) ) { // Bad.
-		return;
-	}
-
-	do_something( $_POST['abc'] ); // Bad.
-};
-
 /*
  * Test using custom properties, setting & unsetting (resetting).
  */
@@ -391,3 +381,108 @@ function disallow_for_non_array_comparison_in_condition_with_named_params() {
 		foo();
 	}
 }
+
+function test_long_list_assignment() {
+	list( $_POST['key1'], list( $_POST['key2'] ) ) = $something; // OK.
+}
+function test_short_list_assignment() {
+	[ $_POST['key1'], [ $_POST['key2'] ] ] = $something; // OK.
+}
+
+function test_assignment_to_long_list_with_noncecheck() {
+	wp_verify_nonce( $_POST['nonce'] );
+	list( $key, list( $key2 ) ) = $_POST; // OK.
+}
+function test_assignment_to_short_list_with_noncecheck() {
+	wp_verify_nonce( $_POST['nonce'] );
+	[ $key, [ $key2 ] ] = $_POST; // OK.
+}
+
+function test_assignment_to_long_list_without_noncecheck() {
+	list( $key, list( $key2 ) ) = $_POST; // Bad.
+}
+function test_assignment_to_short_list_without_noncecheck() {
+	[ $key, [ $key2 ] ] = $_POST; // Bad.
+}
+
+function dont_throw_error_when_only_used_in_unset() {
+	unset( $_POST['foo'] ); // OK.
+}
+
+function dont_throw_error_when_only_used_in_unset_but_error_for_other_use() {
+	unset( $_POST['foo'] ); // OK.
+	echo $_POST['bar']; // Bad.
+}
+
+function dont_throw_error_when_only_used_in_unset_when_there_is_nonce_check_before_other_use() {
+	unset( $_POST['foo'] ); // OK.
+	wp_verify_nonce( $_POST['prefix_nonce'] );
+	echo $_POST['bar']; // OK.
+}
+
+function test_null_coalesce() {
+	$var = $_POST['foo'] ?? 10; // OK.
+	wp_verify_nonce( $_POST['nonce'] );
+}
+function test_null_coalesce_without_noncecheck() {
+	$var = $_POST['foo'] ?? 10; // Bad.
+	// Do something.
+}
+
+function test_null_coalesce_equals() {
+	$_POST['foo'][0] ??= 10; // OK.
+	wp_verify_nonce( $_POST['nonce'] );
+}
+
+function test_null_coalesce_equals_without_noncecheck() {
+	$_POST['foo'][0] ??= 10; // Bad.
+	// Do something.
+}
+
+function test_open_arrow_fn_with_noncecheck() {
+	wp_verify_nonce( $_POST['nonce'] );
+	$callback = fn() => $_POST['key']++; // OK.
+}
+
+function test_open_arrow_fn_without_noncecheck() {
+	$callback = fn() => $_POST['key']++; // Bad.
+}
+
+function test_disregard_noncecheck_in_nested_arrow_function() {
+	$callback = fn() => check_admin_referer( 'foo' );
+	echo $_POST['foo']; // Bad, we don't know if the callback has been called or not.
+}
+
+function test_match() {
+	$var = match($_POST['key']) { // OK, it's a comparison, with the nonce check after.
+		'value' => wp_verify_nonce( $_POST['nonce'] ), // OK.
+		default => $_POST['key'], // OK, due to check above. Realistically, this is wrong, but that goes for all conditional checks.
+	};
+}
+
+function function_containing_nested_enum_with_nonce_check() {
+	enum MyEnum {
+		public function nested_method() {
+			wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['my_nonce'] ) ), 'the_nonce' );
+		}
+	}
+	
+	echo $_POST['foo']; // Bad.
+}
+
+function function_containing_nested_enum_with_nonce_check_outside() {
+	wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['my_nonce'] ) ), 'the_nonce' );
+
+	enum MyEnum {
+		public function nested_method() {
+			echo $_POST['foo']; // Bad.
+		}
+	}
+}
+
+enum MyEnum {
+	public function nested_method() {
+		wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['my_nonce'] ) ), 'the_nonce' );
+		echo $_POST['foo']; // OK.
+	}
+}
diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.2.inc b/WordPress/Tests/Security/NonceVerificationUnitTest.2.inc
new file mode 100644
index 00000000..1171e2f6
--- /dev/null
+++ b/WordPress/Tests/Security/NonceVerificationUnitTest.2.inc
@@ -0,0 +1,15 @@
+<?php
+
+/*
+ * Verify that a nonce check in the global scope will not be accepted as valid for superglobal use in function local scope.
+ */
+
+// Test anonymous function - Bad, needs nonce check.
+check_ajax_referer( 'something' ); // Nonce check is not in function scope.
+$b = function () {
+	if ( ! isset( $_POST['abc'] ) ) { // Bad.
+		return;
+	}
+
+	do_something( $_POST['abc'] ); // Bad.
+};
diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.3.inc b/WordPress/Tests/Security/NonceVerificationUnitTest.3.inc
new file mode 100644
index 00000000..8a74d007
--- /dev/null
+++ b/WordPress/Tests/Security/NonceVerificationUnitTest.3.inc
@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * Verify a correct nonce check (way) _before_ in the global scope.
+ */
+wp_verify_nonce( $_POST['prefix_nonce'] );
+
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+
+echo $_POST['prefix_myfield']; // OK.
diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.4.inc b/WordPress/Tests/Security/NonceVerificationUnitTest.4.inc
new file mode 100644
index 00000000..38cdca2c
--- /dev/null
+++ b/WordPress/Tests/Security/NonceVerificationUnitTest.4.inc
@@ -0,0 +1,25 @@
+<?php
+
+/*
+ * Verify a missing nonce check _before_ in the global scope.
+ */
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+
+echo $_GET['prefix_myfield']; // Bad.
diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.5.inc b/WordPress/Tests/Security/NonceVerificationUnitTest.5.inc
new file mode 100644
index 00000000..77f502bd
--- /dev/null
+++ b/WordPress/Tests/Security/NonceVerificationUnitTest.5.inc
@@ -0,0 +1,18 @@
+<?php
+
+/*
+ * Verify an allowed nonce check _after_ in the global scope.
+ */
+
+if ( isset ( $_POST['prefix_myfield'] ) { // OK.
+	
+	do_something();
+	do_something();
+	do_something();
+	do_something();
+	do_something();
+	do_something();
+
+	wp_verify_nonce( $_POST['prefix_nonce'] );
+	echo $_POST['prefix_myfield']; // OK.
+}
diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.6.inc b/WordPress/Tests/Security/NonceVerificationUnitTest.6.inc
new file mode 100644
index 00000000..a866aea8
--- /dev/null
+++ b/WordPress/Tests/Security/NonceVerificationUnitTest.6.inc
@@ -0,0 +1,11 @@
+<?php
+
+/*
+ * Verify an incorrect nonce check _after_ in the global scope.
+ */
+
+if ( isset ( $_REQUEST['prefix_myfield'] ) {
+	echo $_REQUEST['prefix_myfield']; // Bad, nonce is too late.
+}
+
+wp_verify_nonce( $_REQUEST['prefix_nonce'] );
diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.7.inc b/WordPress/Tests/Security/NonceVerificationUnitTest.7.inc
new file mode 100644
index 00000000..7fa3d641
--- /dev/null
+++ b/WordPress/Tests/Security/NonceVerificationUnitTest.7.inc
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This test is not actually testing anything in the sniff.
+ * More than anything, it demonstrates why the cache format change is relevant.
+ */
+
+if ( isset ( $_POST['prefix_myfield'] ) { // OK.
+
+	do_something();
+	do_something();
+	do_something();
+	do_something();
+	do_something();
+	do_something();
+
+	echo $_POST['prefix_myfield']; // Bad.
+
+	do_something();
+	do_something();
+	do_something();
+
+	echo $_POST['prefix_myfield']; // Bad.
+}
+
+function this_would_previously_reset_the_cache() {
+	if (
+		'newsletter_sign_up' === $_POST['action'] && // OK.
+		wp_verify_nonce( $_POST['newsletter_nonce'] )
+	) {}
+}
+
+// With the change made to the caching, the in-file search will now continue on line 17 instead of start from 0 again.
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+do_something();
+
+wp_verify_nonce( $_POST['prefix_nonce'] );
+echo $_POST['prefix_myfield']; // OK.
+
+function this_would_previously_reset_the_cache_again() {
+	if (
+		'newsletter_sign_up' === $_POST['action'] && // OK.
+		wp_verify_nonce( $_POST['newsletter_nonce'] )
+	) {}
+}
+
+// With the change made to the caching, no in-search file search is needed here as we already found a nonce-check on line 35.
+if ( isset ( $_POST['prefix_myfield'] ) { // OK.
+
+	do_something();
+	do_something();
+	do_something();
+	do_something();
+	do_something();
+	do_something();
+
+	echo $_POST['prefix_myfield']; // OK.
+}
diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.8.inc b/WordPress/Tests/Security/NonceVerificationUnitTest.8.inc
new file mode 100644
index 00000000..c2c134dd
--- /dev/null
+++ b/WordPress/Tests/Security/NonceVerificationUnitTest.8.inc
@@ -0,0 +1,6 @@
+<?php
+
+class IgnoreProperties {
+	public $_GET = array( 'key' => 'something' ); // OK.
+	public $_POST; // OK.
+}
diff --git a/WordPress/Tests/Security/NonceVerificationUnitTest.php b/WordPress/Tests/Security/NonceVerificationUnitTest.php
index edcc509c..5a5bebd9 100644
--- a/WordPress/Tests/Security/NonceVerificationUnitTest.php
+++ b/WordPress/Tests/Security/NonceVerificationUnitTest.php
@@ -31,53 +31,97 @@ final class NonceVerificationUnitTest extends AbstractSniffUnitTest {
 	/**
 	 * Returns the lines where errors should occur.
 	 *
+	 * @param string $testFile The name of the file being tested.
+	 *
 	 * @return array <int line number> => <int number of errors>
 	 */
-	public function getErrorList() {
+	public function getErrorList( $testFile = '' ) {
+		switch ( $testFile ) {
+			case 'NonceVerificationUnitTest.1.inc':
+				return array(
+					5   => 1,
+					9   => 1,
+					31  => 1,
+					44  => 1,
+					48  => 1,
+					69  => 1,
+					88  => 1, // Old-style WPCS ignore comments are no longer supported.
+					89  => 1,
+					113 => 1,
+					114 => 1,
+					138 => 1,
+					140 => 1,
+					149 => 1,
+					150 => 1,
+					151 => 1,
+					167 => 1,
+					175 => 1,
+					180 => 1,
+					188 => 1,
+					192 => 1,
+					242 => 1,
+					259 => 1,
+					296 => 1,
+					302 => 1,
+					325 => 1,
+					329 => 1,
+					337 => 1,
+					341 => 1,
+					402 => 1,
+					405 => 1,
+					414 => 1,
+					428 => 1,
+					438 => 1,
+					448 => 1,
+					453 => 1,
+					470 => 1,
+					478 => 1,
+				);
+
+			case 'NonceVerificationUnitTest.2.inc':
+				return array(
+					10 => 1,
+					14 => 1,
+				);
 
-		return array(
-			5   => 1,
-			9   => 1,
-			31  => 1,
-			44  => 1,
-			48  => 1,
-			69  => 1,
-			88  => 1, // Old-style WPCS ignore comments are no longer supported.
-			89  => 1,
-			113 => 1,
-			114 => 1,
-			122 => 1,
-			126 => 1,
-			148 => 1,
-			150 => 1,
-			159 => 1,
-			160 => 1,
-			161 => 1,
-			177 => 1,
-			185 => 1,
-			190 => 1,
-			198 => 1,
-			202 => 1,
-			252 => 1,
-			269 => 1,
-			306 => 1,
-			312 => 1,
-			335 => 1,
-			339 => 1,
-			347 => 1,
-			351 => 1,
-		);
+			case 'NonceVerificationUnitTest.7.inc':
+				return array(
+					17 => 1,
+					23 => 1,
+				);
+
+			default:
+				return array();
+		}
 	}
 
 	/**
 	 * Returns the lines where warnings should occur.
 	 *
+	 * @param string $testFile The name of the file being tested.
+	 *
 	 * @return array <int line number> => <int number of warnings>
 	 */
-	public function getWarningList() {
-		return array(
-			375 => 1,
-			389 => 1,
-		);
+	public function getWarningList( $testFile = '' ) {
+		switch ( $testFile ) {
+			case 'NonceVerificationUnitTest.1.inc':
+				return array(
+					365 => 1,
+					379 => 1,
+				);
+
+			case 'NonceVerificationUnitTest.4.inc':
+				return array(
+					25 => 1,
+				);
+
+			case 'NonceVerificationUnitTest.6.inc':
+				return array(
+					8 => 1,
+				);
+
+			default:
+				return array();
+		}
 	}
 }