| @@ -62,7 +62,7 @@ static void GetCommonFunc(ani_vm* vm, ani_ref savePtr, |
| webviewControllerPeer->releaseRefFunc = std::move(releaseRefFunc); | webviewControllerPeer->releaseRefFunc = std::move(releaseRefFunc); |
| } | } |
| | |
| -static bool GetFileSelectorObject(ani_env* env, const char* classDesc, ani_object* obj, void* args) | +static bool GetObjectFromPtr(ani_env* env, const char* classDesc, ani_object* obj, void* args) |
| { | { |
| ani_class cls; | ani_class cls; |
| if (env->FindClass(classDesc, &cls) != ANI_OK) { | if (env->FindClass(classDesc, &cls) != ANI_OK) { |
| @@ -92,13 +92,13 @@ static void DefaultOnShowFileSelector(ani_vm* vm, void* paramPeer, void* resultP |
| return; | return; |
| } | } |
| ani_object paramObj; | ani_object paramObj; |
| - if (!GetFileSelectorObject(env, "arkui.component.web.FileSelectorParam", ¶mObj, paramPeer)) { | + if (!GetObjectFromPtr(env, "arkui.component.web.FileSelectorParam", ¶mObj, paramPeer)) { |
| release(paramPeer); | release(paramPeer); |
| release(resultPeer); | release(resultPeer); |
| return; | return; |
| } | } |
| ani_object resultObj; | ani_object resultObj; |
| - if (!GetFileSelectorObject(env, "arkui.component.web.FileSelectorResult", &resultObj, resultPeer)) { | + if (!GetObjectFromPtr(env, "arkui.component.web.FileSelectorResult", &resultObj, resultPeer)) { |
| release(resultPeer); | release(resultPeer); |
| return; | return; |
| } | } |
| @@ -130,6 +130,39 @@ static void DefaultOnShowFileSelector(ani_vm* vm, void* paramPeer, void* resultP |
| HILOGI("Call defaultOnShowFileSelector done"); | HILOGI("Call defaultOnShowFileSelector done"); |
| } | } |
| | |
| +static void DefaultPermissionClipboard(ani_vm* vm, void* peer, std::function<void()> release) |
| +{ |
| + HILOGI("Call defaultPermissionClipboard start"); |
| + ani_env* env = GetAniEnv(vm); |
| + if (!env) { |
| + HILOGE("DefaultPermissionClipboard callback env is nullptr"); |
| + release(); |
| + return; |
| + } |
| + ani_object obj; |
| + if (!GetObjectFromPtr(env, "arkui.component.web.PermissionRequest", &obj, peer)) { |
| + release(); |
| + return; |
| + } |
| + ani_class cls; |
| + if (env->FindClass("@ohos.web.permissionRequest.PermissionClipboard", &cls) != ANI_OK) { |
| + HILOGE("FindClass fail: PermissionClipboard"); |
| + return; |
| + } |
| + ani_static_method method; |
| + if (env->Class_FindStaticMethod(cls, "defaultPermissionClipboard", |
| + "C{arkui.component.web.PermissionRequest}:", |
| + &method) != ANI_OK) { |
| + HILOGE("Class_FindStaticMethod fail, defaultPermissionClipboard"); |
| + return; |
| + } |
| + if (env->Class_CallStaticMethod_Void(cls, method, obj) != ANI_OK) { |
| + HILOGE("Call defaultPermissionClipboard fail"); |
| + return; |
| + } |
| + HILOGI("Call defaultPermissionClipboard done"); |
| +} |
| + |
| static void GetWebOptionsFunc(ani_vm* vm, ani_ref savePtr, | static void GetWebOptionsFunc(ani_vm* vm, ani_ref savePtr, |
| WebviewControllerPeer* webviewControllerPeer) | WebviewControllerPeer* webviewControllerPeer) |
| { | { |
| @@ -167,10 +200,14 @@ static void GetWebOptionsFunc(ani_vm* vm, ani_ref savePtr, |
| auto defaultOnShowFileSelectorFunc = [vm](void* paramPeer, void* resultPeer, std::function<void(void*)> release) { | auto defaultOnShowFileSelectorFunc = [vm](void* paramPeer, void* resultPeer, std::function<void(void*)> release) { |
| DefaultOnShowFileSelector(vm, paramPeer, resultPeer, std::move(release)); | DefaultOnShowFileSelector(vm, paramPeer, resultPeer, std::move(release)); |
| }; | }; |
| + auto defaultPermissionClipboardFunc = [vm](void* peer, std::function<void()> release) { |
| + DefaultPermissionClipboard(vm, peer, std::move(release)); |
| + }; |
| webviewControllerPeer->setWebIdFunc = std::move(setWebIdFunc); | webviewControllerPeer->setWebIdFunc = std::move(setWebIdFunc); |
| webviewControllerPeer->setHapPathFunc = std::move(setHapPathFunc); | webviewControllerPeer->setHapPathFunc = std::move(setHapPathFunc); |
| webviewControllerPeer->setWebDetachFunc = std::move(setWebDetachFunc); | webviewControllerPeer->setWebDetachFunc = std::move(setWebDetachFunc); |
| webviewControllerPeer->defaultOnShowFileSelectorFunc = std::move(defaultOnShowFileSelectorFunc); | webviewControllerPeer->defaultOnShowFileSelectorFunc = std::move(defaultOnShowFileSelectorFunc); |
| + webviewControllerPeer->defaultPermissionClipboardFunc = std::move(defaultPermissionClipboardFunc); |
| } | } |
| | |
| static void GetWebviewControllerHandlerFunc(ani_vm* vm, ani_ref savePtr, | static void GetWebviewControllerHandlerFunc(ani_vm* vm, ani_ref savePtr, |
| |
🤖 AI 代码检视意见(回复本评论可解决检视意见,点击被检视代码行左侧的小头像可收起检视意见)
🟠 资源泄漏:错误路径未调用release函数
位置:
L133-L164| 严重程度: High❓ 问题描述
DefaultPermissionClipboard函数在第148和153行的FindClass和Class_FindStaticMethod失败时,直接return而没有调用之前传入的release函数,这可能导致资源泄漏。与DefaultOnShowFileSelector函数的错误处理不一致(后者在所有错误路径都调用了release)。
💡 修复建议
在所有错误路径中添加release()调用:
static void DefaultPermissionClipboard(ani_vm* vm, void* peer, std::function<void()> release) { HILOGI("Call defaultPermissionClipboard start"); ani_env* env = GetAniEnv(vm); if (!env) { HILOGE("DefaultPermissionClipboard callback env is nullptr"); release(); return; } ani_object obj; if (!GetObjectFromPtr(env, "arkui.component.web.PermissionRequest", &obj, peer)) { release(); return; } ani_class cls; if (env->FindClass("@ohos.web.permissionRequest.PermissionClipboard", &cls) != ANI_OK) { HILOGE("FindClass fail: PermissionClipboard"); release(); // 添加此行 return; } ani_static_method method; if (env->Class_FindStaticMethod(cls, "defaultPermissionClipboard", "C{arkui.component.web.PermissionRequest}:", &method) != ANI_OK) { HILOGE("Class_FindStaticMethod fail, defaultPermissionClipboard"); release(); // 添加此行 return; } if (env->Class_CallStaticMethod_Void(cls, method, obj) != ANI_OK) { HILOGE("Call defaultPermissionClipboard fail"); release(); // 添加此行 return; } HILOGI("Call defaultPermissionClipboard done"); }