[Top][All Lists]

[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 

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.


Attachment: smime.p7s
Description: S/MIME cryptographic signature

reply via email to

[Prev in Thread] Current Thread [Next in Thread]