File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11CHANGELOG
22=========
33
4+ 1.10.0
5+ ------------------
6+
7+ * When using the pure PHP reader, unsigned integers up to PHP_MAX_INT
8+ will now be integers in PHP rather than strings. Previously integers
9+ greater than 2^24 on 32-bit platforms and 2^56 on 64-bit platforms
10+ would be strings due to the use of ` gmp ` or ` bcmath ` to decode them.
11+ Reported by Alejandro Celaya. GitHub #119 .
12+
4131.9.0 (2021-01-07)
514------------------
615
Original file line number Diff line number Diff line change 1212 *
1313 * We subtract 1 from the log to protect against precision loss.
1414 */
15- \define (__NAMESPACE__ . '\_MM_MAX_INT_BYTES ' , (log (\PHP_INT_MAX , 2 ) - 1 ) / 8 );
15+ \define (__NAMESPACE__ . '\_MM_MAX_INT_BYTES ' , (int ) (( log (\PHP_INT_MAX , 2 ) - 1 ) / 8 ) );
1616
1717class Decoder
1818{
@@ -320,11 +320,17 @@ private function decodeUint(string $bytes, int $byteLength)
320320
321321 $ integer = 0 ;
322322
323+ // PHP integers are signed. _MM_MAX_INT_BYTES is the number of
324+ // complete bytes that can be converted to an integer. However,
325+ // we can convert another byte if the leading bit is zero.
326+ $ useRealInts = $ byteLength <= _MM_MAX_INT_BYTES
327+ || ($ byteLength === _MM_MAX_INT_BYTES + 1 && (\ord ($ bytes [0 ]) & 0x80 ) === 0 );
328+
323329 for ($ i = 0 ; $ i < $ byteLength ; ++$ i ) {
324330 $ part = \ord ($ bytes [$ i ]);
325331
326332 // We only use gmp or bcmath if the final value is too big
327- if ($ byteLength <= _MM_MAX_INT_BYTES ) {
333+ if ($ useRealInts ) {
328334 $ integer = ($ integer << 8 ) + $ part ;
329335 } elseif (\extension_loaded ('gmp ' )) {
330336 $ integer = gmp_strval (gmp_add (gmp_mul ((string ) $ integer , '256 ' ), $ part ));
Original file line number Diff line number Diff line change @@ -64,9 +64,8 @@ public function testDecoder(): void
6464
6565 $ this ->assertSame (-268435456 , $ record ['int32 ' ]);
6666 $ this ->assertSame (100 , $ record ['uint16 ' ]);
67- $ this ->assertSame (\PHP_INT_MAX < 4294967295 && !\extension_loaded ('maxminddb ' ) ? '268435456 ' : 268435456 , $ record ['uint32 ' ]);
68- // @phpstan-ignore-next-line
69- $ this ->assertSame (\PHP_INT_MAX > 1152921504606846976 && \extension_loaded ('maxminddb ' ) ? 1152921504606846976 : '1152921504606846976 ' , $ record ['uint64 ' ]);
67+ $ this ->assertSame (268435456 , $ record ['uint32 ' ]);
68+ $ this ->assertSame (\PHP_INT_MAX > 1152921504606846976 ? 1152921504606846976 : '1152921504606846976 ' , $ record ['uint64 ' ]);
7069
7170 $ uint128 = $ record ['uint128 ' ];
7271
@@ -158,9 +157,8 @@ public function testGetWithPrefixLen(): void
158157 ],
159158 'uint128 ' => \extension_loaded ('maxminddb ' ) ? '0x01000000000000000000000000000000 ' : '1329227995784915872903807060280344576 ' ,
160159 'uint16 ' => 0x64 ,
161- 'uint32 ' => \PHP_INT_MAX < 4294967295 && !\extension_loaded ('maxminddb ' ) ? '268435456 ' : 268435456 ,
162- // @phpstan-ignore-next-line
163- 'uint64 ' => \PHP_INT_MAX > 1152921504606846976 && \extension_loaded ('maxminddb ' ) ? 1152921504606846976 : '1152921504606846976 ' ,
160+ 'uint32 ' => 268435456 ,
161+ 'uint64 ' => \PHP_INT_MAX > 1152921504606846976 ? 1152921504606846976 : '1152921504606846976 ' ,
164162 'utf8_string ' => 'unicode! ☯ - ♫ ' ,
165163 ];
166164 $ tests = [
You can’t perform that action at this time.
0 commit comments