PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 10.9.4
WooCommerce v10.9.4
10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / vendor / maxmind-db / reader / src / MaxMind / Db / Reader / Decoder.php
woocommerce / vendor / maxmind-db / reader / src / MaxMind / Db / Reader Last commit date
Decoder.php 10 months ago InvalidDatabaseException.php 2 years ago Metadata.php 10 months ago Util.php 2 years ago
Decoder.php
453 lines
1 <?php
2
3 declare(strict_types=1);
4
5 namespace MaxMind\Db\Reader;
6
7 // @codingStandardsIgnoreLine
8
9 class Decoder
10 {
11 /**
12 * @var resource
13 */
14 private $fileStream;
15
16 /**
17 * @var int
18 */
19 private $pointerBase;
20
21 /**
22 * This is only used for unit testing.
23 *
24 * @var bool
25 */
26 private $pointerTestHack;
27
28 /**
29 * @var bool
30 */
31 private $switchByteOrder;
32
33 private const _EXTENDED = 0;
34 private const _POINTER = 1;
35 private const _UTF8_STRING = 2;
36 private const _DOUBLE = 3;
37 private const _BYTES = 4;
38 private const _UINT16 = 5;
39 private const _UINT32 = 6;
40 private const _MAP = 7;
41 private const _INT32 = 8;
42 private const _UINT64 = 9;
43 private const _UINT128 = 10;
44 private const _ARRAY = 11;
45 // 12 is the container type
46 // 13 is the end marker type
47 private const _BOOLEAN = 14;
48 private const _FLOAT = 15;
49
50 /**
51 * @param resource $fileStream
52 */
53 public function __construct(
54 $fileStream,
55 int $pointerBase = 0,
56 bool $pointerTestHack = false
57 ) {
58 $this->fileStream = $fileStream;
59 $this->pointerBase = $pointerBase;
60
61 $this->pointerTestHack = $pointerTestHack;
62
63 $this->switchByteOrder = $this->isPlatformLittleEndian();
64 }
65
66 /**
67 * @return array<mixed>
68 */
69 public function decode(int $offset): array
70 {
71 $ctrlByte = \ord(Util::read($this->fileStream, $offset, 1));
72 ++$offset;
73
74 $type = $ctrlByte >> 5;
75
76 // Pointers are a special case, we don't read the next $size bytes, we
77 // use the size to determine the length of the pointer and then follow
78 // it.
79 if ($type === self::_POINTER) {
80 [$pointer, $offset] = $this->decodePointer($ctrlByte, $offset);
81
82 // for unit testing
83 if ($this->pointerTestHack) {
84 return [$pointer];
85 }
86
87 [$result] = $this->decode($pointer);
88
89 return [$result, $offset];
90 }
91
92 if ($type === self::_EXTENDED) {
93 $nextByte = \ord(Util::read($this->fileStream, $offset, 1));
94
95 $type = $nextByte + 7;
96
97 if ($type < 8) {
98 throw new InvalidDatabaseException(
99 'Something went horribly wrong in the decoder. An extended type '
100 . 'resolved to a type number < 8 ('
101 . $type
102 . ')'
103 );
104 }
105
106 ++$offset;
107 }
108
109 [$size, $offset] = $this->sizeFromCtrlByte($ctrlByte, $offset);
110
111 return $this->decodeByType($type, $offset, $size);
112 }
113
114 /**
115 * @param int<0, max> $size
116 *
117 * @return array{0:mixed, 1:int}
118 */
119 private function decodeByType(int $type, int $offset, int $size): array
120 {
121 switch ($type) {
122 case self::_MAP:
123 return $this->decodeMap($size, $offset);
124
125 case self::_ARRAY:
126 return $this->decodeArray($size, $offset);
127
128 case self::_BOOLEAN:
129 return [$this->decodeBoolean($size), $offset];
130 }
131
132 $newOffset = $offset + $size;
133 $bytes = Util::read($this->fileStream, $offset, $size);
134
135 switch ($type) {
136 case self::_BYTES:
137 case self::_UTF8_STRING:
138 return [$bytes, $newOffset];
139
140 case self::_DOUBLE:
141 $this->verifySize(8, $size);
142
143 return [$this->decodeDouble($bytes), $newOffset];
144
145 case self::_FLOAT:
146 $this->verifySize(4, $size);
147
148 return [$this->decodeFloat($bytes), $newOffset];
149
150 case self::_INT32:
151 return [$this->decodeInt32($bytes, $size), $newOffset];
152
153 case self::_UINT16:
154 case self::_UINT32:
155 case self::_UINT64:
156 case self::_UINT128:
157 return [$this->decodeUint($bytes, $size), $newOffset];
158
159 default:
160 throw new InvalidDatabaseException(
161 'Unknown or unexpected type: ' . $type
162 );
163 }
164 }
165
166 private function verifySize(int $expected, int $actual): void
167 {
168 if ($expected !== $actual) {
169 throw new InvalidDatabaseException(
170 "The MaxMind DB file's data section contains bad data (unknown data type or corrupt data)"
171 );
172 }
173 }
174
175 /**
176 * @return array{0:array<mixed>, 1:int}
177 */
178 private function decodeArray(int $size, int $offset): array
179 {
180 $array = [];
181
182 for ($i = 0; $i < $size; ++$i) {
183 [$value, $offset] = $this->decode($offset);
184 $array[] = $value;
185 }
186
187 return [$array, $offset];
188 }
189
190 private function decodeBoolean(int $size): bool
191 {
192 return $size !== 0;
193 }
194
195 private function decodeDouble(string $bytes): float
196 {
197 // This assumes IEEE 754 doubles, but most (all?) modern platforms
198 // use them.
199 $rc = unpack('E', $bytes);
200 if ($rc === false) {
201 throw new InvalidDatabaseException(
202 'Could not unpack a double value from the given bytes.'
203 );
204 }
205 [, $double] = $rc;
206
207 return $double;
208 }
209
210 private function decodeFloat(string $bytes): float
211 {
212 // This assumes IEEE 754 floats, but most (all?) modern platforms
213 // use them.
214 $rc = unpack('G', $bytes);
215 if ($rc === false) {
216 throw new InvalidDatabaseException(
217 'Could not unpack a float value from the given bytes.'
218 );
219 }
220 [, $float] = $rc;
221
222 return $float;
223 }
224
225 private function decodeInt32(string $bytes, int $size): int
226 {
227 switch ($size) {
228 case 0:
229 return 0;
230
231 case 1:
232 case 2:
233 case 3:
234 $bytes = str_pad($bytes, 4, "\x00", \STR_PAD_LEFT);
235
236 break;
237
238 case 4:
239 break;
240
241 default:
242 throw new InvalidDatabaseException(
243 "The MaxMind DB file's data section contains bad data (unknown data type or corrupt data)"
244 );
245 }
246
247 $rc = unpack('l', $this->maybeSwitchByteOrder($bytes));
248 if ($rc === false) {
249 throw new InvalidDatabaseException(
250 'Could not unpack a 32bit integer value from the given bytes.'
251 );
252 }
253 [, $int] = $rc;
254
255 return $int;
256 }
257
258 /**
259 * @return array{0:array<string, mixed>, 1:int}
260 */
261 private function decodeMap(int $size, int $offset): array
262 {
263 $map = [];
264
265 for ($i = 0; $i < $size; ++$i) {
266 [$key, $offset] = $this->decode($offset);
267 [$value, $offset] = $this->decode($offset);
268 $map[$key] = $value;
269 }
270
271 return [$map, $offset];
272 }
273
274 /**
275 * @return array{0:int, 1:int}
276 */
277 private function decodePointer(int $ctrlByte, int $offset): array
278 {
279 $pointerSize = (($ctrlByte >> 3) & 0x3) + 1;
280
281 $buffer = Util::read($this->fileStream, $offset, $pointerSize);
282 $offset += $pointerSize;
283
284 switch ($pointerSize) {
285 case 1:
286 $packed = \chr($ctrlByte & 0x7) . $buffer;
287 $rc = unpack('n', $packed);
288 if ($rc === false) {
289 throw new InvalidDatabaseException(
290 'Could not unpack an unsigned short value from the given bytes (pointerSize is 1).'
291 );
292 }
293 [, $pointer] = $rc;
294 $pointer += $this->pointerBase;
295
296 break;
297
298 case 2:
299 $packed = "\x00" . \chr($ctrlByte & 0x7) . $buffer;
300 $rc = unpack('N', $packed);
301 if ($rc === false) {
302 throw new InvalidDatabaseException(
303 'Could not unpack an unsigned long value from the given bytes (pointerSize is 2).'
304 );
305 }
306 [, $pointer] = $rc;
307 $pointer += $this->pointerBase + 2048;
308
309 break;
310
311 case 3:
312 $packed = \chr($ctrlByte & 0x7) . $buffer;
313
314 // It is safe to use 'N' here, even on 32 bit machines as the
315 // first bit is 0.
316 $rc = unpack('N', $packed);
317 if ($rc === false) {
318 throw new InvalidDatabaseException(
319 'Could not unpack an unsigned long value from the given bytes (pointerSize is 3).'
320 );
321 }
322 [, $pointer] = $rc;
323 $pointer += $this->pointerBase + 526336;
324
325 break;
326
327 case 4:
328 // We cannot use unpack here as we might overflow on 32 bit
329 // machines
330 $pointerOffset = $this->decodeUint($buffer, $pointerSize);
331
332 $pointerBase = $this->pointerBase;
333
334 if (\PHP_INT_MAX - $pointerBase >= $pointerOffset) {
335 $pointer = $pointerOffset + $pointerBase;
336 } else {
337 throw new \RuntimeException(
338 'The database offset is too large to be represented on your platform.'
339 );
340 }
341
342 break;
343
344 default:
345 throw new InvalidDatabaseException(
346 'Unexpected pointer size ' . $pointerSize
347 );
348 }
349
350 return [$pointer, $offset];
351 }
352
353 // @phpstan-ignore-next-line
354 private function decodeUint(string $bytes, int $byteLength)
355 {
356 if ($byteLength === 0) {
357 return 0;
358 }
359
360 // PHP integers are signed. PHP_INT_SIZE - 1 is the number of
361 // complete bytes that can be converted to an integer. However,
362 // we can convert another byte if the leading bit is zero.
363 $useRealInts = $byteLength <= \PHP_INT_SIZE - 1
364 || ($byteLength === \PHP_INT_SIZE && (\ord($bytes[0]) & 0x80) === 0);
365
366 if ($useRealInts) {
367 $integer = 0;
368 for ($i = 0; $i < $byteLength; ++$i) {
369 $part = \ord($bytes[$i]);
370 $integer = ($integer << 8) + $part;
371 }
372
373 return $integer;
374 }
375
376 // We only use gmp or bcmath if the final value is too big
377 $integerAsString = '0';
378 for ($i = 0; $i < $byteLength; ++$i) {
379 $part = \ord($bytes[$i]);
380
381 if (\extension_loaded('gmp')) {
382 $integerAsString = gmp_strval(gmp_add(gmp_mul($integerAsString, '256'), $part));
383 } elseif (\extension_loaded('bcmath')) {
384 $integerAsString = bcadd(bcmul($integerAsString, '256'), (string) $part);
385 } else {
386 throw new \RuntimeException(
387 'The gmp or bcmath extension must be installed to read this database.'
388 );
389 }
390 }
391
392 return $integerAsString;
393 }
394
395 /**
396 * @return array{0:int, 1:int}
397 */
398 private function sizeFromCtrlByte(int $ctrlByte, int $offset): array
399 {
400 $size = $ctrlByte & 0x1F;
401
402 if ($size < 29) {
403 return [$size, $offset];
404 }
405
406 $bytesToRead = $size - 28;
407 $bytes = Util::read($this->fileStream, $offset, $bytesToRead);
408
409 if ($size === 29) {
410 $size = 29 + \ord($bytes);
411 } elseif ($size === 30) {
412 $rc = unpack('n', $bytes);
413 if ($rc === false) {
414 throw new InvalidDatabaseException(
415 'Could not unpack an unsigned short value from the given bytes.'
416 );
417 }
418 [, $adjust] = $rc;
419 $size = 285 + $adjust;
420 } else {
421 $rc = unpack('N', "\x00" . $bytes);
422 if ($rc === false) {
423 throw new InvalidDatabaseException(
424 'Could not unpack an unsigned long value from the given bytes.'
425 );
426 }
427 [, $adjust] = $rc;
428 $size = $adjust + 65821;
429 }
430
431 return [$size, $offset + $bytesToRead];
432 }
433
434 private function maybeSwitchByteOrder(string $bytes): string
435 {
436 return $this->switchByteOrder ? strrev($bytes) : $bytes;
437 }
438
439 private function isPlatformLittleEndian(): bool
440 {
441 $testint = 0x00FF;
442 $packed = pack('S', $testint);
443 $rc = unpack('v', $packed);
444 if ($rc === false) {
445 throw new InvalidDatabaseException(
446 'Could not unpack an unsigned short value from the given bytes.'
447 );
448 }
449
450 return $testint === current($rc);
451 }
452 }
453