Information Leaks on [NSJSONSerialization dataWithJSONObject:data]
The senior iOS engineer, Plasma, write this article, and I just translate it into English.
NSData* data = [NSJSONSerialization dataWithJSONObject:self.parameters options:0 error:&error];
We found previous codes might leak other data inside memory space, but why? [NSJSONSerialization dataWithJSONObject: options: error:] says its return value is
JSON data for obj, or nil if an internal error occurs. The resulting data is encoded in UTF-8.
The resulting data is encoded in UTF-8. Hmmmm, it looks like the return value is a String.
Then let’s take a look at NSData:
A static byte buffer that bridges to Data
That means, it represents a block of bytes on the memory space essentially; even the return value is the type of NSData; in essence, it can be considered to an NSString.
So we can convert NSData to NSString by NSString* jsonDataAsString = [NSString stringWithUTF8String:[data bytes]];
Now the problem is [NSData bytes] is a pointer to the data object’s contents. When we look into its definition, it is actually a void *
pointer to the data.
@property(readonly) const void *bytes;
With [NSString stringWithUTF8String:]
Returns an NSString object initialized by copying the characters from a given C array of UTF8-encoded bytes.
Objective-C is still a kind of C, with many C behaviors. The C string is a byte array that requires 0x00
in the tail. For example, “Hello”, the actual The representation in the memory will be 0x48 0x65 0x6c 0x6c 0x6f 0x00
. If there is no ending 0x00
, then C language will think that the string has not ended, so it looks down.
But [NSJSONSerialization’s dataWithJSONObject: options: error:] didn’t say the NSData it returns is a null-terminated C string, and then it is not …
Because NSData is “A static byte buffer in memory”, [NSData bytes] directly returns this buffer. When the program wants to get a JSON string, it did not encounter 0x00
after reading the JSON String in data, it did not encounter 0x00, so it continued to go down.
And the latter memory just contains other data, so it was put in together, and it didn’t end until it encountered 0x00
luckily! That is a very typical buffer overflow error.