Issues (1061)

Sources/Subs-Compat.php (2 issues)

Labels
Severity
1
<?php
2
3
/**
4
 * This file provides compatibility functions and code for older versions of
5
 * PHP, such as the sha1() function, missing extensions, or 64-bit vs 32-bit
6
 * systems. It is only included for those older versions or when the respective
7
 * extension or function cannot be found.
8
 *
9
 * Simple Machines Forum (SMF)
10
 *
11
 * @package SMF
12
 * @author Simple Machines https://www.simplemachines.org
13
 * @copyright 2020 Simple Machines and individual contributors
14
 * @license https://www.simplemachines.org/about/smf/license.php BSD
15
 *
16
 * @version 2.1 RC2
17
 */
18
19
if (!defined('SMF'))
20
	die('No direct access...');
21
22
/**
23
 * Define the old SMF sha1 function. Uses mhash if available
24
 *
25
 * @param string $str The string
26
 * @return string The sha1 hashed version of $str
27
 */
28
function sha1_smf($str)
29
{
30
	// If we have mhash loaded in, use it instead!
31
	if (function_exists('mhash') && defined('MHASH_SHA1'))
32
		return bin2hex(mhash(MHASH_SHA1, $str));
33
34
	$nblk = (strlen($str) + 8 >> 6) + 1;
35
	$blks = array_pad(array(), $nblk * 16, 0);
36
37
	for ($i = 0; $i < strlen($str); $i++)
38
		$blks[$i >> 2] |= ord($str[$i]) << (24 - ($i % 4) * 8);
39
40
	$blks[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);
41
42
	return sha1_core($blks, strlen($str) * 8);
0 ignored issues
show
$blks of type array is incompatible with the type string expected by parameter $x of sha1_core(). ( Ignorable by Annotation )

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

42
	return sha1_core(/** @scrutinizer ignore-type */ $blks, strlen($str) * 8);
Loading history...
43
}
44
45
/**
46
 * This is the core SHA-1 calculation routine, used by sha1().
47
 *
48
 * @param string $x
49
 * @param int $len
50
 * @return string
51
 */
52
function sha1_core($x, $len)
53
{
54
	@$x[$len >> 5] |= 0x80 << (24 - $len % 32);
55
	$x[(($len + 64 >> 9) << 4) + 15] = $len;
56
57
	$w = array();
58
	$a = 1732584193;
59
	$b = -271733879;
60
	$c = -1732584194;
61
	$d = 271733878;
62
	$e = -1009589776;
63
64
	for ($i = 0, $n = count($x); $i < $n; $i += 16)
0 ignored issues
show
$x of type string is incompatible with the type Countable|array expected by parameter $var of count(). ( Ignorable by Annotation )

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

64
	for ($i = 0, $n = count(/** @scrutinizer ignore-type */ $x); $i < $n; $i += 16)
Loading history...
65
	{
66
		$olda = $a;
67
		$oldb = $b;
68
		$oldc = $c;
69
		$oldd = $d;
70
		$olde = $e;
71
72
		for ($j = 0; $j < 80; $j++)
73
		{
74
			if ($j < 16)
75
				$w[$j] = isset($x[$i + $j]) ? $x[$i + $j] : 0;
76
			else
77
				$w[$j] = sha1_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1);
78
79
			$t = sha1_rol($a, 5) + sha1_ft($j, $b, $c, $d) + $e + $w[$j] + sha1_kt($j);
80
			$e = $d;
81
			$d = $c;
82
			$c = sha1_rol($b, 30);
83
			$b = $a;
84
			$a = $t;
85
		}
86
87
		$a += $olda;
88
		$b += $oldb;
89
		$c += $oldc;
90
		$d += $oldd;
91
		$e += $olde;
92
	}
93
94
	return sprintf('%08x%08x%08x%08x%08x', $a, $b, $c, $d, $e);
95
}
96
97
/**
98
 * Helper function for the core SHA-1 calculation
99
 *
100
 * @param int $t
101
 * @param int $b
102
 * @param int $c
103
 * @param int $d
104
 * @return int
105
 */
106
function sha1_ft($t, $b, $c, $d)
107
{
108
	if ($t < 20)
109
		return ($b & $c) | ((~$b) & $d);
110
	if ($t < 40)
111
		return $b ^ $c ^ $d;
112
	if ($t < 60)
113
		return ($b & $c) | ($b & $d) | ($c & $d);
114
115
	return $b ^ $c ^ $d;
116
}
117
118
/**
119
 * Helper function for the core SHA-1 calculation
120
 *
121
 * @param int $t
122
 * @return int 1518500249, 1859775393, -1894007588 or -899497514 depending on the value of $t
123
 */
124
function sha1_kt($t)
125
{
126
	return $t < 20 ? 1518500249 : ($t < 40 ? 1859775393 : ($t < 60 ? -1894007588 : -899497514));
127
}
128
129
/**
130
 * Helper function for the core SHA-1 calculation
131
 *
132
 * @param int $num
133
 * @param int $cnt
134
 * @return int
135
 */
136
function sha1_rol($num, $cnt)
137
{
138
	// Unfortunately, PHP uses unsigned 32-bit longs only.  So we have to kludge it a bit.
139
	if ($num & 0x80000000)
140
		$a = ($num >> 1 & 0x7fffffff) >> (31 - $cnt);
141
	else
142
		$a = $num >> (32 - $cnt);
143
144
	return ($num << $cnt) | $a;
145
}
146
147
/**
148
 * Available since: (PHP 5)
149
 * If the optional raw_output is set to TRUE, then the sha1 digest is instead returned in raw binary format with a length of 20,
150
 * otherwise the returned value is a 40-character hexadecimal number.
151
 *
152
 * @param string $text The text to hash
153
 * @return string The sha1 hash of $text
154
 */
155
function sha1_raw($text)
156
{
157
	return sha1($text, true);
158
}
159
160
if (!function_exists('smf_crc32'))
161
{
162
	/**
163
	 * Compatibility function.
164
	 * crc32 doesn't work as expected on 64-bit functions - make our own.
165
	 * https://php.net/crc32#79567
166
	 *
167
	 * @param string $number
168
	 * @return string The crc32 polynomial of $number
169
	 */
170
	function smf_crc32($number)
171
	{
172
		$crc = crc32($number);
173
174
		if ($crc & 0x80000000)
175
		{
176
			$crc ^= 0xffffffff;
177
			$crc += 1;
178
			$crc = -$crc;
179
		}
180
181
		return $crc;
182
	}
183
}
184
185
?>