Skip to content

Uuid::isValid is opinionated about encoding #60331

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

Closed
adrianrudnik opened this issue May 2, 2025 · 1 comment
Closed

Uuid::isValid is opinionated about encoding #60331

adrianrudnik opened this issue May 2, 2025 · 1 comment

Comments

@adrianrudnik
Copy link
Contributor

Symfony version(s) affected

7.2

Description

I'm currently trying to implement a simple denormalizer for API platform that allows invalid UUID values like "abc" to hit the validator of the DTO property path instead of producing a hard "The input data is misformatted." exception. First I thought it might be a quirk within the vendor, but simplifying it to the following shows some unexpected behavior:

Using symfony/uids own commands I get the following:

bin/console uuid:generate --random-based

8131873f-5df8-49c2-92af-38ee4c0bfbb2

bin/console uuid:inspect 8131873f-5df8-49c2-92af-38ee4c0bfbb2

 ----------------------- -------------------------------------- 
  Label                   Value                                 
 ----------------------- -------------------------------------- 
  Version                 4                                     
  toRfc4122 (canonical)   8131873f-5df8-49c2-92af-38ee4c0bfbb2  
  toBase58                GxJ74kHnMFDTtatLm9gQvV                
  toBase32                41663KYQFR97195BSRXS60QYXJ            
  toHex                   0x8131873f5df849c292af38ee4c0bfbb2    
 ----------------------- -------------------------------------- 

yet simple validation checks seem to be all over the place:

Uuid::isValid('8131873f-5df8-49c2-92af-38ee4c0bfbb2') // true
Uuid::isValid('41663KYQFR97195BSRXS60QYXJ'); // false
Uuid::isValid('GxJ74kHnMFDTtatLm9gQvV'); // false

Ulid::isValid('8131873f-5df8-49c2-92af-38ee4c0bfbb2') // false
Ulid::isValid('41663KYQFR97195BSRXS60QYXJ') // true
Ulid::isValid('GxJ74kHnMFDTtatLm9gQvV') // false

So I'm unsure about the following points, maybe I'm missing something and this all expected:

I see there is an attempt to satisfy the RFC by juggling a second parameter, but I do not understand why it would matter that early in the code, because a developer should be able to pass any valid-encoded value and the implementation is very strict about the encodings that can go in.

Then the whole process breaks at the point where Ulid::isValid is used within Uuid::transformToRfc9562. What is the whole && $format & self::FORMAT_BASE_32 part protecting against, and why are we handling a Ulid all of the sudden?

A similar question was raised in #45148 but with no real outcome.

How to reproduce

See description for simple code snippets.

Possible Solution

During development I expected the following given:

  • Uuid:isValid should validate any encoding, and fail ULIDs and invalid values.
  • Ulid::isValid should validate any encoding and fail UUIDs and invalid values.

As for the vendors weird behavior:

  • UidNormalizer should be split into UuidNormalizer and UlidNormalizer if there is such a stark contrast between both and not be based on the abstract. This split is also done on the validator constraints as well.
  • UidNormalizer could use RFC 9562s NilUuid as an indication that there is no processable value there, allowing the Uuid constraint to actually fail (NilUuid is invalid) instead of the de/normalizer beforehand.

Additional Context

No response

@adrianrudnik
Copy link
Contributor Author

After a round-trip through the RFCs and docs, I'll close this. Reading the 7.2 docs I see now that Uuid::FORMAT_ALL was introduced as a second parameter to isValid in a way that does not use PHP function signature with default values, but a magical variant that hides it from IDEs. Not sure why, but that solves it.

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

No branches or pull requests

3 participants