Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unserialize error with OrderedTimeCodec #494

Closed
mbabic131 opened this issue Feb 7, 2023 · 2 comments · Fixed by #496
Closed

Unserialize error with OrderedTimeCodec #494

mbabic131 opened this issue Feb 7, 2023 · 2 comments · Fixed by #496
Labels

Comments

@mbabic131
Copy link

Hi,
in my Symfony app I upgraded ramsey/uuid from v3.9.6 to v4.7.1 and ramsey/uuid-doctrine from v1.8.1 to v2.0.0.

After that upgrade app has started throwing error on UUID unserialize (when Symfony tries to unserialize session data).

Error:

In OrderedTimeCodec.php line 105:
                                                                     
  [Ramsey\Uuid\Exception\UnsupportedOperationException]              
  Attempting to decode a non-time-based UUID using OrderedTimeCodec  
                                                                     

Exception trace:
  at /app/vendor/ramsey/uuid/src/Codec/OrderedTimeCodec.php:105
 Ramsey\Uuid\Codec\OrderedTimeCodec->decodeBytes() at /app/vendor/ramsey/uuid/src/UuidFactory.php:269
 Ramsey\Uuid\UuidFactory->fromBytes() at /app/vendor/ramsey/uuid/src/Uuid.php:317
 Ramsey\Uuid\Uuid->unserialize() at /app/vendor/ramsey/uuid/src/Uuid.php:340
 Ramsey\Uuid\Uuid->__unserialize() at n/a:n/a

How to reproduce:

$factory = new UuidFactory();
$factory->setCodec(new OrderedTimeCodec(
    $factory->getUuidBuilder()
));

Uuid::setFactory($factory);
$uuid = Uuid::fromString('211a3b1e-928f-11ed-b52d-0242ac12000b');

$serializedUuid = serialize($uuid);
$unserializedUuid = unserialize($serializedUuid);

I have noticed that issue is somewhat related to OrderedTimeCodec specifically to rearrange of bytes for optimal storage.
If I add this code to Uuid::serialize() then unserialize works OK.

if ($this->codec instanceof OrderedTimeCodec) {
    $bytes = $this->getFields()->getBytes();
    $rearrangedBytes = $bytes[6] . $bytes[7]
        . $bytes[4] . $bytes[5]
        . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3]
        . substr($bytes, 8);

    return $rearrangedBytes;
}

This rearranges bytes before serialization and on unserialize OrderedTimeCodec will rearrange bytes to original order.

note: I provided this info here #259 (comment) but seems that this is a separate issue.

@Ph0tonic
Copy link
Contributor

Hello,
I had a look at your issues and think that I have identified the problem.
When serialising the uuid, the codec is not used anymore.
I have created a PR to fix this and added a test to assert that it is now working.
Maybe @ramsey can have a look and confirm that the change is legit.

@ramsey ramsey linked a pull request Apr 15, 2023 that will close this issue
7 tasks
@ramsey
Copy link
Owner

ramsey commented Apr 15, 2023

The fix for this is released in version 4.7.4. Thank you for your patience.

Thank you, @Ph0tonic, for the patch! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants