SMF icon indicating copy to clipboard operation
SMF copied to clipboard

[2.1]: Verification Questions: Trying to access array offset on null

Open qcybb opened this issue 8 months ago • 2 comments

Basic Information

If you have a couple verification question/answers entered in, and then set "Number of verification questions user must answer" to 0, the error log fills up with these errors:

/forum/Sources/Subs-Editor.php (Line 2269)
Type of error: General
Error message:
2: Trying to access array offset on null

Steps to reproduce

  1. Add a couple verification questions
  2. Set "Number of verification questions user must answer" to 0
  3. View a page where verification questions should appear

Expected result

No response

Actual result

No response

Version/Git revision

2.1.4

Database Engine

All

Database Version

No response

PHP Version

PHP 8.3.20

Logs


Additional Information

No response

qcybb avatar Apr 25 '25 03:04 qcybb

That's because $modSettings['question_id_cache'] isn't necessarily set if they don't have any questions to answer (no point in loading up/caching questions if there's nothing to answer in the first place). The question here is why we're still plowing ahead and trying to load the info later. I suspect this might affect 3.0 as well, but the code is completely different in 3.0 so I'd have to look into it further.

Oldiesmann avatar Apr 25 '25 23:04 Oldiesmann

An easy fix for this is to check whether $row['question'] is empty or not.

in Subs-Editor:

Find:

	// Have we got some questions to load?
	if (!empty($questionIDs))
	{
		$_SESSION[$verificationOptions['id'] . '_vv']['q'] = array();
		foreach ($questionIDs as $q)
		{
			// Bit of a shortcut this.
			$row = &$modSettings['question_id_cache']['questions'][$q];
			$thisVerification['questions'][] = array(
				'id' => $q,
				'q' => parse_bbc($row['question']),
				'is_error' => !empty($incorrectQuestions) && in_array($q, $incorrectQuestions),
				// Remember a previous submission?
				'a' => isset($_REQUEST[$verificationOptions['id'] . '_vv'], $_REQUEST[$verificationOptions['id'] . '_vv']['q'], $_REQUEST[$verificationOptions['id'] . '_vv']['q'][$q]) ? $smcFunc['htmlspecialchars']($_REQUEST[$verificationOptions['id'] . '_vv']['q'][$q]) : '',
			);
			$_SESSION[$verificationOptions['id'] . '_vv']['q'][] = $q;
		}
	}

Replace:

	// Have we got some questions to load?
	if (!empty($questionIDs))
	{
		$_SESSION[$verificationOptions['id'] . '_vv']['q'] = array();
		foreach ($questionIDs as $q)
		{
			// Bit of a shortcut this.
			$row = &$modSettings['question_id_cache']['questions'][$q];
			if ( $row['question'] )
			{
				$thisVerification['questions'][] = array(
					'id' => $q,
					'q' => parse_bbc($row['question']),
					'is_error' => !empty($incorrectQuestions) && in_array($q, $incorrectQuestions),
					// Remember a previous submission?
					'a' => isset($_REQUEST[$verificationOptions['id'] . '_vv'], $_REQUEST[$verificationOptions['id'] . '_vv']['q'], $_REQUEST[$verificationOptions['id'] . '_vv']['q'][$q]) ? $smcFunc['htmlspecialchars']($_REQUEST[$verificationOptions['id'] . '_vv']['q'][$q]) : '',
				);
				$_SESSION[$verificationOptions['id'] . '_vv']['q'][] = $q;
			}
		}
	}

The only change is this:

if ( $row['question'] )

Fully tested, and I no longer get those error messages.

qcybb avatar Apr 26 '25 03:04 qcybb