fragment extension doc inadequately describes profile UUID generation #14171

Closed
opened 2026-01-31 04:02:53 +00:00 by claunia · 6 comments
Owner

Originally created by @jeremyd2019 on GitHub (Jun 9, 2021).

In https://docs.microsoft.com/en-us/windows/terminal/json-fragment-extensions#how-to-determine-the-guid-of-an-existing-profile, it says:

To determine the GUID of the profile to be updated, use a Version 5 UUID generator with the following namespace GUID and name:

  • The namespace GUID: {2BDE4A90-D05F-401C-9492-E40884EAD1D8}
  • The name of the profile to be updated

As a sanity check, a profile called 'Ubuntu' will get the generated GUID: {2C4DE342-38B7-51CF-B940-2309A097F518}

If you go online and search for "version 5 UUID generator", you will find several webpages. None of these result in the {2C4DE342... UUID for "Ubuntu".

More research revealed #870 which says:

Canonical Form: Name of profile encoded in BOM-less UTF-8 BOM-less UTF-16LE

That's an apparently important piece of information that was missing from the fragment doc. OK, so we'll probably need some custom code after all

import uuid
uuid.uuid5(uuid.UUID("{2BDE4A90-D05F-401C-9492-E40884EAD1D8}"), "Ubuntu".encode("UTF-16LE"))

This works for python2 (but who uses that anymore?), but on python3 this gives

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python38\lib\uuid.py", line 787, in uuid5
    hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest()
TypeError: encoding without a string argument

It seems that even Python hard-codes the fact that the name should be utf-8 encoded! Let's try a hack

import uuid
uuid.uuid5(uuid.UUID("{2BDE4A90-D05F-401C-9492-E40884EAD1D8}"), "Ubuntu".encode("UTF-16LE").decode("ASCII"))

That gives the expected answer.

So, to summarize, it seems like that doc should make it more clear that something unusual is going on in the UUID generation, rather than saying "just grab your nearest v5 UUID generator and plug these strings in".

Originally created by @jeremyd2019 on GitHub (Jun 9, 2021). <!-- Briefly describe which document needs to be corrected and why. --> In https://docs.microsoft.com/en-us/windows/terminal/json-fragment-extensions#how-to-determine-the-guid-of-an-existing-profile, it says: > To determine the GUID of the profile to be updated, use a Version 5 UUID generator with the following namespace GUID and name: > > * The namespace GUID: {2BDE4A90-D05F-401C-9492-E40884EAD1D8} > * The name of the profile to be updated > > As a sanity check, a profile called 'Ubuntu' will get the generated GUID: {2C4DE342-38B7-51CF-B940-2309A097F518} If you go online and search for "version 5 UUID generator", you will find several webpages. None of these result in the `{2C4DE342`... UUID for "Ubuntu". More research revealed #870 which says: > Canonical Form: Name of profile encoded in ~~BOM-less UTF-8~~ BOM-less UTF-16LE That's an apparently important piece of information that was missing from the fragment doc. OK, so we'll probably need some custom code after all ```python import uuid uuid.uuid5(uuid.UUID("{2BDE4A90-D05F-401C-9492-E40884EAD1D8}"), "Ubuntu".encode("UTF-16LE")) ``` This works for python2 (but who uses *that* anymore?), but on python3 this gives ``` Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python38\lib\uuid.py", line 787, in uuid5 hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest() TypeError: encoding without a string argument ``` It seems that even Python *hard-codes* the fact that the name should be utf-8 encoded! Let's try a hack ```python import uuid uuid.uuid5(uuid.UUID("{2BDE4A90-D05F-401C-9492-E40884EAD1D8}"), "Ubuntu".encode("UTF-16LE").decode("ASCII")) ``` That gives the expected answer. So, to summarize, it seems like that doc should make it more clear that something unusual is going on in the UUID generation, rather than saying "just grab your nearest v5 UUID generator and plug these strings in".
Author
Owner

@skyline75489 commented on GitHub (Jun 9, 2021):

CC @PankajBhojwani.

@skyline75489 commented on GitHub (Jun 9, 2021): CC @PankajBhojwani.
Author
Owner

@DHowett commented on GitHub (Jun 9, 2021):

Thanks for this. We'll make sure the docs get updated.

One note:

something unusual

I'm surprised by this characterization, but not offended. When I implemented the generator, I read this part of RFC4122 (excerpted below) to suggest that as the namespace owner we could define the layout of bytes inside it.

o  Convert the name to a canonical sequence of octets (as defined by
   the standards or conventions of its name space); 

I'm surprised Python specifies that the name is a string, actually. It precludes RFC4122 compliance! ☹️

@DHowett commented on GitHub (Jun 9, 2021): Thanks for this. We'll make sure the docs get updated. One note: > something unusual I'm surprised by this characterization, but not offended. When I implemented the generator, I read [this part of RFC4122](https://datatracker.ietf.org/doc/html/rfc4122#section-4.3) (excerpted below) to suggest that as the namespace owner we could define the layout of bytes inside it. o Convert the name to a canonical sequence of octets (as defined by the standards or conventions of its name space); I'm surprised Python specifies that the [name is a _string_](https://docs.python.org/3/library/uuid.html#uuid.uuid5), actually. It precludes RFC4122 compliance! ☹️
Author
Owner

@DHowett commented on GitHub (Jun 9, 2021):

UGH. Our documentation here is not correct¹.

The namespace GUID is actually based on the name of the folder/fragment name you're using, and it will be used to automatically generate a GUID if you haven't specified one.

Okay -- we can't change this because now we'll break compatibility with all user customizations on top of Fragments (grrr).

Here is the code that will generate the same GUID as Git Bash is already getting. You'll want to use this guid specifically, because doing anything else will separate the user's settings from your upstream document.

import uuid

# CALCULATE NAMESPACE BASED ON FRAGMENT FOLDER NAME
u = uuid.uuid5(uuid.UUID("{f65ddb7e-706b-4499-8a50-40313caf510a}"), "Git".encode("UTF-16LE").decode("ASCII"))

# CALCULATE FINAL BASED ON NAMESPACE
uuid.uuid5(u, "Git Bash".encode("UTF-16LE").decode("ASCII"))

# For Git/Git Bash: UUID('2ece5bfe-50ed-5f3a-ab87-5cd4baafed2b')

¹ The namespace GUID it provides is actually for the internal "Windows.Terminal.Wsl" namespace... which due to legacy reasons doesn't follow the same rules. It was authored in v0.5, and we didn't want to break user customizations back then either. 😬

@DHowett commented on GitHub (Jun 9, 2021): **UGH**. Our documentation here is not correct¹. The namespace GUID is actually based on the name of the folder/fragment name you're using, and it will be used to automatically generate a GUID if you haven't specified one. Okay -- we can't change this because now we'll break compatibility with all user customizations on top of Fragments (grrr). Here is the code that will generate the same GUID as Git Bash is already getting. You'll want to use this guid specifically, because doing anything else will separate the user's settings from your upstream document. ``` import uuid # CALCULATE NAMESPACE BASED ON FRAGMENT FOLDER NAME u = uuid.uuid5(uuid.UUID("{f65ddb7e-706b-4499-8a50-40313caf510a}"), "Git".encode("UTF-16LE").decode("ASCII")) # CALCULATE FINAL BASED ON NAMESPACE uuid.uuid5(u, "Git Bash".encode("UTF-16LE").decode("ASCII")) # For Git/Git Bash: UUID('2ece5bfe-50ed-5f3a-ab87-5cd4baafed2b') ``` ¹ The namespace GUID it provides is actually for the internal "Windows.Terminal.Wsl" namespace... which due to legacy reasons doesn't follow the same rules. It was authored in v0.5, and we didn't want to break user customizations back then either. 😬
Author
Owner

@jeremyd2019 commented on GitHub (Jun 9, 2021):

One note:

something unusual

I'm surprised by this characterization, but not offended. When I implemented the generator, I read this part of RFC4122 (excerpted below) to suggest that as the namespace owner we could define the layout of bytes inside it.
...

Yes, I chose that wording carefully. It's not "wrong" per the spec, but basically every generator I found seemed to not allow specifying the encoding, so it's apparently "unusual" to use something other than UTF-8.

I'm surprised Python specifies that the name is a string, actually. It precludes RFC4122 compliance! ☹️

Me too.

@jeremyd2019 commented on GitHub (Jun 9, 2021): > One note: > > > something unusual > > I'm surprised by this characterization, but not offended. When I implemented the generator, I read [this part of RFC4122](https://datatracker.ietf.org/doc/html/rfc4122#section-4.3) (excerpted below) to suggest that as the namespace owner we could define the layout of bytes inside it. ... Yes, I chose that wording carefully. It's not "wrong" per the spec, but basically every generator I found seemed to not allow specifying the encoding, so it's apparently "unusual" to use something other than UTF-8. > I'm surprised Python specifies that the [name is a _string_](https://docs.python.org/3/library/uuid.html#uuid.uuid5), actually. It precludes RFC4122 compliance! ☹️ Me too.
Author
Owner

@Okeanos commented on GitHub (Jun 10, 2021):

This looks very much like the issue I was having with the documentation a while ago.

@Okeanos commented on GitHub (Jun 10, 2021): This looks very much like the issue I was having with the [documentation](https://github.com/MicrosoftDocs/terminal/issues/320) a while ago.
Author
Owner

@Okeanos commented on GitHub (Feb 3, 2022):

@DHowett @jeremyd2019 changes to the documentation are now live 🎉 – I think this issue can be closed now.

Btw. @jeremyd2019 thanks for figuring in this out and getting the ball rolling – I took the liberty of adapting your initial approach and contribute it with some adaptions to the documentation repository.

@Okeanos commented on GitHub (Feb 3, 2022): @DHowett @jeremyd2019 changes to [the documentation](https://docs.microsoft.com/en-us/windows/terminal/json-fragment-extensions) are now live 🎉 – I _think_ this issue can be closed now. Btw. @jeremyd2019 thanks for figuring in this out and getting the ball rolling – I took the liberty of adapting your initial approach and contribute it with some adaptions to the documentation repository.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#14171