iOS handling crash EXC_CRASH (SIGSEGV) with source code - ios

I have received the following error from one of our clients with an exact place where the crash happen.
Error report:
Symbolize build number: 89778
2Incident Identifier: 8B5F5ADE-295C-4596-8B34-37280A38511A
3Hardware Model: iPhone13,2
4Process: Glip [73149]
5Path: /private/var/containers/Bundle/Application/D2CA9563-630A-470F-BC84-A9E6546D5B71/SomeApp.app
6Identifier: SomeApp
7Version: 89778 (21.2.35)
8AppStoreTools: 12E506
9AppVariant: 1:iPhone13,2:14
10Code Type: ARM-64 (Native)
11Role: unknown
12Parent Process: launchd [1]
13Coalition: com.glip.mobile [7033]
14
15
16Date/Time: 2021-07-06 18:29:00.1537 -0700
17Launch Time: 2021-07-06 18:28:56.2301 -0700
18OS Version: iPhone OS 14.6 (18F72)
19Release Type: User
20Baseband Version: 1.71.01
21Report Version: 104
22
23Exception Type: EXC_CRASH (SIGSEGV)
24Exception Codes: 0x0000000000000000, 0x0000000000000000
25Exception Note: EXC_CORPSE_NOTIFY
26Termination Signal: Segmentation fault: 11
27Termination Reason: Namespace SIGNAL, Code 0xb
28Terminating Process: Glip [73149]
29Triggered by Thread: 0
30
31Thread 0 name:
32Thread 0 Crashed:
330 CoreFoundation 0x000000018ed62ea4 __CFStringChangeSizeMultiple + 148 (CFString.c:1032)
341 CoreFoundation 0x000000018ed5d874 __CFStringAppendBytes + 708 (CFString.c:1149)
352 CoreFoundation 0x000000018ed4d800 __CFStringAppendFormatCore + 9220 (CFString.c:8375)
363 CoreFoundation 0x000000018ed619fc _CFStringAppendFormatAndArgumentsAux2 + 68 (CFString.c:7556)
374 CoreFoundation 0x000000018ec8af58 -[__NSCFString appendFormat:] + 120 (CFObject.m:462)
385 Pendo 0x0000000114173794 -[NSString(IIOStringUtils) pnd_toHexString:length:] + 116
396 Pendo 0x00000001141733cc -[NSString(IIOStringUtils) pnd_SHA256] + 112
The code responsible for the crash is the following:
//my stack trace is get called from this method (don't think its matter in that case)
- (nonnull NSString *)pnd_SHA1 {
unsigned int outputLength = CC_SHA1_DIGEST_LENGTH;
unsigned char output[outputLength];
CC_SHA1(self.UTF8String, [self pnd_UTF8Length], output);
return [NSString pnd_toHexString:output length:outputLength];
}
- (NSString *)pnd_SHA256 {
unsigned int outputLength = CC_SHA256_DIGEST_LENGTH;
unsigned char output[outputLength];
CC_SHA256(self.UTF8String, [self pnd_UTF8Length], output);
return [self pnd_toHexString:output length:outputLength];
}
- (NSString*)pnd_toHexString:(unsigned char*) data length:(unsigned int)length {
NSMutableString* hash = [NSMutableString stringWithCapacity:length * 2];
for (unsigned int i = 0; i < length; i++) {
[hash appendFormat:#"%02x", data[i]];
data[i] = 0;
}
return [hash copy];
}
From quick look I immediately blamed the following line:
[hash appendFormat:#"%02x", data[i]];
So I reproduced the crash by:[hash appendFormat:nil];
And the local report I got: (which is similar BUT not exact)
Process: MyApp [45754]
Path: /Users/USER/Library/Developer/CoreSimulator/Devices/EAEA42C2-3B8F-48EF-B1D3-BEA68FE046A0/data/Containers/Bundle/Application/DE83DA67-70A9-4ECF-92B9-526137C6E4B3/MyApp
Identifier: PendoDevelopmentApp
Version: 1.0 (1)
Code Type: X86-64 (Native)
Parent Process: launchd_sim [24742]
Responsible: SimulatorTrampoline [957]
User ID: 502
Date/Time: 2021-07-21 14:42:56.804 +0300
OS Version: Mac OS X 10.15.7 (19H1217)
Report Version: 12
Bridge OS Version: 5.4 (18P4663)
Anonymous UUID: 74B25560-EFCE-769F-F0B4-E4DD4C6B09A4
Sleep/Wake UUID: F52FC80E-F86E-4813-B352-D0A7B5FF87B2
Time Awake Since Boot: 120000 seconds
Time Since Wake: 6700 seconds
System Integrity Protection: enabled
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [45754]
VM Regions Near 0:
-->
__TEXT 000000010f038000-000000010f0bc000 [ 528K] r-x/r-x SM=COW /Users/USER/Library/Developer/CoreSimulator/Devices/EAEA42C2-3B8F-48EF-B1D3-BEA68FE046A0/data/Containers/Bundle/Application/DE83DA67-70A9-4ECF-92B9-526137C6E4B3/MyApp
Application Specific Information:
CoreSimulator 732.18.6 - Device: iPhone 11 Pro Max (EAEA42C2-3B8F-48EF-B1D3-BEA68FE046A0) - Runtime: iOS 13.0 (17A577) - DeviceType: iPhone 11 Pro Max
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 com.apple.CoreFoundation 0x00007fff23b1df08 __CFStringAppendFormatCore + 536
1 com.apple.CoreFoundation 0x00007fff23b395cc _CFStringAppendFormatAndArgumentsAux2 + 60
2 com.apple.CoreFoundation 0x00007fff23accba8 -[__NSCFString appendFormat:] + 184
3 io.pendo.PendoSDKFramework 0x000000010f35061d -[NSString(IIOStringUtils) pnd_toHexString:length:] + 109 (NSString+IIOStringUtils.m:111)
4 io.pendo.PendoSDKFramework 0x000000010f35010f -[NSString(IIOStringUtils) pnd_SHA256] + 175 (NSString+IIOStringUtils.m:57)
and fixed the code as follows:
+ (NSString*)pnd_toHexString:(unsigned char*)data length:(unsigned int)length {
if (data == nil || data == NULL) {
IIOCriticalLog(#"hash diget is nil");
return nil;
}
NSMutableString* hash = [NSMutableString stringWithCapacity:length * 2];
for (unsigned int i = 0; i < length; i++) {
NSString *str = [NSString stringWithFormat:#"%02x",data[i]];
if (str == nil) {
IIOCriticalLog(#"hash diget was corrupted");
return nil;
}
[hash appendString:str];
data[i] = 0;
}
return [hash copy];
}
The problem that I am still not 100% sure how it could happen for only this specific client as for how the appendString could get a nil.
Maybe somebody had a similar issue.

Related

Crash on one specific Unity scene in iOS build - TexturesMetal::AddCreatedTexture

I am having a crash only on one specific scene in my AR Foundation Unity build with the following error.
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000020
VM Region Info: 0x20 is not in any region. Bytes before following region: 4362387424
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
__TEXT 10404c000-104050000 [ 16K] r-x/r-x SM=COW ...lycoroTestApp
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [5380]
Triggered by Thread: 28
Thread 28 name:
Thread 28 Crashed:
0 libobjc.A.dylib 0x0000000195ac5ac0 objc_retain + 16 (objc-object.h:636)
1 UnityFramework 0x00000001066d5320 TexturesMetal::AddCreatedTexture(TextureID, id, bool) + 32 (TexturesMetal.mm:481)
2 UnityFramework 0x0000000106634828 GfxDeviceWorker::RunCommand(ThreadedStreamBuffer&) + 21972 (GfxDeviceWorker.cpp:0)
3 UnityFramework 0x00000001066aa2ec GfxDeviceWorkerAutoreleasePoolProxy + 68 (GfxDeviceMetal.mm:5242)
4 UnityFramework 0x0000000106636bd0 GfxDeviceWorker::RunExt(ThreadedStreamBuffer&) + 92 (GfxDeviceWorker.cpp:389)
5 UnityFramework 0x0000000106636b68 GfxDeviceWorker::Run() + 156 (GfxDeviceWorker.cpp:373)
6 UnityFramework 0x000000010662ef70 GfxDeviceWorker::RunGfxDeviceWorker(void*) + 12 (GfxDeviceWorker.cpp:352)
7 UnityFramework 0x00000001062289f8 Thread::RunThreadWrapper(void*) + 496 (Thread.cpp:81)
8 libsystem_pthread.dylib 0x00000001c9777c74 _pthread_start + 288 (pthread.c:887)
9 libsystem_pthread.dylib 0x00000001c977c878 thread_start + 8
At first I thought it was because I was missing the Environmental Probe manager in that scene (no). Then I thought perhaps it was because I was using a specific shader that didn't use a _MainTex. But I use that shader no problem in other working scenes.
And then I built the scene with only a simple primitive and my UI and still received this error. After that crash the scene did open successfully, but obviously the problem is still there. The UI is the exact same as the other working scenes.
I can't find out much about this specific error: TexturesMetal::AddCreatedTexture - only that there may be this bug with GLES3 and PVRTC textures - but they aren't present in the most recent build.
https://issuetracker.unity3d.com/issues/ios-crash-in-uploadtexture-at-texturesmeta-dot-mm-or-drawbufferranges-at-gfxdevicegles-dot-cpp-using-atlas-with-pvrtc-compress
The scene works perfectly in Android - it only crashes in iOS.
Any ideas? Full report below.
I ran a Product>Analysis in Xcode and it gave me this warning:
/Users/xcodeclub/Downloads/Eliot Silver/Classes/UI/UnityView.mm:200:5: nil returned from a method that is expected to return a non-null value
For this bit of Code in UnityView.mm:
static Class UnityRenderingView_LayerClassMTL(id self_, SEL _cmd)
{
return NSClassFromString(#"CAMetalLayer");
}
static Class UnityRenderingView_LayerClassNULL(id self_, SEL _cmd)
{
return NSClassFromString(#"CALayer");
}
#implementation UnityRenderingView
(Class)layerClass
{
return nil;
}
(void)InitializeForAPI:(UnityRenderingAPI)api
{
IMP layerClassImpl = api == apiMetal ? (IMP)UnityRenderingView_LayerClassMTL : (IMP)UnityRenderingView_LayerClassNULL;
class_replaceMethod(object_getClass([UnityRenderingView class]), #Selector(layerClass), layerClassImpl, UIView_LayerClass_Enc);
}
#End

Swift framework with a C lib inside: Got segmentation fault during working with C types

I'm building swift wrapper for PJSIP C lib.
I faced with a strange behaviour of memory alloc/free.
This func produces seg fault error [old plain NULL pointer]:
pjsua_msg_data is a C struct
static func makePj(fromHeaders headers: [SipHeader],
pool: inout UnsafeMutablePointer<pj_pool_t>) -> pjsua_msg_data {
var msgData = pjsua_msg_data()
pjsua_msg_data_init(&msgData)
pj_list_init(&msgData.hdr_list)
for header in headers {
let pjHeader = header.toPj(pool: &pool)
pj_list_push_back(&msgData.hdr_list, pjHeader)
}
return msgData
}
This implementation works (difference is that msgData as inout param)
static func makePj(fromHeaders headers: [SipHeader],
msgData: inout pjsua_msg_data,
pool: inout UnsafeMutablePointer<pj_pool_t>) {
pjsua_msg_data_init(&msgData)
pj_list_init(&msgData.hdr_list)
for header in headers {
let pjHeader = header.toPj(pool: &pool)
pj_list_push_back(&msgData.hdr_list, pjHeader)
}
}
Usage
var msgData = pjsua_msg_data()
var pool = try API.shared.createMemPool("pool", block: 4096, increment: 1024)
defer { try? API.shared.releaseMemPool(pool) }
if !headers.isEmpty {
// - usage of working implementations
//MessageData.makePj(fromHeaders: headers,
// msgData: &msgData,
// pool: &pool)
// - seg fault implementation usage
msgData = MessageData.makePj(fromHeaders: headers,
pool: &pool)
}
try callPJSUA {
pjsua_call_make_call(accountId,
&uriStr,
&callSetting,
nil,
&msgData,
&callId)
}
Little bit about framework:
it's a just Swift wrapper under C lib.
This framework then linked to the iOS app
Question:
I don't understand why inout param works but returning value doesn't.
Can I change this swift compiler behaviour? Build settings or smth else ?
Exception:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Codes: 0x0000000000000001, 0x0000000000000000
VM Region Info: 0 is not in any region. Bytes before following region: 4365074432
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
--->
__TEXT 1042dc000-1056ec000 [ 20.1M] r-x/r-x SM=COW ...app/CallScape
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: SIGNAL 11 Segmentation fault: 11
Terminating Process: exc handler [2095]
Thread 11 name: Dispatch queue: working.queue
Thread 11 Crashed:
0 SDK 0x10d3f3f28 pjsip_hdr_clone + 36
1 SDK 0x10d6d7454 pjsua_msg_data_clone + 280
2 SDK 0x10d6d7454 pjsua_msg_data_clone + 280
3 SDK 0x10d6cc4c8 pjsua_call_make_call + 1276
4 SDK 0x10d38a710 specialized CallAPI.make(_:destinationURI:setting:headers:) + 1268
5 SDK 0x10d389de8 protocol witness for CallAPI.make(_:destinationURI:setting:headers:) in conformance API + 12
6 SDK 0x10d39c8a8 Call.make(to:setting:headers:) + 152

backtrace miss the function that caused a crash

I use backtrace and backtrace_symbols to collect the call stack when my app crashed.
void InstallSignalHandler(void)
{
signal(SIGHUP, SignalExceptionHandler);
signal(SIGINT, SignalExceptionHandler);
signal(SIGQUIT, SignalExceptionHandler);
signal(SIGABRT, SignalExceptionHandler);
signal(SIGILL, SignalExceptionHandler);
signal(SIGSEGV, SignalExceptionHandler);
signal(SIGFPE, SignalExceptionHandler);
signal(SIGBUS, SignalExceptionHandler);
signal(SIGPIPE, SignalExceptionHandler);
}
void SignalExceptionHandler(int signal)
{
NSMutableString *mstr = [[NSMutableString alloc] init];
[mstr appendString:#"Stack:\n"];
void* callstack[128];
int i, frames = backtrace(callstack, 128);
char** strs = backtrace_symbols(callstack, frames);
for (i = 0; i <frames; ++i) {
[mstr appendFormat:#"%s\n", strs[i]];
}
NSLog(#"%#", mstr);
free(strs);
}
When I check the log in console, I just find the log miss the function that caused the crash.The function is:
+ (void)testCrash
{
int *nullPointer = NULL;
*nullPointer = 2019;
}
And the log in console is:
0 TestApp 0x0000000101d1e040 SignalExceptionHandler + 160
1 libsystem_platform.dylib 0x000000011002bb5d _sigtramp + 29
2 ??? 0x0000000000000000 0x0 + 0
3 TestApp 0x00000001019bbc6f __39+[MyCrashTesting showInViewController:]_block_invoke + 303
4 UIKit 0x000000010b09a559 -[UIAlertController _invokeHandlersForAction:] + 105
5 UIKit 0x000000010b09af5e __103-[UIAlertController _dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:dismissCompletion:]_block_invoke.461 + 16
6 UIKit 0x000000010ae42ca2 -[UIPresentationController transitionDidFinish:] + 1346
7 UIKit 0x000000010ae46b12 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke.436 + 183
8 UIKit 0x000000010ba2a3b4 -[_UIViewControllerTransitionContext c
I have thought the function name "testCrash" should be in the top of the log. Does I do something wrong?
Since this is a very simple method with no arguments and no ARC heavylifting inside clang the Objective-C compiler is able to do an optimization (-O1 is enough to achieve that) of removing the message runtime call.
You can prevent this behavior with:
+ (void)testCrash __attribute__((optnone))
{
int *nullPointer = NULL;
*nullPointer = 2019;
}
The lesson learnt here is you should never rely on particular stacktrace to achieve something during your program execution. Diagnostics is fine as long as you understand the optimizing principles you've just encountered.

SpeechKit SDK (Dragon Mobile) - Crash on Initialization

We have a repeating crash when initilizing Speechkit.
It only happens sometimes on both iOS7 & iOS8 and we could not identify a specific scenario.
We were using ver. 1.0.3 and upgraded to 1.4.12. This issue happens in both versions.
The trace looks like:
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x00000000
Thread : Crashed: com.apple.main-thread
0 CoreFoundation 0x25521ca4 CFArrayGetCount + 23
1 24me 0x00548de1 -[TAGPValue(Hash) hash]
2 24me 0x00548de1 -[TAGPValue(Hash) hash]
3 24me 0x00548bf3 -[TAGPValue(Hash) hash]
4 24me 0x00548513 -[TAGPValue(Hash) hash]
5 24me 0x0054b6a9 -[TAGPValue(Hash) hash]
6 24me 0x0038ab17 -[ViewController setupTextToSpeechInterface] (ViewController.m:1370)
7 24me 0x0037a481 -[ViewController viewDidLoad] (ViewController.m:196)
//this is the method we use to initialise
-(void)setupTextToSpeechInterface{
if (![SpeechKit sessionID]) {
[SpeechKit setupWithID:#"XXXXXXXXXXXX"
host:#"ti.nmdp.nuancemobility.net"
port:443
useSSL:NO
delegate:nil];
}
}

Why my [UIScrollView removeFromSuperview] is crashing?

The crash log is below.
Do you know any particular reason why might [UIScrollView removeFromSuperview] can crash? The scrollview contains view hierarchy with different types of UIViews. I also finds that the ad hoc version crash often not the debug version. I could not find any reason for that.
Same viewcontroller is loaded in a different flow in iPhone that works fine. But in iPad it crashes.
In iPad, in a container view controller, only viewcontroler.view is loaded.
Incident Identifier: EE102239-34D1-4BE7-8B52-41F74AB26203
CrashReporter Key: 2b11ea2a01ac5618e199ffc5a1e1f321600bb6a9
Hardware Model: iPad3,4
Version: ??? (???)
Code Type: ARM (Native)
Parent Process: launchd [1]
Date/Time: 2013-06-18 15:19:16.132 +0200
OS Version: iOS 6.1.3 (10B329)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000000
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x3bab7070 prepareForMethodLookup + 20
1 libobjc.A.dylib 0x3bab6fb2 lookUpMethod + 42
2 libobjc.A.dylib 0x3bab6f7e _class_lookupMethodAndLoadCache3 + 14
3 libobjc.A.dylib 0x3bab6638 objc_msgSend_uncached + 24
4 QuartzCore 0x357f2a72 CA::Layer::contents_visibility_changed(CA::Transaction*, bool) + 50
5 QuartzCore 0x357f29de CA::Layer::mark_visible(CA::Transaction*, bool) + 190
6 QuartzCore 0x357f29b2 CA::Layer::mark_visible(CA::Transaction*, bool) + 146
7 QuartzCore 0x357f29b2 CA::Layer::mark_visible(CA::Transaction*, bool) + 146
8 QuartzCore 0x357f29b2 CA::Layer::mark_visible(CA::Transaction*, bool) + 146
9 QuartzCore 0x357f29b2 CA::Layer::mark_visible(CA::Transaction*, bool) + 146
10 QuartzCore 0x357f28d2 CA::Layer::update_removed_sublayer(CA::Transaction*, unsigned int) + 18
11 QuartzCore 0x357f255a CA::Layer::remove_sublayer(CA::Transaction*, CALayer*) + 130
12 QuartzCore 0x357f246a CA::Layer::remove_from_superlayer() + 34
13 UIKit 0x35a6e92c -[UIView(Hierarchy) removeFromSuperview] + 144
14 UIKit 0x35b857bc -[UIScrollView removeFromSuperview] + 60
15 MyApp 0x000bde8a -[iPadNavigationController vcAnimationDone] (iPadNavigationController.m:400)
16 UIKit 0x35a55ab6 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 154
17 UIKit 0x35aca8f8 -[UIViewAnimationState animationDidStop:finished:] + 44
18 QuartzCore 0x35801304 CA::Layer::run_animation_callbacks(void*) + 204
19 libdispatch.dylib 0x3bed55d8 _dispatch_client_callout + 20
20 libdispatch.dylib 0x3bed8e40 _dispatch_main_queue_callback_4CF + 224
21 CoreFoundation 0x33c051ac __CFRunLoopRun + 1284
22 CoreFoundation 0x33b78238 CFRunLoopRunSpecific + 352
23 CoreFoundation 0x33b780c4 CFRunLoopRunInMode + 100
24 GraphicsServices 0x37733336 GSEventRunModal + 70
25 UIKit 0x35a942b4 UIApplicationMain + 1116
A few line from the code (as asked),
previous = showing;
showing = [ vc retain ];
showing.view.frame = startFrameIn;
[ container addSubview:showing.view ];
CGContextRef context = UIGraphicsGetCurrentContext();
[ UIView beginAnimations:nil context:context ];
[ UIView setAnimationDelegate:self ];
[ UIView setAnimationDidStopSelector:#selector(vcAnimationDone) ];
[ UIView setAnimationCurve:UIViewAnimationCurveEaseOut ];
[ UIView setAnimationDuration:0.4 ];
previous.view.frame = endFrameOut;
showing.view.frame = detailFrame;
[ UIView commitAnimations ];
}
- (void) vcAnimationDone {
if ( previous != nil ) {
if (previous.view.superview != nil) {
[previous.view removeFromSuperview];
}
[ previous release ];
previous = nil;
}
A very probable reason is that you are overreleasing your scrollview or one of the views inside it.
Calling removeFromSuperview then deallocates the view instead of simply decreasing the retain count.
Actually, if you are still stuck with non-ARC project, Static Code Analysis is very useful for this kind of bug. Retain/release balancing issues are hard to pin down, and nearly impossible with incomplete method so I suggest you post the full method body if possible.
Thanks everyone for your answers, tips and tricks. However one thing I want share with you is the cause of the crash. I found that the crash was at different thread in different times. I had several views loaded with button pressing/menu in my iPad app. Some of the button pressing fetch data from web service. So I was bit confused to get the cuase of crash, animation, or url connection etc... I tried with enabled NSZombie objects, but it did not show any information.
Then I tried with Guard Malloc. This only runs in Simulator. And magically I found the code point of crash. I have function to convert a hex string into data. There I have line of code to make a C string null terminated. where I assigned 0 at the last index. and that makes the crash!
tmpCh[count] = 0;
I do not why, but probably it takes some time in the memory management procedure in iOS so it crash at different thread at different times. But with Guard malloc in Simulator, it always point out here and when I rewrite the code, the crash is gone.
/* Converts a hex string to bytes.
Precondition:
. The hex string can be separated by space or not.
. the string length without space or 0x, must be even. 2 symbols for one byte/char
. sample input: 23 3A F1 OR 233AF1
*/
+ (NSData *) dataFromHexString:(NSString*)hexString
{
if (hexString.length < 1) {
return nil;
}
char * tmpCh = (char *) malloc([hexString length] * sizeof(char));
int count = 0;
for (int k=0; k<hexString.length;k++) {
char c = [hexString characterAtIndex:k];
if (c == (char)0x20) { //skip space
continue;
}
if (c == '0') { // skip 0x
if(k+1 < hexString.length){
if ([hexString characterAtIndex:k+1] == 'x'
|| [hexString characterAtIndex:k+1] == 'X' )
{
k = k + 1;
continue;
}
}
}
tmpCh[count] = c;
count++;
}
tmpCh[count] = 0; // make null terminated string
if (count % 2) {
return nil;
}
NSString *temp = [[NSString alloc] initWithUTF8String:tmpCh];
free(tmpCh);
if ([temp length] % 2 != 0) {
return nil;
}
NSMutableData *result = [[NSMutableData alloc] init];
unsigned char byte;
char hexChars[3] = {0};
for (int i=0; i < (temp.length/2); i++) {
hexChars[0] = [temp characterAtIndex:i*2];
hexChars[1] = [temp characterAtIndex:i*2+1];
if (![Util isValidChar:hexChars[0]] || ![Util isValidChar:hexChars[1]]) {
return nil;
}
byte = strtol(hexChars, NULL, 16);
[result appendBytes:&byte length:1];
}
NSData * data = [NSData dataWithData:result];
[result release];
return data;
}

Resources