fix: prevent crash converting UUID timestamps near the Unix epoch
PhpTimeConverter::convertTime() threw an uncaught InvalidArgumentException for v1/v6 UUID timestamps within about 100 microseconds of the Unix epoch (on the pre-1970 side), because PHP renders such small floats in scientific notation, which splitTime() misparsed as a malformed microseconds fragment. splitTime() now recognizes scientific notation and defers to the existing GenericTimeConverter fallback, the same mechanism already used for other precision-loss cases.
This commit is contained in:
1 parent
a27d5edc8f
commit
90c8548448
2 files changed
+15
No files matched your search
@@ -26,6 +26,7 @@ use function dechex;
|
|||||||
use function explode;
|
use function explode;
|
||||||
use function is_float;
|
use function is_float;
|
||||||
use function is_int;
|
use function is_int;
|
||||||
|
use function str_contains;
|
||||||
use function str_pad;
|
use function str_pad;
|
||||||
use function strlen;
|
use function strlen;
|
||||||
use function substr;
|
use function substr;
|
||||||
@@ -142,6 +143,12 @@ class PhpTimeConverter implements TimeConverterInterface
|
|||||||
return ['sec' => $split[0], 'usec' => '0'];
|
return ['sec' => $split[0], 'usec' => '0'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Near zero PHP renders the float in scientific notation ("-1.0E-6"), whose
|
||||||
|
// exponent would be misparsed as microseconds; fall back instead.
|
||||||
|
if (str_contains($split[1], 'E')) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
// If the microseconds are less than six characters AND the length of the number is greater than or equal to the
|
// If the microseconds are less than six characters AND the length of the number is greater than or equal to the
|
||||||
// PHP precision, then it's possible that we lost some precision for the microseconds. Return an empty array so
|
// PHP precision, then it's possible that we lost some precision for the microseconds. Return an empty array so
|
||||||
// that we can choose to use the fallback converter.
|
// that we can choose to use the fallback converter.
|
||||||
|
|||||||
@@ -133,6 +133,14 @@ class PhpTimeConverterTest extends TestCase
|
|||||||
'unixTimestamp' => '0',
|
'unixTimestamp' => '0',
|
||||||
'microseconds' => '0',
|
'microseconds' => '0',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// One microsecond before the epoch: PHP renders "-1.0E-6", which must not
|
||||||
|
// be misparsed as microseconds.
|
||||||
|
[
|
||||||
|
'uuidTimestamp' => new Hexadecimal('1b21dd213813ff6'),
|
||||||
|
'unixTimestamp' => '0',
|
||||||
|
'microseconds' => '1',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user