Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ios): fix conversion crash from oc object to CtxValue #3802

Merged
merged 2 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions driver/js/src/napi/jsc/jsc_ctx.cc
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,8 @@ std::shared_ptr<CtxValue> JSCCtx::CreateObject(const std::unordered_map<std::sha
auto ctx_value = std::static_pointer_cast<JSCCtxValue>(it.second);
if (!ctx_value) {
auto error = CreateException("CreateObject ctx_value is nullptr");
return nullptr;
SetException(std::static_pointer_cast<JSCCtxValue>(error));
continue;
}
JSObjectSetProperty(context_, obj, object_key, ctx_value->value_, kJSPropertyAttributeNone, &exception);
if (exception) {
Expand All @@ -817,7 +818,7 @@ std::shared_ptr<CtxValue> JSCCtx::CreateArray(size_t count,
JSValueRef values[count]; // NOLINT(runtime/arrays)
for (size_t i = 0; i < count; i++) {
auto ele_value = std::static_pointer_cast<JSCCtxValue>(array[i]);
values[i] = ele_value->value_;
values[i] = ele_value ? ele_value->value_ : nullptr;
}

JSValueRef exception = nullptr;
Expand Down
9 changes: 7 additions & 2 deletions framework/ios/utils/NSObject+CtxValue.mm
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ @implementation NSObject (CtxValue)

- (CtxValuePtr)convertToCtxValue:(const CtxPtr &)context; {
@autoreleasepool {
HippyLogWarn(@"%@ must implemente convertToCtxValue method", NSStringFromClass([self class]));
HippyLogWarn(@"%@ No convertToCtxValue method", NSStringFromClass([self class]));
std::unordered_map<CtxValuePtr, CtxValuePtr> valueMap;
return context->CreateObject(valueMap);
}
Expand Down Expand Up @@ -87,7 +87,9 @@ - (CtxValuePtr)convertToCtxValue:(const CtxPtr &)context {
id value = [self objectForKey:key];
auto keyPtr = [key convertToCtxValue:context];
auto valuePtr = [value convertToCtxValue:context];
valueMap[keyPtr] = valuePtr;
if (keyPtr && valuePtr) {
valueMap[keyPtr] = valuePtr;
}
}
return context->CreateObject(valueMap);
}
Expand All @@ -99,6 +101,9 @@ @implementation NSData (CtxValue)

- (CtxValuePtr)convertToCtxValue:(const CtxPtr &)context {
size_t bufferLength = [self length];
if (bufferLength == 0) {
return context->CreateNull();
}
void *buffer = malloc(bufferLength);
if (buffer) {
[self getBytes:buffer length:bufferLength];
Expand Down
89 changes: 89 additions & 0 deletions tests/ios/HippyOC2CtxValueTest.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*!
* iOS SDK
*
* Tencent is pleased to support the open source community by making
* Hippy available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#import <XCTest/XCTest.h>
#import <hippy/NSObject+CtxValue.h>
#import <hippy/HippyJSEnginesMapper.h>
#import "driver/engine.h"
#import "driver/scope.h"

@interface HippyOC2CtxValueTest : XCTestCase

@end

@implementation HippyOC2CtxValueTest

- (void)setUp {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

- (void)testOCObject2CtxValue {
auto engine = [[HippyJSEnginesMapper defaultInstance] createJSEngineResourceForKey:@"testKey"];
auto scope = engine->GetEngine()->CreateScope("testKey");

XCTestExpectation *expectation = [self expectationWithDescription:@"ToCtxValue"];
engine->GetEngine()->GetJsTaskRunner()->PostTask([scope, expectation](){
scope->CreateContext();
auto context = scope->GetContext();

NSMutableDictionary *testDic = [NSMutableDictionary dictionary];
NSMutableDictionary *nestedDic = [NSMutableDictionary dictionary];
nestedDic[@"testZeroData"] = [NSData data];
nestedDic[@"testNumber"] = @200;
nestedDic[@"testNull"] = [NSNull null];
nestedDic[@"testString"] = @"";
nestedDic[@"testString1"] = @"0";
nestedDic[@"testArray"] = @[];
nestedDic[@"testError"] = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:nil];
nestedDic[@"testDictionary"] = @{};
nestedDic[@"testURL"] = [NSURL URLWithString:@""];
std::shared_ptr<hippy::CtxValue> ctxValue = [nestedDic convertToCtxValue:context];
XCTAssert(ctxValue != nullptr);

testDic[@"testDic"] = nestedDic;
ctxValue = [testDic convertToCtxValue:context];
XCTAssert(ctxValue != nullptr);

ctxValue = [@[testDic, testDic, testDic] convertToCtxValue:context];
XCTAssert(ctxValue != nullptr);

NSMutableArray *testArr = [NSMutableArray array];
[testArr addObject:[NSData data]];
[testArr addObject:[NSDate date]];
[testArr addObject:[NSHashTable weakObjectsHashTable]];
[testArr addObject:[NSHTTPURLResponse new]];
XCTAssert([testArr convertToCtxValue:context] != nullptr);

[expectation fulfill];
});

[self waitForExpectationsWithTimeout:10 handler:^(NSError *error) {
NSLog(@"%@", error);
}];
}


@end
Loading