[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Nasty NSString bug (garbage buffers)
From: |
Jens Alfke |
Subject: |
Nasty NSString bug (garbage buffers) |
Date: |
Fri, 2 Mar 2012 10:29:24 -0800 |
I just found and filed a rather nasty NSString bug
<https://savannah.gnu.org/bugs/index.php?35699>. If you create an NSString
object using -initWithBytesNoCopy: — i.e. its backing store points to an
app-supplied memory buffer — then new NSStrings created as substrings of it
also end up pointing into that same buffer. The effect then is that, even if
you’re careful and never use the original string anymore after the buffer
contents become invalid, you’ve still got the substrings around, and their
contents change into garbage sooner or later when the buffer’s memory gets
reused for something else (i.e. very soon thereafter, if the buffer was on the
stack.)
Here’s a very simple example:
void test(void)
{
char buffer[] = "I HAZ A BUFFER";
NSString* str = [[NSString alloc] initWithBytesNoCopy: buffer
length: strlen(buffer)
encoding: NSUTF8StringEncoding
freeWhenDone: NO];
NSString* substr = [str substringWithRange: NSMakeRange(2, 3)];
NSLog(@"substr = '%@'", substr);
[str release];
memset(buffer, '*', sizeof(buffer));
NSLog(@"substr = '%@'", substr);
}
The first logged line shows that substr is equal to @"HAZ", as expected.
The second logged line shows that its contents have morphed into @"***"!
The bug seems to be that NSString allows substrings to share a backing store
with the source string, even if the source string’s backing store consists of
ephemeral caller-supplied memory. That shouldn’t be allowed in this case.
The workaround of course is just to use -initWithBytes: instead, at the cost of
some extra memory allocation/copying.
—Jens
smime.p7s
Description: S/MIME cryptographic signature
- Nasty NSString bug (garbage buffers),
Jens Alfke <=