0

I'm looking at some code that creates a mutable data object and puts a SHA1 hash into it. If I initialize the target mutable data object with

CFMutableDataRef hashDataRef = (CFMutableDataRef)[[NSMutableData alloc] initWithLength:SHA_DIGEST_LENGTH];

everything works fine. If I change that one line to

CFMutableDataRef hashDataRef = CFDataCreateMutable(kCFAllocatorDefault, SHA_DIGEST_LENGTH);

it breaks (the mutable data object appears to still be empty after the SHA1 command). In both cases, the line that follows the creation of hashDataRef is

SHA1(CFDataGetBytePtr(inputDataRef), CFDataGetLength(inputDataRef), CFDataGetMutableBytePtr(hashDataRef));

I hadn't expected there to be any difference between the two, but clearly I'm missing something. Is there a proper Core Foundation way to get the mutable data object I want without using NSMutableData and toll-free bridging?

Isaac
  • 10,668
  • 5
  • 59
  • 68

1 Answers1

3

NSMutableData initWithLength: creates a data object whose raw data is filled with zeros, but CFDataCreateMutable creates an empty CFMutableDataRef. Even though it was created with a capacity, its length is still zero. So, when you use CFDataGetMutableBytePtr, it returns a NULL pointer.

To fix it, you could fill the CFMutableDataRef to its capacity using CFDataSetLength, which fills the data with zeros.

wquist
  • 2,569
  • 1
  • 15
  • 14
  • 3
    Might be worth noting that `CFDataCreateMutable()` is more similar to `-[NSMutableData initWithCapacity:]`. – Justin Spahr-Summers Jun 30 '12 at 01:00
  • 1
    Actually, that similarity is misleading. The capacity of `CFDataCreateMutable()` is a strict limit. The "capacity" of `-[NSMutableData initWithCapacity:]` is just a lower bound of the *first* allocation (when that happens), but does not prevent the object from being grown beyond that. It's mostly just an optimization. – Ken Thomases Jun 30 '12 at 13:10