Lê Khánh Vinh
Lê Khánh Vinh

Reputation: 2611

iOS Objective C substringToIndex crash

I'm working with an old project with some validation rule.

My problem with few barcode scanning string which has lesser then certain character. The program will crash for the following line of code

if ([[sBarcodeValues substringToIndex:6] isEqualToString:@"2C2C2P"]){

}

Here is the error log (below is picture contain detail):

2016-12-22 14:51:56.019324 SAMKiosk[1008:476815] -[ScanAndPayVC checkBarCodeDetail]: sBarcodeValues 11.10
2016-12-22 14:51:56.019839 SAMKiosk[1008:476815] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSTaggedPointerString substringToIndex:]: Index 6 out of bounds; string length 5'
*** First throw call stack:
(0x1889611b8 0x18739855c 0x188961100 0x189386e80 0x1002ad930 0x1002a8320 0x1002a5bb8 0x19019ca54 0x19019c5f0 0x18b2b1d94 0x18b2d0dcc 0x10070d218 0x100719334 0x100727f94 0x10070f300 0x10071a8ac 0x100710ce0 0x10071205c 0x18890e810 0x18890c3fc 0x18883a2b8 0x18a2ee198 0x18e87a7fc 0x18e875534 0x1000e0414 0x18781d5b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

enter image description here

Maybe because string is only contain 5 characters when the checking require 6. How can we prevent this crashing happen?

Upvotes: 2

Views: 1394

Answers (2)

Ronak Chaniyara
Ronak Chaniyara

Reputation: 5436

It is a good practice that you check the string length before substring.

You can check that as follows:

if (sBarcodeValues.length>=6 && [[sBarcodeValues substringToIndex:6] isEqualToString:@"2C2C2P"]){

}

Edit:

If you want use only substringToIndex then length check is necessary to prevent crash.

Otherwise, hasPrefix will do the work.

Upvotes: 1

rmaddy
rmaddy

Reputation: 318944

You are correct that the crash will happen anytime sBarcodeValues is less than 6 characters.

You can add an additional check for the length:

if (sBarcodeValues.length >= 6 && [[sBarcodeValues substringToIndex:6] isEqualToString:@"2C2C2P"]) {
}

or you can simply do:

if ([sBarcodeValues hasPrefix:@"2C2C2P"]) {
}

This will work no matter how long sBarcodeValues is.

Upvotes: 5

Related Questions