Issues (1061)

Sources/Subs-Sound.php (1 issue)

1
<?php
2
3
/**
4
 * Handles sound processing. In order to make sure the visual
5
 * verification is still accessible for all users, a sound clip is being addded
6
 * that reads the letters that are being shown.
7
 *
8
 * Simple Machines Forum (SMF)
9
 *
10
 * @package SMF
11
 * @author Simple Machines https://www.simplemachines.org
12
 * @copyright 2020 Simple Machines and individual contributors
13
 * @license https://www.simplemachines.org/about/smf/license.php BSD
14
 *
15
 * @version 2.1 RC2
16
 */
17
18
if (!defined('SMF'))
19
	die('No direct access...');
20
21
/**
22
 * Creates a wave file that spells the letters of $word.
23
 * Tries the user's language first, and defaults to english.
24
 * Used by VerificationCode() (Register.php).
25
 *
26
 * @param string $word
27
 * @return boolean false on failure
28
 */
29
30
function createWaveFile($word)
31
{
32
	global $settings, $user_info;
33
34
	// Allow max 2 requests per 20 seconds.
35
	if (($ip = cache_get_data('wave_file/' . $user_info['ip'], 20)) > 2 || ($ip2 = cache_get_data('wave_file/' . $user_info['ip2'], 20)) > 2)
36
		die(send_http_status(400));
37
	cache_put_data('wave_file/' . $user_info['ip'], $ip ? $ip + 1 : 1, 20);
38
	cache_put_data('wave_file/' . $user_info['ip2'], $ip2 ? $ip2 + 1 : 1, 20);
39
40
	// Fixate randomization for this word.
41
	$tmp = unpack('n', md5($word . session_id()));
42
	mt_srand(end($tmp));
0 ignored issues
show
It seems like $tmp can also be of type false; however, parameter $array of end() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

42
	mt_srand(end(/** @scrutinizer ignore-type */ $tmp));
Loading history...
43
44
	// Try to see if there's a sound font in the user's language.
45
	if (file_exists($settings['default_theme_dir'] . '/fonts/sound/a.' . $user_info['language'] . '.wav'))
46
		$sound_language = $user_info['language'];
47
48
	// English should be there.
49
	elseif (file_exists($settings['default_theme_dir'] . '/fonts/sound/a.english.wav'))
50
		$sound_language = 'english';
51
52
	// Guess not...
53
	else
54
		return false;
55
56
	// File names are in lower case so lets make sure that we are only using a lower case string
57
	$word = strtolower($word);
58
59
	// Loop through all letters of the word $word.
60
	$sound_word = '';
61
	for ($i = 0; $i < strlen($word); $i++)
62
	{
63
		$sound_letter = implode('', file($settings['default_theme_dir'] . '/fonts/sound/' . $word[$i] . '.' . $sound_language . '.wav'));
64
		if (strpos($sound_letter, 'data') === false)
65
			return false;
66
67
		$sound_letter = substr($sound_letter, strpos($sound_letter, 'data') + 8);
68
		switch ($word[$i] === 's' ? 0 : mt_rand(0, 2))
69
		{
70
			case 0 :
71
				for ($j = 0, $n = strlen($sound_letter); $j < $n; $j++)
72
					for ($k = 0, $m = round(mt_rand(15, 25) / 10); $k < $m; $k++)
73
						$sound_word .= $word[$i] === 's' ? $sound_letter[$j] : chr(mt_rand(max(ord($sound_letter[$j]) - 1, 0x00), min(ord($sound_letter[$j]) + 1, 0xFF)));
74
				break;
75
76
			case 1:
77
				for ($j = 0, $n = strlen($sound_letter) - 1; $j < $n; $j += 2)
78
					$sound_word .= (mt_rand(0, 3) == 0 ? '' : $sound_letter[$j]) . (mt_rand(0, 3) === 0 ? $sound_letter[$j + 1] : $sound_letter[$j]) . (mt_rand(0, 3) === 0 ? $sound_letter[$j] : $sound_letter[$j + 1]) . $sound_letter[$j + 1] . (mt_rand(0, 3) == 0 ? $sound_letter[$j + 1] : '');
79
				$sound_word .= str_repeat($sound_letter[$n], 2);
80
				break;
81
82
			case 2:
83
				$shift = 0;
84
				for ($j = 0, $n = strlen($sound_letter); $j < $n; $j++)
85
				{
86
					if (mt_rand(0, 10) === 0)
87
						$shift += mt_rand(-3, 3);
88
					for ($k = 0, $m = round(mt_rand(15, 25) / 10); $k < $m; $k++)
89
						$sound_word .= chr(min(max(ord($sound_letter[$j]) + $shift, 0x00), 0xFF));
90
				}
91
				break;
92
		}
93
94
		$sound_word .= str_repeat(chr(0x80), mt_rand(10000, 10500));
95
	}
96
97
	$data_size = strlen($sound_word);
98
	$file_size = $data_size + 0x24;
99
	$sample_rate = 16000;
100
101
	// Disable compression.
102
	ob_end_clean();
103
	header('content-encoding: none');
104
105
	// Output the wav.
106
	header('content-type: audio/x-wav');
107
	header('expires: ' . gmdate('D, d M Y H:i:s', time() + 525600 * 60) . ' GMT');
108
	header('content-length: ' . ($file_size + 0x08));
109
110
	echo pack('nnVnnnnnnnnVVnnnnV', 0x5249, 0x4646, $file_size, 0x5741, 0x5645, 0x666D, 0x7420, 0x1000, 0x0000, 0x0100, 0x0100, $sample_rate, $sample_rate, 0x0100, 0x0800, 0x6461, 0x7461, $data_size), $sound_word;
111
112
	// Noting more to add.
113
	die();
114
}
115
116
?>