Closed
Bug 279521
Opened 19 years ago
Closed 19 years ago
Add a way to generate UUIDs
Categories
(Core :: XPCOM, enhancement)
Core
XPCOM
Tracking
()
RESOLVED
FIXED
People
(Reporter: Biesinger, Assigned: vlad)
References
Details
(Keywords: fixed1.8.1)
Attachments
(1 file, 7 obsolete files)
12.54 KB,
patch
|
darin.moz
:
review+
shaver
:
superreview+
darin.moz
:
approval-branch-1.8.1+
|
Details | Diff | Splinter Review |
would be nice if xpcom provided a way to programmatically generate UUIDs. I have a patch for this, most of it done by Marja.
Comment 2•19 years ago
|
||
nsIUUID sounds to me like it is an uuid. But it isn't. maybe name it nsIUUIDGenerator or nsIUUIDService?
Generator, please, not Service. Generator tells you what it does, while Service really does not.
Comment 4•19 years ago
|
||
We already have MD5 code in the tree, and it is exposed via nsISignatureVerifier. Did you consider using that? It looks like you're putting this in XPCOM, which means that using nsISignatureVerifier would be somewhat of a problem, and maybe you want this to work even when PSM is not present? There may be subtle issues with adding crypto code outside of PSM. Can the implementation of this interface simply live in PSM? The algo uses gethostname. What if that returns "localhost" or "127.0.0.1"? Do we need to worry about that common case? Doesn't NSS/PSM have access to a better source of random data? Could we leverage that at all? The comment in get_random_info seems to suggest that we can play with that code a bit since it mentions a previous version including "struct sysinfo" in the input.
> https://bugzilla.mozilla.org/show_bug.cgi?id=279521 > > > darin@meer.net changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > CC| |wtchang@redhat.com > > > > > ------- Additional Comments From darin@meer.net 2005-02-09 09:21 PST > ------- > We already have MD5 code in the tree, and it is exposed via > nsISignatureVerifier. Did you consider using that? It looks like you're > putting this in XPCOM, which means that using nsISignatureVerifier would be > somewhat of a problem, and maybe you want this to work even when PSM is not > present? There may be subtle issues with adding crypto code outside of PSM. > > Can the implementation of this interface simply live in PSM? I'm quite new here and I don't know what PSM is or why it would be problematic to use nsISignatureVerifier. I simply want to have a way to generate urn uuids from javascript (ids for Annotea shared bookmarks and topics) and as the code already existed in Mozilla I was hoping to make it available through an interface also to others. It does not have to be its own XPCOM package, if it makes more sense to add it to another XPCOM package that's fine too. And the suggestion of changing the name to nsIUUIDGenerator if kept in its own package is good. The code to Mozilla probably came from http://www.ietf.org/internet- drafts/draft-mealling-uuid-urn-05.txt but I haven't checked if they are exactly same right now. I understood the draft was not far from being accepted so maybe it already is. Marja > > The algo uses gethostname. What if that returns "localhost" or "127.0.0.1"? > Do > we need to worry about that common case? Doesn't NSS/PSM have access to a > better source of random data? Could we leverage that at all? The comment > in > get_random_info seems to suggest that we can play with that code a bit since > it > mentions a previous version including "struct sysinfo" in the input. > > > -- > Configure bugmail: https://bugzilla.mozilla.org/userprefs.cgi?tab=email >
darin: not everyone builds psm and this is one of those times when having interfaces in a global location instead of a module would make some sense....
Comment 7•19 years ago
|
||
timeless: there won't be a global place for interfaces, but among the producing and consuming modules, there ought to be a most-primitive consumer in which to locate the interface. Then producers (more derived in the build process) can implement that interface (so can consumers as derived or moreso than the one that hosts the interface). Dependencies form a partial order, and humans can t-sort pretty well for small set size. /be
Comment 8•19 years ago
|
||
I would really like a uuid generator for a searchplugins-as-extensions patch I'm working on (and I don't mind depending on PSM, if we want to put the impl there): can we resolve whatever issues are remaining?
(In reply to comment #8) > I would really like a uuid generator for a searchplugins-as-extensions patch I'm > working on (and I don't mind depending on PSM, if we want to put the impl > there): can we resolve whatever issues are remaining? I thought this was already getting to the tree. I'm not sure how it will happen processwise? As I said earlier my goal is to be able to use this easily from javascript to create "urn:uid:..." identifiers. I'm not sure what PSM is or how using that would affect that goal. I really hope it does not mean I need to do more compiling as I still have problems with the Windows libraries in some cases (versions) and I could not get help to my questions concerning that. XPCOM would work well for me. Marja
Assignee | ||
Comment 10•19 years ago
|
||
A couple of issues with the patch... nsIUUID is a horrible interface name for a generator, same with @mozilla.org/uuid for the contractid. nsIUIIDGenerator && @mozilla.org/uuid-generator;1 would be preferable. Do we really need a new subdirectory in xpcom for this? It seems like all we need is nsIUUIDGenerator.idl and nsUUIDGenerator.h/cpp somewhere, even if the .cpp is somewhat large. What license is the code taken from mod_dav under? Is it compatible with (and can be used under) MPL/GPL/LGPL?
Assignee | ||
Comment 11•19 years ago
|
||
Here's my take on this.. just generates random-based UUIDs. It would be possible to create platform-specific implementations that return stronger IIDs, and change what UUID generator is returned by the uuid-generator contract ID on a per-platform basis, but this should be good enough to be usable.
Attachment #188643 -
Flags: review?(shaver)
Comment on attachment 188643 [details] [diff] [review] random uuid generator r=shaver, let's double up with darin.
Attachment #188643 -
Flags: superreview?(darin)
Attachment #188643 -
Flags: review?(shaver)
Attachment #188643 -
Flags: review+
Comment 13•19 years ago
|
||
Comment on attachment 188643 [details] [diff] [review] random uuid generator >Index: xpcom/base/nsRandomUUIDGenerator.cpp >+ PR_GetRandomNoise(id, sizeof(nsIID)); According to the documentation for PR_GetRandomNoise, size does matter. You need to check that the returned PRSize value is equal to sizeof(nsIID). If it is less, which can happen, then all of |id| would not be initialized to a random value. If this is not a problem somehow, then a comment in the code is at least warranted. >Index: xpcom/build/nsXPCOMCID.h >+/** >+ * UUID generator >+ */ >+#define NS_UUID_GENERATOR_CID \ >+{ 0x706d36bb, 0xbf79, 0x4293, \ >+{ 0x81, 0xf2, 0x8f, 0x68, 0x28, 0xc1, 0x8f, 0x9d } } >+#define NS_UUID_GENERATOR_CONTRACTID "@mozilla.org/uuid-generator;1" We are not consistent about exposing CIDs and ContractIDs, but I think that it would be better to only expose ContractIDs here. Or, is there some reason why someone would want to get at exactly this implementation of the contract? IOW, just put the CID definition in your nsUUIDGenerator.h file.
Attachment #188643 -
Flags: superreview?(darin) → superreview-
Assignee | ||
Comment 14•19 years ago
|
||
(In reply to comment #13) > (From update of attachment 188643 [details] [diff] [review] [edit]) > >Index: xpcom/base/nsRandomUUIDGenerator.cpp > > >+ PR_GetRandomNoise(id, sizeof(nsIID)); > > According to the documentation for PR_GetRandomNoise, size does > matter. You need to check that the returned PRSize value is > equal to sizeof(nsIID). If it is less, which can happen, then > all of |id| would not be initialized to a random value. If this > is not a problem somehow, then a comment in the code is at least > warranted. Youch, I didn't read the return value comment there. Ok, will fix. PR_GetRandomNoise isn't all /that/ random, but it should still be good enough for an initial implementation. I don't think that we have any good sources of entropy that we can get at from xpcom.
Assignee | ||
Comment 15•19 years ago
|
||
Ok, we correctly use the return value from GetRandomNoise now and abort if we can't get any noise. Moved the CID to nsRandomUUIDGenerator.h as well.
Attachment #188643 -
Attachment is obsolete: true
Assignee | ||
Updated•19 years ago
|
Attachment #188716 -
Flags: superreview?(darin)
Attachment #188716 -
Flags: review?(shaver)
Comment 16•19 years ago
|
||
Comment on attachment 188716 [details] [diff] [review] random uuid generator Don't use PR_GetRandomNoise. It has two problems. 1. It's simply not the right function. Its purpose is to get true randomness, which you would feed into a pseudorandom number generator (PRNG). A PRNG is what you should be using. 2. It is not well implemented. A good PRNG is the PK11_GenerateRandom function in the NSS library. I remember that Mozilla does not have direct access to the NSS library and must go through mozilla/security/manager. If so, you will need to implement a new method in mozilla/security/manager that exposes the functionality of PK11_GenerateRandom to Mozilla. I found an unimplemented method nsCrypto::Random, which might be appropriate. http://lxr.mozilla.org/mozilla/source/security/manager/ssl/src/nsCrypto.cpp#204 3
Attachment #188716 -
Flags: superreview?(darin)
Attachment #188716 -
Flags: review?(shaver)
Attachment #188716 -
Flags: review-
Assignee | ||
Comment 17•19 years ago
|
||
(In reply to comment #16) > (From update of attachment 188716 [details] [diff] [review] [edit]) > Don't use PR_GetRandomNoise. It has two problems. > 1. It's simply not the right function. Its purpose > is to get true randomness, which you would feed into > a pseudorandom number generator (PRNG). A PRNG is what > you should be using. 2. It is not well implemented. I understand that the purpose is to get true randomness; right now it only does that on platforms that have /dev/random (linux and the bsds). I can certainly use it as input for the libc PRNG via initstate/random, but that's not available on win32. It can fall back to rand/srand on windows (or whatever platform SDK functions are there for for randomness), I guess. I didn't see any PRNG implementation in NSPR -- did I miss one? > A good PRNG is the PK11_GenerateRandom function in > the NSS library. I remember that Mozilla does not > have direct access to the NSS library and must go > through mozilla/security/manager. If so, you will > need to implement a new method in mozilla/security/manager > that exposes the functionality of PK11_GenerateRandom > to Mozilla. I found an unimplemented method > nsCrypto::Random, which might be appropriate. That's all well and good, except that xpcom can't depend on NSS/secman.
Comment 18•19 years ago
|
||
On windows why don't we just use the platform uuid generator?
Comment 19•19 years ago
|
||
if we need to be using NSS to generate better UUID, then this implementation should live in PSM. Does anyone need to use this impl. when PSM isn't there?
Assignee | ||
Comment 20•19 years ago
|
||
(In reply to comment #19) > if we need to be using NSS to generate better UUID, then this implementation > should live in PSM. > > Does anyone need to use this impl. when PSM isn't there? In some theoretical world where people want to use individual components of our platform, I can see someone wanting to generate UUIDs without PSM. In reality, noone is going to be using xpcom without most of the rest of our platform. Also, if I'm looking for something that will generate UUIDs, PSM wouldn't be near the top of the list of places I'd look, but maybe that's just me. A lot of the current codebase is structured around that theoretical world, though. I've got a patch coming shortly (as soon as I find a win32 box to test on) that uses random() & friends on unix, and just uses UuidCreate on windows.
Comment 21•19 years ago
|
||
that patch sounds like it will solve the current problem. also, I think you will want to use CoCreateGuid() on windows.
Comment 22•19 years ago
|
||
rand and srand are not suitable for situations where you need the pseudorandom numbers to be unpredictable. In those situations you need to use a cryptographic PRNG such as PK11_GenerateRandom. For generating UUIDs you may not need that property. I think the property you need is "collision free". A secure hash algorithm such as MD5 or SHA-1 can give you that property.
Comment 23•19 years ago
|
||
Mozilla stores my user profile in a directory named C:\Documents and Settings\wtc\Application Data\Mozilla\Profiles\wtc\h5x3whmf.slt. I guess the code that generates the "h5x3whmf" string would meet your need?
Comment 24•19 years ago
|
||
> That's all well and good, except that xpcom can't depend on NSS/secman.
It can using an XPCOM interface defined in mozilla/xpcom/ somewhere. In fact,
why not just implement nsIUUIDGenerator in PSM? Define the interface in
mozilla/xpcom/ as you have, but implement it in PSM. We do this sort of thing
elsewhere.
Comment 25•19 years ago
|
||
> I guess the code that generates the "h5x3whmf" string
> would meet your need?
That code uses srand and rand. It uses the time of day as the seed.
Assignee | ||
Comment 26•19 years ago
|
||
Let's try this again. On the three platforms we care about: Linux/BSDs: PR_GetRandomNoise uses /dev/random to get randomness; we feed that into initstate()/random() (I can't believe there's a libc function called "initstate") MacOS X: same as Linux/BSDs Windows: We use CoCreateGuid (which just calls UuidCreate, but eh!) and it creates something that's presumably globally unique.
Attachment #188716 -
Attachment is obsolete: true
Attachment #188729 -
Flags: superreview?(darin)
Assignee | ||
Comment 27•19 years ago
|
||
Blah, posted the patch before I saw Darin's comment about just implementing the component in PSM. Yes, I guess I can do that, if that's preferable.
Reporter | ||
Comment 28•19 years ago
|
||
(In reply to comment #20) > In some theoretical world where people want to use individual components of our > platform, I can see someone wanting to generate UUIDs without PSM. some people do use standalone xpcom, I think... they might want this...
Who uses standalone XPCOM that we care about? But I'd rather use the platform's services here rather than having to initialize PSM in order to get a GUID. (I can see wanting to use this facility early in startup to generate UUIDs for ephemeral extensions or whatnot.)
Comment 30•19 years ago
|
||
(In reply to comment #14) >I don't think that we have any good sources of entropy that we can get at from xpcom. Our entropy collector lives in, yes you guessed it, our old friend PSM.
Comment 31•19 years ago
|
||
Comment on attachment 188729 [details] [diff] [review] random uuid generator, take 3 I don't think you need an explict init method on this interface. |generateUUID| could just call init internally if the state is not initalized.
Comment 32•19 years ago
|
||
Comment on attachment 188729 [details] [diff] [review] random uuid generator, take 3 according to msdn, UuidCreate isn't support everywhere you think: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidcr eate.asp I think you should use CoCreateGuid: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/8d5ce dea-8c2b-4918-99db-1a000989f178.asp
Assignee | ||
Comment 33•19 years ago
|
||
Comment on attachment 188729 [details] [diff] [review] random uuid generator, take 3 Blah, this is the wrong version of the patch.. I was confused why dougt was bringing up CoCreateGuid again when I did use CoCreateGuid, except apparently not in this diff. =/ New patch coming soon without the Init. (FTR, doug, CoCreateGuid is defined to just call UuidCreate, the MSDN links you gave explicitly say so! :)
Attachment #188729 -
Flags: superreview?(darin)
Assignee | ||
Comment 34•19 years ago
|
||
Ok, no more Init method, and use CoCreateGuid on win32. (nsID and GUID are supposed to be compatible structures, right?)
Assignee | ||
Updated•19 years ago
|
Attachment #188729 -
Attachment is obsolete: true
Attachment #188746 -
Flags: superreview?(darin)
Assignee | ||
Updated•19 years ago
|
Attachment #188746 -
Flags: superreview?(darin)
Assignee | ||
Comment 35•19 years ago
|
||
Patches late at night are bad, and lead to uninitialized variables.
Attachment #188746 -
Attachment is obsolete: true
Attachment #188752 -
Flags: superreview?(darin)
Attachment #188752 -
Flags: review?(shaver)
Reporter | ||
Comment 36•19 years ago
|
||
why not use NS_GENERIC_FACTORY_CONSTRUCTOR_INIT? That avoids having to check mInitialized each time.
Reporter | ||
Updated•19 years ago
|
Assignee: cbiesinger → vladimir
Reporter | ||
Comment 37•19 years ago
|
||
also: should this use a threadsafe isupports impl (the class seems to be threadsafe, at least with that init change I suggested)? and, is it supposed to be used as a service or a normal component?
Comment on attachment 188752 [details] [diff] [review] uuid generator, take 5 r=shaver with biesi's two comments (NS_GENERIC_FACTORY_CONSTRUCTOR_INIT and threadsafe nsISupports impl) addressed.
Attachment #188752 -
Flags: review?(shaver) → review+
Comment 39•19 years ago
|
||
So, if I create two of these generators, and init them both and then ask each to generate a GUID for me, will random() do the right thing? Yeah, I think so. Now, what if the same thing is done on two threads? Maybe we don't care.
Reporter | ||
Comment 40•19 years ago
|
||
the question is: Is this supposed to be used as a service or as a component?
Comment 41•19 years ago
|
||
Using it as a service seems like a good idea, since it avoids that problem. Perhaps it wants to be renamed to indicate that it is intended to be a service?
Comment 42•19 years ago
|
||
see comment #3.
Comment 43•19 years ago
|
||
nsIUUIDGeneratorService?
Comment 44•19 years ago
|
||
not that i care one way or the other... but... we don't have to have a rule requiring interface names suffixed with Service to ensure that users will use GetService to aquire them. The IDL should state that this is a servcie and, maybe, the implementation's factory should protect to ensure that it remains a singleton. but I do not dislike the name you proposed.
Comment 45•19 years ago
|
||
I'm fine with the current interface name, and the interface name doesn't need to indicate how the component that implements that interface should be instantiated. That is best documented alongside the ContractID for the component. As I said before, maybe there is no concern here. I don't know if the OS implementation of initstate/random is re-entrant, but probably it is.
Comment 46•19 years ago
|
||
Comment on attachment 188752 [details] [diff] [review] uuid generator, take 5 >Index: xpcom/base/nsIUUIDGenerator.idl >+ >+[scriptable, uuid(138ad1b2-c694-41cc-b201-333ce936d8b8)] >+interface nsIUUIDGenerator : nsISupports please add a comment above the interface describing what this interface is for, etc. >+{ >+ /** >+ * Obtains a new GUID using appropriate platform-specific methods to >+ * obtain an IID that can be considered to be globally unique. >+ * >+ * @returns an nsIID filled in with a new GUID. >+ * >+ * @throws NS_ERROR_FAILURE if a UUID cannot be generated (e.g. if >+ * an underlying source of randomness is not available) >+ */ >+ nsIIDPtr generateUUID(); >+}; I recomment being consist with terminology. Replace GUID with UUID. I think the return type should be nsIDPtr instead of nsIIDPtr because this is not solely for use with generating interface IDs. you could use it to generate UUIDs for any purpose, so keep the type name generic. Do we want a version of this function that is [noscript] that allows the caller to pass in an allocated nsID struct? That way the caller can allocate the nsID struct on the stack instead of being forced to heap allocate the object? >Index: xpcom/base/nsRandomUUIDGenerator.cpp >+#if !defined(WIN32) >+#include <stdlib.h> >+#else >+#include <windows.h> >+#endif Prefer XP_WIN to WIN32 in preprocessor fu. Also, I think it's slightly cleaner to write: #if defined(XP_WIN) #include <windows.h> #else #include <stdlib.h> #endif >+nsresult >+nsRandomUUIDGenerator::Init() >+{ >+#if !defined(WIN32) Again, I would put the XP_WIN case first. No reason for the "!" >+ unsigned int seed; >+ >+ PRSize bytes = 0; >+ while (bytes < sizeof(seed)) { >+ PRSize nbytes = PR_GetRandomNoise(((unsigned char *)&seed)+bytes, sizeof(seed)-bytes); >+ if (nbytes == 0) { >+ return NS_ERROR_FAILURE; >+ } >+ bytes += nbytes; >+ } >+ >+ initstate(seed, mState, sizeof(mState)); >+ >+ mRBytes = 4; What happens on 64-bit platforms where sizeof(long) is 8? Is RAND_MAX always at most 0xffffffff on these platforms? >+ NS_ASSERTION(sizeof(GUID) == sizeof(nsIID), "GUID and nsIID aren't the same size!"); This assertion is pretty gratuitous, but ok ;-) >+ nsIID *id = new nsIID; s/nsIID/nsID/ >Index: xpcom/build/nsXPCOMCID.h >+/** >+ * UUID generator >+ */ >+#define NS_UUID_GENERATOR_CONTRACTID "@mozilla.org/uuid-generator;1" Historically, this header file has only been used to record frozen contract IDs. Is this a frozen contract ID? If so, then please be sure to include documentation about what interfaces this class implements. I'm not sure we want to freeze this guy.
Attachment #188752 -
Flags: superreview?(darin) → superreview-
Assignee | ||
Comment 47•19 years ago
|
||
Sounds good; I'll get a new patch up incorporating the comments over the weekend. As for RAND_MAX, I think it's 0x7fffffff everywhere -- but I'm i'm not positive; worst case the nrbytes bit just means we'll end up using only 4 of the generated bytes instead of 7-8.
Comment 48•19 years ago
|
||
Comment on attachment 173692 [details] [diff] [review] patch removing old request flag.
Attachment #173692 -
Flags: review?(dougt) → review-
Assignee | ||
Comment 49•19 years ago
|
||
Resurrecting this, as a bunch of people have asked me about the functionality recently. (In reply to comment #46) > Do we want a version of this function that is [noscript] that allows > the caller to pass in an allocated nsID struct? That way the caller > can allocate the nsID struct on the stack instead of being forced to > heap allocate the object? Do we? I can go either way; what would be a name for the noscript function? generateUUIDShared?
generateUUIDInPlace?
Assignee | ||
Comment 51•19 years ago
|
||
Updated.
Attachment #173692 -
Attachment is obsolete: true
Attachment #188752 -
Attachment is obsolete: true
Attachment #203585 -
Flags: review?(darin)
Comment 52•19 years ago
|
||
Comment on attachment 203585 [details] [diff] [review] uuid-generator-6.patch >--- xpcom/base/nsRandomUUIDGenerator.cpp >+NS_IMETHODIMP >+nsRandomUUIDGenerator::GenerateUUID(nsID** ret) >+{ >+ nsID *id = new nsID; perhaps you should use NS_Alloc instead of 'new' to ensure that the correct heap allocator is used across XPCOM boundaries. >+ delete id; NS_Free >--- xpcom/build/nsXPComInit.cpp b7a64c3a770fcce7b569b92179b2dda36aa4def3 >+#define NS_UUID_GENERATOR_CONTRACTID "@mozilla.org/uuid-generator;1" >+#define NS_UUID_GENERATOR_CLASSNAME "UUID Generator" >+#define NS_UUID_GENERATOR_CID NS_RANDOM_UUID_GENERATOR_CID I think these should be moved to nsUUIDGenerator.h. Not sure why there is a NS_UUID_GENERATOR_CID and a NS_RANDOM_UUID_GENERATOR_CID. Seems like you only need one of those defines.
Attachment #203585 -
Flags: review?(darin) → review-
Assignee | ||
Comment 53•19 years ago
|
||
Updated with review comments. I went and changed the nsRandomUUIDGenerator implementation class name to nsUUIDGenerator as well -- at one point I thought it might be useful to support multiple UUID generators, e.g. one that always generates a random-type UUID and another that generates a host-based UUID or something, but I realize now that that isn't all that useful.
Attachment #203585 -
Attachment is obsolete: true
Attachment #203824 -
Flags: superreview?(shaver)
Attachment #203824 -
Flags: review?(darin)
Updated•19 years ago
|
Attachment #203824 -
Flags: review?(darin) → review+
Comment on attachment 203824 [details] [diff] [review] uuid-generator-7.patch r=shaver
Comment on attachment 203824 [details] [diff] [review] uuid-generator-7.patch sr=shaver, I should say.
Attachment #203824 -
Flags: superreview?(shaver) → superreview+
Assignee | ||
Comment 56•19 years ago
|
||
Checked in
Status: NEW → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
By the way, shouldn't this hit the 1.8 branch at some point? Any plans?
Comment 58•18 years ago
|
||
I'd really like to use this for bug 326506. Could we get this in on the branch?
Blocks: 326506
So surely we're going to want this for Firefox 2, which means that this should hit the 1.8 branch soon? I'll gladly spin the 1.8 patch if that's all that's holding us up here. Or maybe there's some other reason why no progress has been made on getting this into the 1.8 branch?
Comment 60•18 years ago
|
||
Comment on attachment 203824 [details] [diff] [review] uuid-generator-7.patch would like to land this on the branch for use by the metrics service. I tested that the code compiles cleanly with no changes.
Attachment #203824 -
Flags: approval-branch-1.8.1?(darin)
Comment 61•18 years ago
|
||
Comment on attachment 203824 [details] [diff] [review] uuid-generator-7.patch a=darin
Attachment #203824 -
Flags: approval-branch-1.8.1?(darin) → approval-branch-1.8.1+
You need to log in
before you can comment on or make changes to this bug.
Description
•