Fri 04 Dec 2009 10:55:27 PM UTC, comment #3:
Okay, so on looking at the code again, I realized that it was simply trying to do a straight compare of non-Unicode strings when in fact one of them was Unicode. Here's a patch that resolves the problem (since the comparison logic for GSMutableStrings was correct, this just eliminates the incorrect code for GSStrings and combines the two).
I'm having trouble right now committing this in SVN myself, so I would appreciate if someone else would...
Index: GSString.m
===================================================================
--- GSString.m (revision 29096)
+++ GSString.m (working copy)
@@ -2113,7 +2113,7 @@
return YES;
return NO;
}
- else if (c == GSMutableStringClass)
+ else if (c == GSMutableStringClass || GSObjCIsKindOf(c, GSStringClass) == YES)
{
GSStr other = (GSStr)anObject;
NSRange r = {0, self->_count};
@@ -2144,26 +2144,6 @@
}
return NO;
}
- else if (GSObjCIsKindOf(c, GSStringClass) == YES)
- {
- GSStr other = (GSStr)anObject;
-
- /*
- * First see if the hash is the same - if not, we can't be equal.
- */
- if (self->_flags.hash == 0)
- self->_flags.hash = (*hashImp)((id)self, hashSel);
- if (other->_flags.hash == 0)
- other->_flags.hash = (*hashImp)((id)other, hashSel);
- if (self->_flags.hash != other->_flags.hash)
- return NO;
-
- if (other->_count == self->_count
- && memcmp(other->_contents.c, self->_contents.c, self->_count) == 0)
- return YES;
-
- return NO;
- }
else if (GSObjCIsKindOf(c, NSStringClass))
{
return (*equalImp)((id)self, equalSel, anObject);
|
Fri 04 Dec 2009 05:25:14 PM UTC, comment #2:
Whatever you changed seemed to fix one of my tests, but it's still broken. It appears that this GSUnicodeInlineString's _contents.c are incorrect, so it doesn't compare as equal to the other string.
Stepping through in gdb, at line 2161 in GSString.m I see this:
(gdb) po [anObject class]
GSUnicodeInlineString
(gdb) p (GSUnicodeInlineString *)anObject
$6 = (class GSUnicodeInlineString *) 0x8417748
(gdb) p *$6
$7 = {{{{{isa = 0xb7d7f720}}, _contents = {u = 0x8417758, c = 0x8417758 "c"}, _count = 3, _flags = {wide = 1,
owned = 1, unused = 0, hash = 111128}}}}
(gdb) p $6._contents.c
$8 = (unsigned char *) 0x8417758 "c"
(gdb) p *self
$9 = {{{{isa = 0xb7d7fb40}}, _contents = {u = 0x8417688, c = 0x8417688 "cat"}, _count = 3, _flags = {wide = 0,
owned = 1, unused = 0, hash = 111128}}}
|
Thu 03 Dec 2009 11:41:57 PM UTC, original submission:
Something is seriously broken in NSMutableDictionary with respect to GSUnicodeInlineString keys, as seen in this transcript from gdb. As you can see, the dictionary wasn't able to retrieve the object when the key was that type of string. This is using the latest tip of the trunk (r29095) but I think it has been broken for a while. This issue didn't exist back in r28259 or so.
(gdb) p [aKey hash]
$12 = 111128
(gdb) p [@"cat" hash]
$13 = 111128
(gdb) p [aKey isEqual:@"cat"]
$14 = 1 '\001'
(gdb) p [aKey isEqualToString:@"cat"]
$15 = 1 '\001'
(gdb) po theDict
{cat = "(species:\"feline\")"; "first name" = Mike; }
(gdb) p [theDict objectForKey:@"cat"]
$16 = (struct objc_object *) 0x83f3ef0
(gdb) p [theDict objectForKey:aKey]
$17 = (struct objc_object *) 0x0
(gdb) po [@"cat" class]
GSCBufferString
(gdb) po [aKey class]
GSUnicodeInlineString
(gdb) po [theDict class]
GSMutableDictionary
(gdb)
|