Search code examples
objective-cmacoscocoansdatadata-loss

NSData becomes null after a while


Currently I am working on an Objective-c / Cocoa app that finds images in other documents. However I am having an issue with the NSData I am analysing since after some time the NSData becomes null. Below is the code to create the NSData, get the length and some basic debugging.

/* Get Data */
NSError *error;
NSData *data = [NSData dataWithContentsOfFile:file options:NSDataReadingMapped error:&error];

/* Split Data into hex chunks */
/* Get length of data */
NSUInteger data_length = [data length];

/* Debug NSLogs */
NSLog(@"[1] Data length: %lu",(unsigned long)data_length);
NSLog(@"[1] Data: %@ with Error: %@",data,error);

When I NSLog the data here the document that was passed is written to the console in its hex representation.

However, when I try to process the data the debug NSLog at the end says the data is null. (The for loop checks the data for the hex FF) The code is below:

/* Declare start and end pointer */
NSUInteger start_point = data_length + 2;
NSUInteger end_pointer = data_length + 2;

/* loop through data */
for (NSUInteger i = 0; i < data_length; i++) {
    // Create Range
    NSRange range = NSMakeRange(i, (i+1));
    // Allocate Byte
    Byte byte[1];
    // Get data from data set
    [data getBytes:byte range:range];
    // Convert Byte (char representation) to NSData
    NSData *byte_data = [NSData dataWithBytes:byte length:1];
    // Set string representation of temp_data
    NSString *byte_check = [NSString stringWithFormat:@"%@",byte_data];
    // Check Byte
    if ([byte_check isEqualToString:@"<FF>"]) {
        // First byte found, check if next is correct
        NSRange range2 = NSMakeRange((i+1), (i+2));
        Byte byte2[1];
        [data getBytes:byte2 range:range2];
        NSData *byte_data2 = [NSData dataWithBytes:byte2 length:1];
        NSString *byte_check2 = [NSString stringWithFormat:@"%@",byte_data2];
        if ([byte_check2 isEqualToString:@"<E0>"]) {
            // Success found start of JPEG
            start_point = i;
            // set i to length + 1 to stop loop
            i = data_length + 1;
        }
    }
}

/* Debug point */
NSLog(@"pointer: %lu length: %lu",(unsigned long)end_pointer, (unsigned long)data_length);
NSLog(@"[2] DATA BYTES: %@ with Error: %@",data,error);

In the second part the length of the NSData also becomes 0.

Below is the NSLog output, I have shortened the hex output in order to not make it too long.

2015-09-10 21:11:24.935 PicRecover[51550:13961579] [1] Data length: 66528
2015-09-10 21:11:24.939 PicRecover[51550:13961579] [1] Data: <504b0304 ...
... 01000000> with Error: (null)
2015-09-10 21:11:24.960 PicRecover[51550:13961579] pointer: 0 length: 0
2015-09-10 21:11:24.960 PicRecover[51550:13961579] [2] DATA BYTES: (null) with Error: (null)

I hope someone understands the NSData more than I do and can point out my mistake. If you need any more information I can always add it.

Thank you very much in advance.


Solution

  • NSMakeRange takes an offset and a length, you are passing two offsets... This means your ranges are a lot larger than you think and you are writing all over memory, given your destination buffer is just one byte long.

    Also your check for a specific byte value is over complicated and unreliable as it uses the result of the description method (it's called when you do the stringWithFormat: call). You can just compare your byte value directly, as with any other integral type, e.g.:

    if (byte[0] == 0xFF) ...
    

    Finally look up what the break statement does.

    HTH