bugGNUstep - Bugs: bug #35699, NSStrings can point into garbage...

Group
 
 

bug #35699: NSStrings can point into garbage memory (misuse of app-supplied backing buffer)

Submitter:  Jens Alfke <snej>
Submitted:  Fri 02 Mar 2012 06:21:39 PM UTC
   
 
Category:  Base/Foundation Severity:  3 - Normal
Item Group:  Bug Status:  Fixed
Privacy:  Public Assigned to:  None
Open/Closed:  Closed
* Mandatory Fields

Add a New Comment Rich Markup
   

Fri 02 Mar 2012 07:10:27 PM UTC, comment #2: 

More a compatibility issue than a bug ... but in this case it's a probably a better behaviour too.  AFAIK this is an undocumented feature (I've never heard of it before), so perhaps we should document it?

I've always considered the NoCopy/freeWhenDone=NO method to be a variant for use with constant buffers, and code which uses non-constant buffers to be buggy (i.e. an app error to do that) unless it really knows what it's doing.

But the behaviour of implicitly copying in this situation is certainly more fault tolerant.
It still doesn't  deal with the case of code which modifies the buffer while the original string is using it, but such code is plainly asking for trouble :-)

Richard Frith-Macdonald <CaS>
Group Member
Fri 02 Mar 2012 06:54:31 PM UTC, comment #1: 

I looked at GSString.m a bit.
It seems that substring_c and substring_u should check the parent string's _flags.owned and create a GSSubString only if the flag is true; otherwise they should be conservative and create a regular string with a copy of the characters/bytes.

Jens Alfke <snej>
Fri 02 Mar 2012 06:21:39 PM UTC, original submission:  

NSString is insufficiently careful in its use of externally-provided buffers (i.e. passed to -initWithBytesNoCopy:).  Substrings created from such a string apparently point into the same temporary buffer, even after the original string is released, meaning that their contents become garbage as soon as the buffer contents become invalid.

In the test case below, the contents of the NSString 'substr' change if the temporary buffer is modified, even after the original string created from that buffer is released. This is of course likely to lead to very nasty side effects later on.

I don't know the details of Apple's NSString implementation, but my understanding is that the -substringWithRange: method should not allow the string it returns to share a buffer with the original string, when the original string uses ephemeral user-supplied memory.

TEST CASE

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);
    NSAssert([substr isEqualToString: @"HAZ"], @"bad substr");
    [str release];  // after this point nothing should be using the contents of buffer[]!
    memset(buffer, '*', sizeof(buffer));
    NSLog(@"substr = '%@'", substr);
    NSAssert([substr isEqualToString: @"HAZ"], @"bad substr");
}

Jens Alfke <snej>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by CaS (Posted a comment)
  • -email is unavailable- added by snej (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2012-03-02 CaS StatusNone Fixed
        Open/ClosedOpen Closed

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code