convertFollyDynamicToId - Don't crash if illegal value is return in one of the conversions

Summary:
Fixing T31692652.
I couldn't reproduce this on my local tests - (tried non-utf chars, deleted memory, onverted vectors that are erased).
My guess - an illegal string cannot be converted to NSSString and thus we return nil when the folly::dynamic type is STRING.

See task for additional details.

Reviewed By: nubbel

Differential Revision: D8952714

fbshipit-source-id: c87af523efca1b96a4cf3d5d26fa5c16ed5cd773
This commit is contained in:
Eldad Moneta
2018-07-24 06:43:46 -07:00
committed by Facebook Github Bot
parent c7ccff117f
commit 333ceac957

View File

@@ -11,7 +11,8 @@ namespace cxxutils {
* The implementation is taken from RCTFollyConvert(https://fburl.com/vzw8ql2q) * The implementation is taken from RCTFollyConvert(https://fburl.com/vzw8ql2q)
*/ */
id convertFollyDynamicToId(const folly::dynamic &dyn) { id convertFollyDynamicToId(const folly::dynamic &dyn)
{
// I could imagine an implementation which avoids copies by wrapping the // I could imagine an implementation which avoids copies by wrapping the
// dynamic in a derived class of NSDictionary. We can do that if profiling // dynamic in a derived class of NSDictionary. We can do that if profiling
// implies it will help. // implies it will help.
@@ -26,19 +27,24 @@ id convertFollyDynamicToId(const folly::dynamic &dyn) {
case folly::dynamic::DOUBLE: case folly::dynamic::DOUBLE:
return @(dyn.getDouble()); return @(dyn.getDouble());
case folly::dynamic::STRING: case folly::dynamic::STRING:
return [[NSString alloc] initWithBytes:dyn.c_str() length:dyn.size() return [[NSString alloc] initWithBytes:dyn.c_str() length:dyn.size() encoding:NSUTF8StringEncoding];
encoding:NSUTF8StringEncoding];
case folly::dynamic::ARRAY: { case folly::dynamic::ARRAY: {
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dyn.size()]; NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:dyn.size()];
for (auto &elem : dyn) { for (auto &elem : dyn) {
[array addObject:convertFollyDynamicToId(elem)]; id obj = convertFollyDynamicToId(elem);
if (obj) {
[array addObject:obj];
}
} }
return array; return array;
} }
case folly::dynamic::OBJECT: { case folly::dynamic::OBJECT: {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:dyn.size()]; NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:dyn.size()];
for (auto &elem : dyn.items()) { for (auto &elem : dyn.items()) {
dict[convertFollyDynamicToId(elem.first)] = convertFollyDynamicToId(elem.second); id obj = convertFollyDynamicToId(elem.second);
if (obj) {
dict[convertFollyDynamicToId(elem.first)] = obj;
}
} }
return dict; return dict;
} }
@@ -99,8 +105,7 @@ folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf)
} }
} else if ([json isKindOfClass:[NSString class]]) { } else if ([json isKindOfClass:[NSString class]]) {
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding]; NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
return std::string(reinterpret_cast<const char*>(data.bytes), return std::string(reinterpret_cast<const char *>(data.bytes), data.length);
data.length);
} else if ([json isKindOfClass:[NSArray class]]) { } else if ([json isKindOfClass:[NSArray class]]) {
folly::dynamic array = folly::dynamic::array; folly::dynamic array = folly::dynamic::array;
for (id element in json) { for (id element in json) {
@@ -111,8 +116,7 @@ folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf)
__block folly::dynamic object = folly::dynamic::object(); __block folly::dynamic object = folly::dynamic::object();
[json enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, __unused BOOL *stop) { [json enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, __unused BOOL *stop) {
object.insert(convertIdToFollyDynamic(key, nullifyNanAndInf), object.insert(convertIdToFollyDynamic(key, nullifyNanAndInf), convertIdToFollyDynamic(value, nullifyNanAndInf));
convertIdToFollyDynamic(value, nullifyNanAndInf));
}]; }];
return object; return object;
@@ -120,5 +124,5 @@ folly::dynamic convertIdToFollyDynamic(id json, bool nullifyNanAndInf)
return nil; return nil;
} }
}
} } }