• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSString "midstring()"
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSString "midstring()"


  • Subject: Re: NSString "midstring()"
  • From: "Stephen J. Butler" <email@hidden>
  • Date: Sun, 17 Apr 2011 16:47:14 -0500

On Sun, Apr 17, 2011 at 4:08 PM, JAMES ROGERS <email@hidden> wrote:
> I have stepped this through with the debugger and no flags were raised. The code compiles without an error or a warning of any kind. I am afraid your response has overwhelmed me.

You didn't see it in the debugger because you aren't using the right
kind of test data. Look at this example:

#import <Foundation/Foundation.h>

#define BUFFER_SIZE 65
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString *str1 = @"временный";
    NSString *str2 = nil;
    char buffer[BUFFER_SIZE + 1];
    int i, count;

    count = MIN( [str1 length], BUFFER_SIZE );
    for (i = 0; i < count; i++)
        buffer[i] = [str1 characterAtIndex:i];
    buffer[i] = 0x00;

    str2 = [NSString stringWithUTF8String:buffer];
    NSLog( @"str1 = %@", str1 );
    NSLog( @"str2 = %@", str2 );

    [pool drain];
    return 0;
}

This does not at all correctly copy the string. Also, while writing up
the example, I noticed you have a buffer overflow error. At the end of
the loop, j == 65 and the last index in your buffer is 64.

Now, compare with this example:

#import <Foundation/Foundation.h>

#define BUFFER_SIZE 5
int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString *str1 = @"временный";
    NSString *str2 = nil;
    char buffer[BUFFER_SIZE];
    NSUInteger i = 0, bufferLength;
    NSRange askRange, leftRange;

    NSLog( @"str1 = %@", str1 );
    while (i < [str1 length])
    {
        askRange = NSMakeRange( i, [str1 length] - i );
        if (![str1 getBytes:buffer
                  maxLength:BUFFER_SIZE
                 usedLength:&bufferLength
                   encoding:NSUTF8StringEncoding
                    options:0
                      range:askRange
             remainingRange:&leftRange])
        {
            NSLog( @"error: no characters to convert" );
            break;
        }

        str2 = [[[NSString alloc] initWithBytes:buffer
length:bufferLength encoding:NSUTF8StringEncoding] autorelease];
        NSLog( @"str2 = %@ (%d:%d)", str2, bufferLength, [str2 length] );

        i = leftRange.location;
    }

    [pool drain];
    return 0;
}

Notice how that even though the buffer is large enough to hold one
more 'character',
getBytes:maxLength:usedLength:encoding:options:range:remainingRange:
doesn't fill it because that would make the buffer contain an invalid
UTF8 character sequence.

> The "substring = [NSString stringWithUTF8String:sndBuffer]" was not my own and came from a website as a result of my query on "C string to NSString" and it works.

You should be very careful about copying code from another website
that you don't understand.
_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >NSString "midstring()" (From: JAMES ROGERS <email@hidden>)
 >Re: NSString "midstring()" (From: Quincey Morris <email@hidden>)
 >Re: NSString "midstring()" (From: JAMES ROGERS <email@hidden>)

  • Prev by Date: Re: NSString "midstring()"
  • Next by Date: Re: NSString "midstring()"
  • Previous by thread: Re: NSString "midstring()"
  • Next by thread: Re: NSString "midstring()"
  • Index(es):
    • Date
    • Thread