issue处理注意事项:
1. 提交正常修复分支的修复PR时,必须关联当前issue,否则无法关闭当前issue;
2. 模板内容需要填写完整, 无论是受影响或者不受影响都需要填写完整内容;
3. 以下为模板中需要填写完整的内容, 请复制到评论区回复;
注: 内容的关键词(影响性分析说明, openEuler评分, 受影响版本排查(受影响/不受影响), 修复是否涉及abi变化(是/否), 原因说明)不能省略,省略后cve-manager将无法正常解析填写内容.
影响性分析说明:
openEuler评分: (评分和向量)
受影响版本排查(受影响/不受影响):
1.master(2.52.6):
2.openEuler-20.03-LTS-SP4:
3.openEuler-22.03-LTS-SP4:
4.openEuler-24.03-LTS-Next(2.50.6):
5.openEuler-24.03-LTS-SP1:
6.openEuler-24.03-LTS-SP3:
7.openEuler-24.03-LTS-SP4(2.50.6):
修复是否涉及abi变化(是/否):
1.master(2.52.6):
2.openEuler-20.03-LTS-SP4:
3.openEuler-22.03-LTS-SP4:
4.openEuler-24.03-LTS-Next(2.50.6):
5.openEuler-24.03-LTS-SP1:
6.openEuler-24.03-LTS-SP3:
7.openEuler-24.03-LTS-SP4(2.50.6):
原因说明:
1.master(2.52.6):
2.openEuler-20.03-LTS-SP4:
3.openEuler-22.03-LTS-SP4:
4.openEuler-24.03-LTS-Next(2.50.6):
5.openEuler-24.03-LTS-SP1:
6.openEuler-24.03-LTS-SP3:
7.openEuler-24.03-LTS-SP4(2.50.6):
原因说明填写请参考下方表格(注意:版本是否受影响和版本的原因说明必须对应,例如master版本分支受影响,那原因说明只能是受影响对应的原因之一!):
分支状态 |
原因说明 | 使用场景 |
|---|---|---|
| 受影响 | 正常修复 | 受影响且需要修复(包含升级版本修复)的漏洞; 受影响且已经修复的漏洞(历史修复PR也需要关联issue); 若因特殊原因无法修复,应修改原因说明为【不修复-特殊原因】,并在安委会备案相关情况。 |
| 受影响 | 漏洞仍在分析中 | 已关注到相关漏洞,正在处理,未明确漏洞影响和修复方案。 |
| 受影响 | 暂不修复-暂无解决方案或补丁 | 当前没有可用的修复或补救措施。【影响性分析】中应包含有关为什么没有修复或补救措施的详细说明、上游相关PR等。 |
| 受影响 | 不修复-超出修复范围 | 没有漏洞的修复计划。当版本停维、软件包宣布生命周期终止或弃用使用。 |
| 受影响 | 不修复-特殊原因导致不再修复 | 如存在其他特殊情况不修复相关漏洞,或评估后无法升级修复,应在openEuler社区安全委员会例会进行说明备案。 【影响性分析】中应包含不发布修复的详细说明、特殊情况还应有安委会会议纪要。 |
| 不受影响 | 不受影响-组件不存在 | 软件不受影响,因为易受攻击的组件不在产品中。 |
| 不受影响 | 不受影响-已有内置的内联控制或缓解措施 | 内置的内联控制或缓解措施可防止攻击者利用漏洞 |
| 不受影响 | 不受影响-漏洞代码不能被攻击者触发 | 易受攻击的组件存在,并且该组件包含易受攻击的代码。但是,易受攻击的代码的使用方式使得攻击者无法进行任何预期的攻击。 |
| 不受影响 | 不受影响-漏洞代码不在执行路径 | 易受影响的代码在执行过程中不可访问,包括产品的非预期状态。产品不使用也不执行的组件。 |
| 不受影响 | 不受影响-漏洞代码不存在 | 产品不受影响,因为漏洞背后的代码在产品中不存在。与component_not_present不同的是,有问题的组件存在,但由于某种原因(例如安全的编译器选项)使漏洞的特定代码不存在于组件中。 |
issue处理具体操作请参考:
https://atomgit.com/openeuler/cve-manager/blob/master/cve-vulner-manager/doc/md/manual.md
pr关联issue具体操作请参考:
https://docs.atomgit.com/docs/help/home/org_project/pullrequests/pr-related-issue


Welcome To openEuler Community
Hey @openeuler-ci-bot , thanks for your contribution to the community.
Bot Usage Manual
I'm the Bot here serving you. You can find the instructions on how to interact with me at Here . That means you can comment below every pull request or issue to trigger Bot Commands. You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
Contact Guide
If you have any questions, please contact the SIG: Desktop ,
and any of the maintainers: @cherry530, @dou33, @dwl301, @lipingEmmaSiguyi, @lostway1, @lw520203, @openbot, @robert-xingwang, @small_leek, @starlet-dx, @t_feng, @technology208, @wangxp006, @weidongkl, @yanan-rock ,
and any of the committers: @t_feng, @wangxp006, @yanan-rock .


| 参考网址 | 关联pr | 状态 | 补丁链接 |
|---|---|---|---|
| https://www.opencve.io/cve/CVE-2026-78376 | https://github.com/WebKit/WebKit/pull/72142 | open | https://github.com/WebKit/WebKit/commit/438db2d18c98507df322eb68d7b7a0c432573342 |
| https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2026-78376 | |||
| https://security-tracker.debian.org/tracker/CVE-2026-78376 | https://github.com/WebKit/WebKit/pull/72142 | open | https://github.com/WebKit/WebKit/commit/438db2d18c98507df322eb68d7b7a0c432573342 |
| http://www.cnnvd.org.cn/web/vulnerability/queryLds.tag?qcvCnnvdid=CVE-2026-78376 | |||
| https://nvd.nist.gov/vuln/detail/CVE-2026-78376 | https://github.com/WebKit/WebKit/pull/72142 | open | https://github.com/WebKit/WebKit/commit/438db2d18c98507df322eb68d7b7a0c432573342 |
| https://ubuntu.com/security/CVE-2026-78376 | None | None | https://discourse.ubuntu.com/c/project |
说明:补丁链接仅供初步排查参考,实际可用性请人工再次确认,补丁下载验证可使用CVE补丁工具。
若补丁不准确,烦请在此issue下评论 '/report-patch 参考网址 补丁链接1,补丁链接2' 反馈正确信息,便于我们不断优化工具,不胜感激。
如 /report-patch https://security-tracker.debian.org/tracker/CVE-2021-3997 https://github.com/systemd/systemd/commit/5b1cf7a9be37e20133c0208005274ce4a5b5c6a1


影响性分析说明:
A flaw was found in WebKitGTK. Processing malicious web content can cause a use-after-free issue due to improper memory handling and result in memory corruption.
openEuler评分: (评分和向量)
8.8
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
受影响版本排查(受影响/不受影响):
1.master(2.52.6):受影响
2.openEuler-20.03-LTS-SP4(2.22.2):受影响
3.openEuler-22.03-LTS-SP4(2.36.3):受影响
4.openEuler-24.03-LTS-Next(2.50.6):受影响
5.openEuler-24.03-LTS-SP1(2.38.2):受影响
6.openEuler-24.03-LTS-SP3(2.38.2):受影响
7.openEuler-24.03-LTS-SP4(2.50.6):受影响
修复是否涉及abi变化(是/否):
1.master(2.52.6):否
2.openEuler-20.03-LTS-SP4(2.22.2):否
3.openEuler-22.03-LTS-SP4(2.36.3):否
4.openEuler-24.03-LTS-Next(2.50.6):否
5.openEuler-24.03-LTS-SP1(2.38.2):否
6.openEuler-24.03-LTS-SP3(2.38.2):否
7.openEuler-24.03-LTS-SP4(2.50.6):否
原因说明:
1.master(2.52.6):正常修复
2.openEuler-20.03-LTS-SP4(2.22.2):暂不修复-暂无解决方案或补丁
3.openEuler-22.03-LTS-SP4(2.36.3):暂不修复-暂无解决方案或补丁
4.openEuler-24.03-LTS-Next(2.50.6):正常修复
5.openEuler-24.03-LTS-SP1(2.38.2):暂不修复-暂无解决方案或补丁
6.openEuler-24.03-LTS-SP3(2.38.2):暂不修复-暂无解决方案或补丁
7.openEuler-24.03-LTS-SP4(2.50.6):正常修复


@yanan-rock 经过 cve-manager 解析, 已分析的内容如下表所示:
| 状态 | 分析项目 | 内容 |
|---|---|---|
| 已分析 | 1.影响性分析说明 | A flaw was found in WebKitGTK. Processing malicious web content can cause a use-after-free issue due to improper memory handling and result in memory corruption. |
| 已分析 | 2.openEulerScore | 8.8 |
| 已分析 | 3.openEulerVector | AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| 已分析 | 4.受影响版本排查 | master:受影响,openEuler-20.03-LTS-SP4:受影响,openEuler-22.03-LTS-SP4:受影响,openEuler-24.03-LTS-Next:受影响,openEuler-24.03-LTS-SP1:受影响,openEuler-24.03-LTS-SP3:受影响,openEuler-24.03-LTS-SP4:受影响 |
| 已分析 | 5.是否涉及abi变化 | master:否,openEuler-20.03-LTS-SP4:否,openEuler-22.03-LTS-SP4:否,openEuler-24.03-LTS-Next:否,openEuler-24.03-LTS-SP1:否,openEuler-24.03-LTS-SP3:否,openEuler-24.03-LTS-SP4:否 |
| 已分析 | 6.原因说明 | master:正常修复,openEuler-20.03-LTS-SP4:暂不修复-暂无解决方案或补丁,openEuler-22.03-LTS-SP4:暂不修复-暂无解决方案或补丁,openEuler-24.03-LTS-Next:正常修复,openEuler-24.03-LTS-SP1:暂不修复-暂无解决方案或补丁,openEuler-24.03-LTS-SP3:暂不修复-暂无解决方案或补丁,openEuler-24.03-LTS-SP4:正常修复 |
请确认分析内容的准确性, 确认无误后, 您可以进行后续步骤, 否则您可以继续分析.


经过cve-manager解析,部分分支PR未合入,如红色字体所示:
原因说明:
1.master:正常修复(PR未合入)
2.openEuler-20.03-LTS-SP4:暂不修复-暂无解决方案或补丁
3.openEuler-22.03-LTS-SP4:暂不修复-暂无解决方案或补丁
4.openEuler-24.03-LTS-Next:正常修复(PR未合入)
5.openEuler-24.03-LTS-SP1:暂不修复-暂无解决方案或补丁
6.openEuler-24.03-LTS-SP3:暂不修复-暂无解决方案或补丁
7.openEuler-24.03-LTS-SP4:正常修复(PR未合入)


经过cve-manager解析,所有PR均已合入


/branches openEuler-20.03-LTS-SP4 /patch_url https://github.com/WebKit/WebKit/commit/e471f9743fad09955c8d60aabadae310a1088591.patch


/branches openEuler-22.03-LTS-SP4 /patch_url https://github.com/WebKit/WebKit/commit/e471f9743fad09955c8d60aabadae310a1088591.patch


/branches openEuler-24.03-LTS-SP1 /patch_url https://github.com/WebKit/WebKit/commit/e471f9743fad09955c8d60aabadae310a1088591.patch


CVE-2026-78376
是否需要修复:是
是否存在适配:是
上游社区补丁:https://github.com/WebKit/WebKit/commit/e471f9743fad09955c8d60aabadae310a1088591.patch
分支修复情况:
1.openEuler-22.03-LTS-SP4(N/A): 已修复
PR:
- openEuler-22.03-LTS-SP4: https://gitcode.com/src-openeuler/webkitgtk/merge_requests/173


补丁适配报告 (CVE-2026-78376)
1. backport-CVE-2026-78376.patch
- 状态: 适配成功 (status=adapted)
- 置信度: medium
适配冲突说明
适配说明
- 20/23 hunks failed direct apply (git apply --check) due to baseline context drift: baseline webkitgtk-2.36.3 uses Vector<JSValueRef,16>+reserveInitialCapacity+uncheckedAppend loop (not the patch's lambda-constructor form) and jsObjectCall body already uses arguments.data() (not the patch's arguments.span().data()). Adaptation: replaced Vector<JSValueRef,16> with MarkedJSValueRefArray (class exists in baseline at API/MarkedJSValueRefArray.h)
- std::span
-> WTF::Span (baseline deliberately vendored std::span as WTF::Span, project convention) - inlined a missing free helper unsafeMakeSpan (template returning WTF::Span, keeping the call site verbatim). 3 directly-applicable hunks preserved verbatim. Adapted patch applies cleanly to a fresh checkout (git apply --check PASS) and git diff --stat confirms 5 files changed, 318 insertions(+), 28 deletions(-).
完整代码 diff(原补丁 → 适配补丁)
Source/JavaScriptCore/API/APICallbackFunction.h
--- 原补丁/Source/JavaScriptCore/API/APICallbackFunction.h
+++ 适配补丁/Source/JavaScriptCore/API/APICallbackFunction.h
@@ -14,13 +14,14 @@
namespace JSC {
-@@ -49,15 +50,16 @@ EncodedJSValue APICallbackFunction::callImpl(JSGlobalObject* globalObject, CallF
+@@ -49,16 +50,16 @@ EncodedJSValue APICallbackFunction::callImpl(JSGlobalObject* globalObject, CallF
JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(callFrame->thisValue().toThis(globalObject, ECMAMode::sloppy())));
int argumentCount = static_cast<int>(callFrame->argumentCount());
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (int i = 0; i < argumentCount; i++)
+- arguments.uncheckedAppend(toRef(globalObject, callFrame->uncheckedArgument(i)));
+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
@@ -30,18 +31,19 @@
JSValueRef result;
{
JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.span().data(), &exception);
+- result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
+ result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, arguments.size(), arguments.data(), &exception);
}
if (exception) {
throwException(globalObject, scope, toJS(globalObject, exception));
-@@ -92,15 +94,16 @@ EncodedJSValue APICallbackFunction::constructImpl(JSGlobalObject* globalObject,
+@@ -93,16 +94,16 @@ EncodedJSValue APICallbackFunction::constructImpl(JSGlobalObject* globalObject,
}
size_t argumentCount = callFrame->argumentCount();
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (size_t i = 0; i < argumentCount; ++i)
+- arguments.uncheckedAppend(toRef(globalObject, callFrame->uncheckedArgument(i)));
+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
@@ -51,7 +53,7 @@
JSObjectRef result;
{
JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = callback(ctx, constructorRef, argumentCount, arguments.span().data(), &exception);
+- result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
+ result = callback(ctx, constructorRef, arguments.size(), arguments.data(), &exception);
}
Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
--- 原补丁/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ 适配补丁/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -6,7 +6,7 @@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
-@@ -35,6 +36,7 @@
+@@ -36,6 +37,7 @@
#include "JSLock.h"
#include "JSObjectRef.h"
#include "JSString.h"
@@ -14,13 +14,14 @@
#include "OpaqueJSString.h"
#include "PropertyNameArray.h"
#include <wtf/Vector.h>
-@@ -479,14 +481,15 @@ EncodedJSValue JSCallbackObject<Parent>::constructImpl(JSGlobalObject* globalObj
+@@ -478,15 +480,15 @@ EncodedJSValue JSCallbackObject<Parent>::constructImpl(JSGlobalObject* globalObj
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
size_t argumentCount = callFrame->argumentCount();
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (size_t i = 0; i < argumentCount; ++i)
+- arguments.uncheckedAppend(toRef(globalObject, callFrame->uncheckedArgument(i)));
+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
@@ -29,28 +30,29 @@
JSObject* result;
{
JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.span().data(), &exception));
+- result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
+ result = toJS(callAsConstructor(execRef, constructorRef, arguments.size(), arguments.data(), &exception));
}
if (exception) {
throwException(globalObject, scope, toJS(globalObject, exception));
-@@ -557,15 +560,16 @@ EncodedJSValue JSCallbackObject<Parent>::callImpl(JSGlobalObject* globalObject,
+@@ -555,15 +557,16 @@ EncodedJSValue JSCallbackObject<Parent>::callImpl(JSGlobalObject* globalObject,
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
size_t argumentCount = callFrame->argumentCount();
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (size_t i = 0; i < argumentCount; ++i)
+- arguments.uncheckedAppend(toRef(globalObject, callFrame->uncheckedArgument(i)));
+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
+ ASSERT(static_cast<size_t>(argumentCount) == arguments.size());
-
++
JSValueRef exception = nullptr;
JSValue result;
{
JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = toJS(globalObject, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.span().data(), &exception));
+- result = toJS(globalObject, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
+ result = toJS(globalObject, callAsFunction(execRef, functionRef, thisObjRef, arguments.size(), arguments.data(), &exception));
}
if (exception) {
Source/JavaScriptCore/API/glib/JSCValue.cpp
--- 原补丁/Source/JavaScriptCore/API/glib/JSCValue.cpp
+++ 适配补丁/Source/JavaScriptCore/API/glib/JSCValue.cpp
@@ -1,32 +1,26 @@
-@@ -31,6 +31,7 @@
+@@ -29,6 +29,7 @@
+ #include "JSCValuePrivate.h"
#include "JSRetainPtr.h"
- #include "JSTypedArray.h"
#include "LiteralParser.h"
+#include "MarkedJSValueRefArray.h"
#include "OpaqueJSString.h"
- #include "TypedArrayType.h"
- #include <array>
-@@ -873,16 +874,16 @@ char** jsc_value_object_enumerate_properties(JSCValue* value)
- return result.leakSpan().data();
+ #include <gobject/gvaluecollector.h>
+ #include <wtf/glib/GRefPtr.h>
+@@ -862,7 +863,12 @@ char** jsc_value_object_enumerate_properties(JSCValue* value)
+ return result;
}
-static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, const Vector<JSValueRef>& arguments, JSValueRef* exception)
-+static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, std::span<const JSValueRef> arguments, JSValueRef* exception)
++template<typename T> static WTF::Span<T> unsafeMakeSpan(T* data, size_t size)
++{
++ return WTF::Span<T>(data, size);
++}
++
++static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCallbackFunction::Type functionType, JSObjectRef thisObject, WTF::Span<const JSValueRef> arguments, JSValueRef* exception)
{
switch (functionType) {
case JSC::JSCCallbackFunction::Type::Constructor:
-- return JSObjectCallAsConstructor(jsContext, function, arguments.size(), arguments.span().data(), exception);
-+ return JSObjectCallAsConstructor(jsContext, function, arguments.size(), arguments.data(), exception);
- case JSC::JSCCallbackFunction::Type::Method:
- ASSERT(thisObject);
- [[fallthrough]];
- case JSC::JSCCallbackFunction::Type::Function:
-- return JSObjectCallAsFunction(jsContext, function, thisObject, arguments.size(), arguments.span().data(), exception);
-+ return JSObjectCallAsFunction(jsContext, function, thisObject, arguments.size(), arguments.data(), exception);
- }
- RELEASE_ASSERT_NOT_REACHED();
- }
-@@ -895,7 +896,8 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
+@@ -884,7 +890,8 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
JSC::JSLockHolder locker(globalObject);
JSValueRef exception = nullptr;
@@ -36,7 +30,7 @@
GType parameterType = firstParameterType;
while (parameterType != G_TYPE_NONE) {
GValue parameter;
-@@ -914,11 +916,22 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
+@@ -901,11 +908,22 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return jscContextGetOrCreateValue(priv->context.get(), jsValue);
@@ -61,27 +55,27 @@
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return adoptGRef(jsc_value_new_undefined(priv->context.get()));
-@@ -1017,7 +1030,7 @@ JSCValue* jsc_value_object_invoke_methodv(JSCValue* value, const char* name, uns
- return jscValueGetJSValue(parametersSpan[i]);
- });
+@@ -1006,7 +1024,7 @@ JSCValue* jsc_value_object_invoke_methodv(JSCValue* value, const char* name, uns
+ arguments.uncheckedAppend(jscValueGetJSValue(parameters[i]));
+ }
- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Method, object, arguments, &exception);
+ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Method, object, arguments.span(), &exception);
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return jsc_value_new_undefined(priv->context.get());
-@@ -1368,7 +1381,7 @@ JSCValue* jsc_value_function_callv(JSCValue* value, unsigned parametersCount, JS
- return jscValueGetJSValue(parametersSpan[i]);
- });
+@@ -1368,7 +1386,7 @@ JSCValue* jsc_value_function_callv(JSCValue* value, unsigned parametersCount, JS
+ arguments.uncheckedAppend(jscValueGetJSValue(parameters[i]));
+ }
- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Function, nullptr, arguments, &exception);
+ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Function, nullptr, arguments.span(), &exception);
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return jsc_value_new_undefined(priv->context.get());
-@@ -1452,7 +1465,7 @@ JSCValue* jsc_value_constructor_callv(JSCValue* value, unsigned parametersCount,
- return jscValueGetJSValue(parametersSpan[i]);
- });
+@@ -1454,7 +1472,7 @@ JSCValue* jsc_value_constructor_callv(JSCValue* value, unsigned parametersCount,
+ arguments.uncheckedAppend(jscValueGetJSValue(parameters[i]));
+ }
- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Constructor, nullptr, arguments, &exception);
+ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Constructor, nullptr, arguments.span(), &exception);
Source/JavaScriptCore/API/tests/testapi.cpp
--- 原补丁/Source/JavaScriptCore/API/tests/testapi.cpp
+++ 适配补丁/Source/JavaScriptCore/API/tests/testapi.cpp
@@ -1,19 +1,19 @@
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2017-2024 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2026 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
-@@ -38,6 +39,7 @@
+@@ -36,6 +37,7 @@
+ #include <wtf/Noncopyable.h>
#include <wtf/NumberOfCores.h>
#include <wtf/Vector.h>
- #include <wtf/text/MakeString.h>
+#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringCommon.h>
#if PLATFORM(COCOA)
-@@ -159,6 +161,10 @@ class TestAPI {
+@@ -154,6 +156,10 @@ public:
void promiseDrainDoesNotEatExceptions();
void topCallFrameAccess();
void markedJSValueArrayAndGC();
@@ -24,7 +24,7 @@
void classDefinitionWithJSSubclass();
void proxyReturnedWithJSSubclassing();
void testJSObjectSetOnGlobalObjectSubclassDefinition();
-@@ -676,6 +682,122 @@ void TestAPI::markedJSValueArrayAndGC()
+@@ -678,6 +684,122 @@ void TestAPI::markedJSValueArrayAndGC()
testMarkedJSValueArray(1000);
}
@@ -147,7 +147,7 @@
void TestAPI::classDefinitionWithJSSubclass()
{
const static JSClassDefinition definition = kJSClassDefinitionEmpty;
-@@ -1241,6 +1363,10 @@ int testCAPIViaCpp(const char* filter)
+@@ -781,6 +903,10 @@ int testCAPIViaCpp(const char* filter)
RUN(promiseDrainDoesNotEatExceptions());
RUN(promiseEarlyHandledRejections());
RUN(markedJSValueArrayAndGC());
Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
--- 原补丁/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
+++ 适配补丁/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
@@ -6,7 +6,7 @@
#include <wtf/Threading.h>
#include <wtf/Vector.h>
#include <wtf/glib/GRefPtr.h>
-@@ -4819,9 +4820,147 @@ static void testJSCJSON()
+@@ -4167,9 +4168,147 @@ static void testJSCJSON()
}
}
@@ -154,7 +154,7 @@
// options should always be the first test, since changing options
// is not allowed after the first VM instance is created.
-@@ -4846,6 +4985,9 @@ int main(int argc, char** argv)
+@@ -4192,6 +4331,9 @@ int main(int argc, char** argv)
g_test_add_func("/jsc/autocleanups", testsJSCAutocleanups);
#endif
g_test_add_func("/jsc/json", testJSCJSON);


CVE-2026-78376
是否需要修复:是
是否存在适配:是
上游社区补丁:https://github.com/WebKit/WebKit/commit/e471f9743fad09955c8d60aabadae310a1088591.patch
分支修复情况:
1.openEuler-24.03-LTS-SP1(N/A): 已修复
PR:
- openEuler-24.03-LTS-SP1: https://gitcode.com/src-openeuler/webkitgtk/merge_requests/174


补丁适配报告 (CVE-2026-78376)
1. backport-CVE-2026-78376.patch
- 状态: 适配成功 (status=adapted)
- 置信度: high
适配冲突说明
适配说明
- 11 of 23 hunks required context adaptation. Baseline uses reserveInitialCapacity+uncheckedAppend loop instead of lambda constructor for Vector<JSValueRef,16>
- baseline already has arguments.data() and FALLTHROUGH
- instead of arguments.span().data() and [[fallthrough]]. Two API substitutions: std::span→WTF::Span (baseline renames std::span to WTF::Span) and unsafeMakeSpan(ptr,size)→WTF::Span
(ptr,size) (unsafeMakeSpan does not exist in 2.38.2). 12 hunks applied directly without modification. Patch verified: git apply --check passes on clean baseline, git diff --stat confirms 5 files changed, 313 insertions, 28 deletions.
完整代码 diff(原补丁 → 适配补丁)
Source/JavaScriptCore/API/APICallbackFunction.h
--- 原补丁/Source/JavaScriptCore/API/APICallbackFunction.h
+++ 适配补丁/Source/JavaScriptCore/API/APICallbackFunction.h
@@ -14,13 +14,14 @@
namespace JSC {
-@@ -49,15 +50,16 @@ EncodedJSValue APICallbackFunction::callImpl(JSGlobalObject* globalObject, CallF
+@@ -49,16 +50,16 @@ EncodedJSValue APICallbackFunction::callImpl(JSGlobalObject* globalObject, CallF
JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(callFrame->thisValue().toThis(globalObject, ECMAMode::sloppy())));
int argumentCount = static_cast<int>(callFrame->argumentCount());
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (int i = 0; i < argumentCount; i++)
+- arguments.uncheckedAppend(toRef(globalObject, callFrame->uncheckedArgument(i)));
+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
@@ -30,18 +31,19 @@
JSValueRef result;
{
JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.span().data(), &exception);
+- result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
+ result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, arguments.size(), arguments.data(), &exception);
}
if (exception) {
throwException(globalObject, scope, toJS(globalObject, exception));
-@@ -92,15 +94,16 @@ EncodedJSValue APICallbackFunction::constructImpl(JSGlobalObject* globalObject,
+@@ -93,16 +94,16 @@ EncodedJSValue APICallbackFunction::constructImpl(JSGlobalObject* globalObject,
}
size_t argumentCount = callFrame->argumentCount();
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (size_t i = 0; i < argumentCount; ++i)
+- arguments.uncheckedAppend(toRef(globalObject, callFrame->uncheckedArgument(i)));
+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
@@ -51,7 +53,7 @@
JSObjectRef result;
{
JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = callback(ctx, constructorRef, argumentCount, arguments.span().data(), &exception);
+- result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
+ result = callback(ctx, constructorRef, arguments.size(), arguments.data(), &exception);
}
Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
--- 原补丁/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ 适配补丁/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -6,7 +6,7 @@
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
-@@ -35,6 +36,7 @@
+@@ -36,6 +37,7 @@
#include "JSLock.h"
#include "JSObjectRef.h"
#include "JSString.h"
@@ -14,13 +14,14 @@
#include "OpaqueJSString.h"
#include "PropertyNameArray.h"
#include <wtf/Vector.h>
-@@ -479,14 +481,15 @@ EncodedJSValue JSCallbackObject<Parent>::constructImpl(JSGlobalObject* globalObj
+@@ -478,15 +480,15 @@ EncodedJSValue JSCallbackObject<Parent>::constructImpl(JSGlobalObject* globalObj
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
size_t argumentCount = callFrame->argumentCount();
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (size_t i = 0; i < argumentCount; ++i)
+- arguments.uncheckedAppend(toRef(globalObject, callFrame->uncheckedArgument(i)));
+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
@@ -29,28 +30,29 @@
JSObject* result;
{
JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.span().data(), &exception));
+- result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
+ result = toJS(callAsConstructor(execRef, constructorRef, arguments.size(), arguments.data(), &exception));
}
if (exception) {
throwException(globalObject, scope, toJS(globalObject, exception));
-@@ -557,15 +560,16 @@ EncodedJSValue JSCallbackObject<Parent>::callImpl(JSGlobalObject* globalObject,
+@@ -555,15 +557,16 @@ EncodedJSValue JSCallbackObject<Parent>::callImpl(JSGlobalObject* globalObject,
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
size_t argumentCount = callFrame->argumentCount();
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (size_t i = 0; i < argumentCount; ++i)
+- arguments.uncheckedAppend(toRef(globalObject, callFrame->uncheckedArgument(i)));
+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
+ ASSERT(static_cast<size_t>(argumentCount) == arguments.size());
-
++
JSValueRef exception = nullptr;
JSValue result;
{
JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = toJS(globalObject, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.span().data(), &exception));
+- result = toJS(globalObject, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
+ result = toJS(globalObject, callAsFunction(execRef, functionRef, thisObjRef, arguments.size(), arguments.data(), &exception));
}
if (exception) {
Source/JavaScriptCore/API/glib/JSCValue.cpp
--- 原补丁/Source/JavaScriptCore/API/glib/JSCValue.cpp
+++ 适配补丁/Source/JavaScriptCore/API/glib/JSCValue.cpp
@@ -5,28 +5,17 @@
+#include "MarkedJSValueRefArray.h"
#include "OpaqueJSString.h"
#include "TypedArrayType.h"
- #include <array>
-@@ -873,16 +874,16 @@ char** jsc_value_object_enumerate_properties(JSCValue* value)
- return result.leakSpan().data();
+ #include <gobject/gvaluecollector.h>
+@@ -865,7 +866,7 @@ char** jsc_value_object_enumerate_properties(JSCValue* value)
+ return result;
}
-static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, const Vector<JSValueRef>& arguments, JSValueRef* exception)
-+static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, std::span<const JSValueRef> arguments, JSValueRef* exception)
++static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, WTF::Span<const JSValueRef> arguments, JSValueRef* exception)
{
switch (functionType) {
case JSC::JSCCallbackFunction::Type::Constructor:
-- return JSObjectCallAsConstructor(jsContext, function, arguments.size(), arguments.span().data(), exception);
-+ return JSObjectCallAsConstructor(jsContext, function, arguments.size(), arguments.data(), exception);
- case JSC::JSCCallbackFunction::Type::Method:
- ASSERT(thisObject);
- [[fallthrough]];
- case JSC::JSCCallbackFunction::Type::Function:
-- return JSObjectCallAsFunction(jsContext, function, thisObject, arguments.size(), arguments.span().data(), exception);
-+ return JSObjectCallAsFunction(jsContext, function, thisObject, arguments.size(), arguments.data(), exception);
- }
- RELEASE_ASSERT_NOT_REACHED();
- }
-@@ -895,7 +896,8 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
+@@ -887,7 +888,8 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
JSC::JSLockHolder locker(globalObject);
JSValueRef exception = nullptr;
@@ -36,7 +25,7 @@
GType parameterType = firstParameterType;
while (parameterType != G_TYPE_NONE) {
GValue parameter;
-@@ -914,11 +916,22 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
+@@ -904,11 +906,23 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return jscContextGetOrCreateValue(priv->context.get(), jsValue);
@@ -44,6 +33,8 @@
+ parameters.append(toJS(globalObject, jsValue));
parameterType = va_arg(args, GType);
}
+
+- auto result = jsObjectCall(jsContext, function, functionType, thisObject, arguments, &exception);
+ if (parameters.hasOverflowed()) {
+ exception = toRef(JSC::createOutOfMemoryError(globalObject));
+ jscContextHandleExceptionIfNeeded(priv->context.get(), exception);
@@ -55,33 +46,32 @@
+ JSC::MarkedJSValueRefArray arguments(jsContext, static_cast<unsigned>(parameters.size()));
+ for (unsigned i = 0; i < arguments.size(); ++i)
+ arguments[i] = toRef(globalObject, parameters.at(i));
-
-- auto result = jsObjectCall(jsContext, function, functionType, thisObject, arguments, &exception);
-+ auto result = jsObjectCall(jsContext, function, functionType, thisObject, unsafeMakeSpan(arguments.data(), arguments.size()), &exception);
++
++ auto result = jsObjectCall(jsContext, function, functionType, thisObject, WTF::Span<const JSValueRef>(arguments.data(), arguments.size()), &exception);
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return adoptGRef(jsc_value_new_undefined(priv->context.get()));
-@@ -1017,7 +1030,7 @@ JSCValue* jsc_value_object_invoke_methodv(JSCValue* value, const char* name, uns
- return jscValueGetJSValue(parametersSpan[i]);
- });
+@@ -1009,7 +1023,7 @@ JSCValue* jsc_value_object_invoke_methodv(JSCValue* value, const char* name, uns
+ arguments.uncheckedAppend(jscValueGetJSValue(parameters[i]));
+ }
- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Method, object, arguments, &exception);
+ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Method, object, arguments.span(), &exception);
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return jsc_value_new_undefined(priv->context.get());
-@@ -1368,7 +1381,7 @@ JSCValue* jsc_value_function_callv(JSCValue* value, unsigned parametersCount, JS
- return jscValueGetJSValue(parametersSpan[i]);
- });
+@@ -1371,7 +1385,7 @@ JSCValue* jsc_value_function_callv(JSCValue* value, unsigned parametersCount, JS
+ arguments.uncheckedAppend(jscValueGetJSValue(parameters[i]));
+ }
- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Function, nullptr, arguments, &exception);
+ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Function, nullptr, arguments.span(), &exception);
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return jsc_value_new_undefined(priv->context.get());
-@@ -1452,7 +1465,7 @@ JSCValue* jsc_value_constructor_callv(JSCValue* value, unsigned parametersCount,
- return jscValueGetJSValue(parametersSpan[i]);
- });
+@@ -1457,7 +1471,7 @@ JSCValue* jsc_value_constructor_callv(JSCValue* value, unsigned parametersCount,
+ arguments.uncheckedAppend(jscValueGetJSValue(parameters[i]));
+ }
- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Constructor, nullptr, arguments, &exception);
+ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Constructor, nullptr, arguments.span(), &exception);
Source/JavaScriptCore/API/tests/testapi.cpp
--- 原补丁/Source/JavaScriptCore/API/tests/testapi.cpp
+++ 适配补丁/Source/JavaScriptCore/API/tests/testapi.cpp
@@ -1,19 +1,11 @@
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2017-2024 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2026 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
-@@ -38,6 +39,7 @@
- #include <wtf/NumberOfCores.h>
- #include <wtf/Vector.h>
- #include <wtf/text/MakeString.h>
-+#include <wtf/text/StringBuilder.h>
- #include <wtf/text/StringCommon.h>
-
- #if PLATFORM(COCOA)
-@@ -159,6 +161,10 @@ class TestAPI {
+@@ -154,6 +155,10 @@ public:
void promiseDrainDoesNotEatExceptions();
void topCallFrameAccess();
void markedJSValueArrayAndGC();
@@ -24,7 +16,7 @@
void classDefinitionWithJSSubclass();
void proxyReturnedWithJSSubclassing();
void testJSObjectSetOnGlobalObjectSubclassDefinition();
-@@ -676,6 +682,122 @@ void TestAPI::markedJSValueArrayAndGC()
+@@ -680,6 +685,122 @@ void TestAPI::markedJSValueArrayAndGC()
testMarkedJSValueArray(1000);
}
@@ -147,7 +139,7 @@
void TestAPI::classDefinitionWithJSSubclass()
{
const static JSClassDefinition definition = kJSClassDefinitionEmpty;
-@@ -1241,6 +1363,10 @@ int testCAPIViaCpp(const char* filter)
+@@ -783,6 +904,10 @@ int testCAPIViaCpp(const char* filter)
RUN(promiseDrainDoesNotEatExceptions());
RUN(promiseEarlyHandledRejections());
RUN(markedJSValueArrayAndGC());
Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
--- 原补丁/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
+++ 适配补丁/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
@@ -6,7 +6,7 @@
#include <wtf/Threading.h>
#include <wtf/Vector.h>
#include <wtf/glib/GRefPtr.h>
-@@ -4819,9 +4820,147 @@ static void testJSCJSON()
+@@ -4665,9 +4666,147 @@ static void testJSCJSON()
}
}
@@ -154,7 +154,7 @@
// options should always be the first test, since changing options
// is not allowed after the first VM instance is created.
-@@ -4846,6 +4985,9 @@ int main(int argc, char** argv)
+@@ -4692,6 +4831,9 @@ int main(int argc, char** argv)
g_test_add_func("/jsc/autocleanups", testsJSCAutocleanups);
#endif
g_test_add_func("/jsc/json", testJSCJSON);


CVE-2026-78376
是否需要修复:是
是否存在适配:是
上游社区补丁:https://github.com/WebKit/WebKit/commit/e471f9743fad09955c8d60aabadae310a1088591.patch
分支修复情况:
1.openEuler-20.03-LTS-SP4(N/A): 已修复
PR:
- openEuler-20.03-LTS-SP4: https://gitcode.com/src-openeuler/webkitgtk/merge_requests/175


补丁适配报告 (CVE-2026-78376)
1. backport-CVE-2026-78376.patch
- 状态: 适配成功 (status=adapted)
- 置信度: high
适配冲突说明
适配说明
- Cross-version adaptation (webkitgtk-2.22.2 from 2018 vs WebKit 2026 patch). 3 core files modified, 2 test files skipped. APICallbackFunction.h: replaced Vector<JSValueRef,16>+reserveInitialCapacity+uncheckedAppend with MarkedJSValueRefArray(toGlobalRef(exec),...)+fill loop+ASSERT in call() and construct()
- changed argumentCount to arguments.size() in callback calls
- adapted from new JSC API (JSGlobalObject*/callImpl/ECMAMode::sloppy()) to old API (ExecState*/call/NotStrictMode). JSCallbackObjectFunctions.h: same Vector->MarkedJSValueRefArray replacement in construct() and call() template functions
- added include and copyright. JSCValue.cpp: changed jsObjectCall signature from const Vector
& to const JSValueRef*,size_t (std::span unavailable in 2.22.2) - replaced Vector
arguments with MarkedArgumentBuffer+MarkedJSValueRefArray in jscValueCallFunction - adapted globalObject->toJS(jsContext), unsafeMakeSpan->arguments.data(),arguments.size()
- updated 3 call sites (invoke_methodv, function_callv, constructor_callv). Test files (testapi.cpp, TestJSC.cpp) skipped: use APIs unavailable in 2.22.2 (ASCIILiteral, sanitizeStackForVM, vm.heap.collectNow, etc.). Non-critical for CVE fix.
完整代码 diff(原补丁 → 适配补丁)
Source/JavaScriptCore/API/APICallbackFunction.h
--- 原补丁/Source/JavaScriptCore/API/APICallbackFunction.h
+++ 适配补丁/Source/JavaScriptCore/API/APICallbackFunction.h
@@ -1,6 +1,6 @@
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2013-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2026 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
@@ -14,45 +14,47 @@
namespace JSC {
-@@ -49,15 +50,16 @@ EncodedJSValue APICallbackFunction::callImpl(JSGlobalObject* globalObject, CallF
- JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(callFrame->thisValue().toThis(globalObject, ECMAMode::sloppy())));
+@@ -51,16 +52,16 @@ EncodedJSValue JSC_HOST_CALL APICallbackFunction::call(ExecState* exec)
+ JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->thisValue().toThis(exec, NotStrictMode)));
- int argumentCount = static_cast<int>(callFrame->argumentCount());
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
-+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ int argumentCount = static_cast<int>(exec->argumentCount());
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (int i = 0; i < argumentCount; i++)
+- arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
++ MarkedJSValueRefArray arguments(toGlobalRef(exec), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
-+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
++ arguments[i] = toRef(exec, exec->uncheckedArgument(i));
+ ASSERT(static_cast<size_t>(argumentCount) == arguments.size());
- JSValueRef exception = nullptr;
+ JSValueRef exception = 0;
JSValueRef result;
{
- JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.span().data(), &exception);
+ JSLock::DropAllLocks dropAllLocks(exec);
+- result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
+ result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, arguments.size(), arguments.data(), &exception);
}
- if (exception) {
- throwException(globalObject, scope, toJS(globalObject, exception));
-@@ -92,15 +94,16 @@ EncodedJSValue APICallbackFunction::constructImpl(JSGlobalObject* globalObject,
- }
-
- size_t argumentCount = callFrame->argumentCount();
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
-+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ if (exception)
+ throwException(exec, scope, toJS(exec, exception));
+@@ -84,16 +85,16 @@ EncodedJSValue JSC_HOST_CALL APICallbackFunction::construct(ExecState* exec)
+ JSObjectCallAsConstructorCallback callback = jsCast<T*>(constructor)->constructCallback();
+ if (callback) {
+ size_t argumentCount = exec->argumentCount();
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (size_t i = 0; i < argumentCount; ++i)
+- arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
++ MarkedJSValueRefArray arguments(toGlobalRef(exec), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
-+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
++ arguments[i] = toRef(exec, exec->uncheckedArgument(i));
+ ASSERT(static_cast<size_t>(argumentCount) == arguments.size());
- JSValueRef exception = nullptr;
+ JSValueRef exception = 0;
JSObjectRef result;
{
- JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = callback(ctx, constructorRef, argumentCount, arguments.span().data(), &exception);
+ JSLock::DropAllLocks dropAllLocks(exec);
+- result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
+ result = callback(ctx, constructorRef, arguments.size(), arguments.data(), &exception);
}
-
if (exception) {
+ throwException(exec, scope, toJS(exec, exception));
Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
--- 原补丁/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ 适配补丁/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -1,57 +1,58 @@
@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2006-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2008, 2016 Apple Inc. All rights reserved.
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2026 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
-@@ -35,6 +36,7 @@
+@@ -34,6 +35,7 @@
#include "JSLock.h"
#include "JSObjectRef.h"
#include "JSString.h"
+#include "MarkedJSValueRefArray.h"
+ #include "JSStringRef.h"
#include "OpaqueJSString.h"
#include "PropertyNameArray.h"
- #include <wtf/Vector.h>
-@@ -479,14 +481,15 @@ EncodedJSValue JSCallbackObject<Parent>::constructImpl(JSGlobalObject* globalObj
+@@ -443,15 +445,15 @@ EncodedJSValue JSCallbackObject<Parent>::construct(ExecState* exec)
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
- size_t argumentCount = callFrame->argumentCount();
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
-+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ size_t argumentCount = exec->argumentCount();
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (size_t i = 0; i < argumentCount; ++i)
+- arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
++ MarkedJSValueRefArray arguments(toGlobalRef(exec), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
-+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
++ arguments[i] = toRef(exec, exec->uncheckedArgument(i));
+ ASSERT(static_cast<size_t>(argumentCount) == arguments.size());
- JSValueRef exception = nullptr;
+ JSValueRef exception = 0;
JSObject* result;
{
- JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.span().data(), &exception));
+ JSLock::DropAllLocks dropAllLocks(exec);
+- result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
+ result = toJS(callAsConstructor(execRef, constructorRef, arguments.size(), arguments.data(), &exception));
}
- if (exception) {
- throwException(globalObject, scope, toJS(globalObject, exception));
-@@ -557,15 +560,16 @@ EncodedJSValue JSCallbackObject<Parent>::callImpl(JSGlobalObject* globalObject,
+ if (exception)
+ throwException(exec, scope, toJS(exec, exception));
+@@ -516,15 +518,15 @@ EncodedJSValue JSCallbackObject<Parent>::call(ExecState* exec)
for (JSClassRef jsClass = jsCast<JSCallbackObject<Parent>*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
- size_t argumentCount = callFrame->argumentCount();
-- Vector<JSValueRef, 16> arguments(argumentCount, [&](size_t i) {
-- return toRef(globalObject, callFrame->uncheckedArgument(i));
-- });
-+ MarkedJSValueRefArray arguments(toGlobalRef(globalObject), static_cast<unsigned>(argumentCount));
+ size_t argumentCount = exec->argumentCount();
+- Vector<JSValueRef, 16> arguments;
+- arguments.reserveInitialCapacity(argumentCount);
+- for (size_t i = 0; i < argumentCount; ++i)
+- arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i)));
++ MarkedJSValueRefArray arguments(toGlobalRef(exec), static_cast<unsigned>(argumentCount));
+ for (unsigned i = 0; i < arguments.size(); ++i)
-+ arguments[i] = toRef(globalObject, callFrame->uncheckedArgument(i));
++ arguments[i] = toRef(exec, exec->uncheckedArgument(i));
+ ASSERT(static_cast<size_t>(argumentCount) == arguments.size());
-
- JSValueRef exception = nullptr;
+ JSValueRef exception = 0;
JSValue result;
{
- JSLock::DropAllLocks dropAllLocks(globalObject);
-- result = toJS(globalObject, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.span().data(), &exception));
-+ result = toJS(globalObject, callAsFunction(execRef, functionRef, thisObjRef, arguments.size(), arguments.data(), &exception));
+ JSLock::DropAllLocks dropAllLocks(exec);
+- result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
++ result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, arguments.size(), arguments.data(), &exception));
}
- if (exception) {
- throwException(globalObject, scope, toJS(globalObject, exception));
+ if (exception)
+ throwException(exec, scope, toJS(exec, exception));
Source/JavaScriptCore/API/glib/JSCValue.cpp
--- 原补丁/Source/JavaScriptCore/API/glib/JSCValue.cpp
+++ 适配补丁/Source/JavaScriptCore/API/glib/JSCValue.cpp
@@ -1,33 +1,34 @@
-@@ -31,6 +31,7 @@
+@@ -27,6 +27,7 @@
+ #include "JSCInlines.h"
+ #include "JSCValuePrivate.h"
#include "JSRetainPtr.h"
- #include "JSTypedArray.h"
- #include "LiteralParser.h"
+#include "MarkedJSValueRefArray.h"
#include "OpaqueJSString.h"
- #include "TypedArrayType.h"
- #include <array>
-@@ -873,16 +874,16 @@ char** jsc_value_object_enumerate_properties(JSCValue* value)
- return result.leakSpan().data();
+ #include <gobject/gvaluecollector.h>
+ #include <wtf/glib/GRefPtr.h>
+@@ -856,17 +857,17 @@ char** jsc_value_object_enumerate_properties(JSCValue* value)
+ return result;
}
-static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, const Vector<JSValueRef>& arguments, JSValueRef* exception)
-+static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, std::span<const JSValueRef> arguments, JSValueRef* exception)
++static JSValueRef jsObjectCall(JSGlobalContextRef jsContext, JSObjectRef function, JSC::JSCCallbackFunction::Type functionType, JSObjectRef thisObject, const JSValueRef* arguments, size_t argumentCount, JSValueRef* exception)
{
switch (functionType) {
case JSC::JSCCallbackFunction::Type::Constructor:
-- return JSObjectCallAsConstructor(jsContext, function, arguments.size(), arguments.span().data(), exception);
-+ return JSObjectCallAsConstructor(jsContext, function, arguments.size(), arguments.data(), exception);
+- return JSObjectCallAsConstructor(jsContext, function, arguments.size(), arguments.data(), exception);
++ return JSObjectCallAsConstructor(jsContext, function, argumentCount, arguments, exception);
+ break;
case JSC::JSCCallbackFunction::Type::Method:
ASSERT(thisObject);
- [[fallthrough]];
+ FALLTHROUGH;
case JSC::JSCCallbackFunction::Type::Function:
-- return JSObjectCallAsFunction(jsContext, function, thisObject, arguments.size(), arguments.span().data(), exception);
-+ return JSObjectCallAsFunction(jsContext, function, thisObject, arguments.size(), arguments.data(), exception);
+- return JSObjectCallAsFunction(jsContext, function, thisObject, arguments.size(), arguments.data(), exception);
++ return JSObjectCallAsFunction(jsContext, function, thisObject, argumentCount, arguments, exception);
+ break;
}
RELEASE_ASSERT_NOT_REACHED();
- }
-@@ -895,7 +896,8 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
- JSC::JSLockHolder locker(globalObject);
+@@ -878,7 +879,8 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
+ auto* jsContext = jscContextGetJSContext(priv->context.get());
JSValueRef exception = nullptr;
- Vector<JSValueRef> arguments;
@@ -36,16 +37,16 @@
GType parameterType = firstParameterType;
while (parameterType != G_TYPE_NONE) {
GValue parameter;
-@@ -914,11 +916,22 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
+@@ -895,11 +897,22 @@ static GRefPtr<JSCValue> jscValueCallFunction(JSCValue* value, JSObjectRef funct
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return jscContextGetOrCreateValue(priv->context.get(), jsValue);
- arguments.append(jsValue);
-+ parameters.append(toJS(globalObject, jsValue));
++ parameters.append(toJS(toJS(jsContext), jsValue));
parameterType = va_arg(args, GType);
}
+ if (parameters.hasOverflowed()) {
-+ exception = toRef(JSC::createOutOfMemoryError(globalObject));
++ exception = toRef(JSC::createOutOfMemoryError(toJS(jsContext)));
+ jscContextHandleExceptionIfNeeded(priv->context.get(), exception);
+ return adoptGRef(jsc_value_new_undefined(priv->context.get()));
+ }
@@ -54,37 +55,37 @@
+ // need marking as well.
+ JSC::MarkedJSValueRefArray arguments(jsContext, static_cast<unsigned>(parameters.size()));
+ for (unsigned i = 0; i < arguments.size(); ++i)
-+ arguments[i] = toRef(globalObject, parameters.at(i));
++ arguments[i] = toRef(toJS(jsContext), parameters.at(i));
- auto result = jsObjectCall(jsContext, function, functionType, thisObject, arguments, &exception);
-+ auto result = jsObjectCall(jsContext, function, functionType, thisObject, unsafeMakeSpan(arguments.data(), arguments.size()), &exception);
++ auto result = jsObjectCall(jsContext, function, functionType, thisObject, arguments.data(), arguments.size(), &exception);
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return adoptGRef(jsc_value_new_undefined(priv->context.get()));
-@@ -1017,7 +1030,7 @@ JSCValue* jsc_value_object_invoke_methodv(JSCValue* value, const char* name, uns
- return jscValueGetJSValue(parametersSpan[i]);
- });
+@@ -1000,7 +1013,7 @@ JSCValue* jsc_value_object_invoke_methodv(JSCValue* value, const char* name, uns
+ arguments.uncheckedAppend(jscValueGetJSValue(parameters[i]));
+ }
- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Method, object, arguments, &exception);
-+ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Method, object, arguments.span(), &exception);
++ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Method, object, arguments.data(), arguments.size(), &exception);
+ if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
+ jsc_value_new_undefined(priv->context.get());
+
+@@ -1295,7 +1308,7 @@ JSCValue* jsc_value_function_callv(JSCValue* value, unsigned parametersCount, JS
+ arguments.uncheckedAppend(jscValueGetJSValue(parameters[i]));
+ }
+
+- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Function, nullptr, arguments, &exception);
++ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Function, nullptr, arguments.data(), arguments.size(), &exception);
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return jsc_value_new_undefined(priv->context.get());
-@@ -1368,7 +1381,7 @@ JSCValue* jsc_value_function_callv(JSCValue* value, unsigned parametersCount, JS
- return jscValueGetJSValue(parametersSpan[i]);
- });
+@@ -1381,7 +1394,7 @@ JSCValue* jsc_value_constructor_callv(JSCValue* value, unsigned parametersCount,
+ arguments.uncheckedAppend(jscValueGetJSValue(parameters[i]));
+ }
-- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Function, nullptr, arguments, &exception);
-+ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Function, nullptr, arguments.span(), &exception);
+- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Constructor, nullptr, arguments, &exception);
++ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Constructor, nullptr, arguments.data(), arguments.size(), &exception);
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
return jsc_value_new_undefined(priv->context.get());
-@@ -1452,7 +1465,7 @@ JSCValue* jsc_value_constructor_callv(JSCValue* value, unsigned parametersCount,
- return jscValueGetJSValue(parametersSpan[i]);
- });
-
-- auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Constructor, nullptr, arguments, &exception);
-+ auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Constructor, nullptr, arguments.span(), &exception);
- if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
- return jsc_value_new_undefined(priv->context.get());
-
Source/JavaScriptCore/API/tests/testapi.cpp
--- 原补丁/Source/JavaScriptCore/API/tests/testapi.cpp
+++ 适配补丁/Source/JavaScriptCore/API/tests/testapi.cpp
@@ -1,160 +0,0 @@
-@@ -1,5 +1,6 @@
- /*
- * Copyright (C) 2017-2024 Apple Inc. All rights reserved.
-+ * Copyright (C) 2026 Igalia S.L.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
-@@ -38,6 +39,7 @@
- #include <wtf/NumberOfCores.h>
- #include <wtf/Vector.h>
- #include <wtf/text/MakeString.h>
-+#include <wtf/text/StringBuilder.h>
- #include <wtf/text/StringCommon.h>
-
- #if PLATFORM(COCOA)
-@@ -159,6 +161,10 @@ class TestAPI {
- void promiseDrainDoesNotEatExceptions();
- void topCallFrameAccess();
- void markedJSValueArrayAndGC();
-+ void functionCallbackArgumentsAndGC();
-+ void constructorCallbackArgumentsAndGC();
-+ void classCallAsFunctionArgumentsAndGC();
-+ void classCallAsConstructorArgumentsAndGC();
- void classDefinitionWithJSSubclass();
- void proxyReturnedWithJSSubclassing();
- void testJSObjectSetOnGlobalObjectSubclassDefinition();
-@@ -676,6 +682,122 @@ void TestAPI::markedJSValueArrayAndGC()
- testMarkedJSValueArray(1000);
- }
-
-+// Above MarkedJSValueRefArray's inline capacity, where a stack buffer would be found by conservative
-+// scanning whether or not the collector knows about it.
-+static constexpr unsigned manyArgumentCount = 32;
-+static constexpr double recycledArgumentValue = 987654321;
-+
-+static bool argumentsSurviveCollectionInCallback(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[])
-+{
-+ if (argumentCount != manyArgumentCount)
-+ return false;
-+
-+ {
-+ auto* globalObject = toJS(ctx);
-+ JSC::VM& vm = globalObject->vm();
-+ JSC::JSLockHolder locker(vm);
-+ JSC::sanitizeStackForVM(vm);
-+ vm.heap.collectNow(JSC::Sync, JSC::CollectionScope::Full);
-+ }
-+
-+ // Where a JSValue does not fit in a pointer a JSValueRef for a number is a JSAPIValueWrapper cell,
-+ // so these allocations recycle the wrappers that a dangling argument still points at.
-+ for (unsigned index = 0; index < 8192; ++index)
-+ JSValueMakeNumber(ctx, recycledArgumentValue);
-+
-+ for (unsigned index = 0; index < argumentCount; ++index) {
-+ if (!JSValueIsNumber(ctx, arguments[index]))
-+ return false;
-+ if (JSValueToNumber(ctx, arguments[index], nullptr) != index)
-+ return false;
-+ }
-+ return true;
-+}
-+
-+static CString scriptCallingWithManyArguments(ASCIILiteral prefix, ASCIILiteral suffix)
-+{
-+ StringBuilder builder;
-+ builder.append(prefix);
-+ for (unsigned index = 0; index < manyArgumentCount; ++index) {
-+ if (index)
-+ builder.append(", "_s);
-+ builder.append(index);
-+ }
-+ builder.append(suffix);
-+ return builder.toString().utf8();
-+}
-+
-+static JSValueRef checkArgumentsAsFunctionCallback(JSContextRef ctx, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*)
-+{
-+ return JSValueMakeBoolean(ctx, argumentsSurviveCollectionInCallback(ctx, argumentCount, arguments));
-+}
-+
-+static JSObjectRef checkArgumentsAsConstructorCallback(JSContextRef ctx, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*)
-+{
-+ bool survived = argumentsSurviveCollectionInCallback(ctx, argumentCount, arguments);
-+ JSObjectRef result = JSObjectMake(ctx, nullptr, nullptr);
-+ JSObjectSetProperty(ctx, result, APIString("ok"), JSValueMakeBoolean(ctx, survived), kJSPropertyAttributeNone, nullptr);
-+ return result;
-+}
-+
-+void TestAPI::functionCallbackArgumentsAndGC()
-+{
-+ APIString name("functionWithManyArguments");
-+ JSObjectRef function = JSObjectMakeFunctionWithCallback(context, name, checkArgumentsAsFunctionCallback);
-+ JSObjectSetProperty(context, JSContextGetGlobalObject(context), name, function, kJSPropertyAttributeNone, nullptr);
-+
-+ auto script = scriptCallingWithManyArguments("functionWithManyArguments("_s, ")"_s);
-+ ScriptResult result = evaluateScript(script.data());
-+ check(!!result && JSValueToBoolean(context, result.value()), "JSObjectMakeFunctionWithCallback arguments should survive a collection inside the callback.");
-+}
-+
-+void TestAPI::constructorCallbackArgumentsAndGC()
-+{
-+ JSClassDefinition definition = kJSClassDefinitionEmpty;
-+ JSClassRef jsClass = JSClassCreate(&definition);
-+ APIString name("ConstructorWithManyArguments");
-+ JSObjectRef constructor = JSObjectMakeConstructor(context, jsClass, checkArgumentsAsConstructorCallback);
-+ JSObjectSetProperty(context, JSContextGetGlobalObject(context), name, constructor, kJSPropertyAttributeNone, nullptr);
-+
-+ auto script = scriptCallingWithManyArguments("new ConstructorWithManyArguments("_s, ").ok"_s);
-+ ScriptResult result = evaluateScript(script.data());
-+ check(!!result && JSValueToBoolean(context, result.value()), "JSObjectMakeConstructor arguments should survive a collection inside the callback.");
-+
-+ JSClassRelease(jsClass);
-+}
-+
-+void TestAPI::classCallAsFunctionArgumentsAndGC()
-+{
-+ JSClassDefinition definition = kJSClassDefinitionEmpty;
-+ definition.className = "CallableWithManyArguments";
-+ definition.callAsFunction = checkArgumentsAsFunctionCallback;
-+ JSClassRef jsClass = JSClassCreate(&definition);
-+ APIString name("callableWithManyArguments");
-+ JSObjectSetProperty(context, JSContextGetGlobalObject(context), name, JSObjectMake(context, jsClass, nullptr), kJSPropertyAttributeNone, nullptr);
-+
-+ auto script = scriptCallingWithManyArguments("callableWithManyArguments("_s, ")"_s);
-+ ScriptResult result = evaluateScript(script.data());
-+ check(!!result && JSValueToBoolean(context, result.value()), "JSClassDefinition::callAsFunction arguments should survive a collection inside the callback.");
-+
-+ JSClassRelease(jsClass);
-+}
-+
-+void TestAPI::classCallAsConstructorArgumentsAndGC()
-+{
-+ JSClassDefinition definition = kJSClassDefinitionEmpty;
-+ definition.className = "ConstructibleWithManyArguments";
-+ definition.callAsConstructor = checkArgumentsAsConstructorCallback;
-+ JSClassRef jsClass = JSClassCreate(&definition);
-+ APIString name("ConstructibleWithManyArguments");
-+ JSObjectSetProperty(context, JSContextGetGlobalObject(context), name, JSObjectMake(context, jsClass, nullptr), kJSPropertyAttributeNone, nullptr);
-+
-+ auto script = scriptCallingWithManyArguments("new ConstructibleWithManyArguments("_s, ").ok"_s);
-+ ScriptResult result = evaluateScript(script.data());
-+ check(!!result && JSValueToBoolean(context, result.value()), "JSClassDefinition::callAsConstructor arguments should survive a collection inside the callback.");
-+
-+ JSClassRelease(jsClass);
-+}
-+
- void TestAPI::classDefinitionWithJSSubclass()
- {
- const static JSClassDefinition definition = kJSClassDefinitionEmpty;
-@@ -1241,6 +1363,10 @@ int testCAPIViaCpp(const char* filter)
- RUN(promiseDrainDoesNotEatExceptions());
- RUN(promiseEarlyHandledRejections());
- RUN(markedJSValueArrayAndGC());
-+ RUN(functionCallbackArgumentsAndGC());
-+ RUN(constructorCallbackArgumentsAndGC());
-+ RUN(classCallAsFunctionArgumentsAndGC());
-+ RUN(classCallAsConstructorArgumentsAndGC());
- RUN(classDefinitionWithJSSubclass());
- RUN(proxyReturnedWithJSSubclassing());
- RUN(testJSObjectSetOnGlobalObjectSubclassDefinition());
Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
--- 原补丁/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
+++ 适配补丁/Tools/TestWebKitAPI/Tests/JavaScriptCore/glib/TestJSC.cpp
@@ -1,166 +0,0 @@
-@@ -27,6 +27,7 @@
- #include <JavaScriptCore/JSContextRef.h>
- #include <jsc/jsc.h>
- #include <wtf/HashSet.h>
-+#include <wtf/MainThread.h>
- #include <wtf/Threading.h>
- #include <wtf/Vector.h>
- #include <wtf/glib/GRefPtr.h>
-@@ -4819,9 +4820,147 @@ static void testJSCJSON()
- }
- }
-
-+static constexpr unsigned varargsParameterCount = 16;
-+static constexpr unsigned varargsParameterLength = 512 * 1024;
-+
-+// Each parameter reports half a megabyte against a one megabyte smallHeapSize(), so the collector runs
-+// partway through the conversion loop, when only the argument Vector refers to the earlier parameters.
-+static void testJSCFunctionCallParameterLifetime()
-+{
-+ LeakChecker checker;
-+ GRefPtr<JSCContext> context = adoptGRef(jsc_context_new());
-+ checker.watch(context.get());
-+ ExceptionHandler exceptionHandler(context.get());
-+
-+ GRefPtr<JSCValue> function = adoptGRef(jsc_context_evaluate(context.get(),
-+ "(function() {\n"
-+ " for (var i = 0; i < arguments.length; i++) {\n"
-+ " if (arguments[i] !== String.fromCharCode(65 + i).repeat(524288))\n"
-+ " return 'parameter ' + i + ' did not survive';\n"
-+ " }\n"
-+ " return 'ok';\n"
-+ "})", -1));
-+ checker.watch(function.get());
-+ g_assert_true(jsc_value_is_function(function.get()));
-+
-+ GUniquePtr<char> parameters[varargsParameterCount];
-+ for (unsigned i = 0; i < varargsParameterCount; ++i)
-+ parameters[i].reset(g_strnfill(varargsParameterLength, static_cast<char>('A' + i)));
-+
-+#define STRING_PARAMETER(index) G_TYPE_STRING, parameters[index].get()
-+ GRefPtr<JSCValue> result = adoptGRef(jsc_value_function_call(function.get(),
-+ STRING_PARAMETER(0), STRING_PARAMETER(1), STRING_PARAMETER(2), STRING_PARAMETER(3),
-+ STRING_PARAMETER(4), STRING_PARAMETER(5), STRING_PARAMETER(6), STRING_PARAMETER(7),
-+ STRING_PARAMETER(8), STRING_PARAMETER(9), STRING_PARAMETER(10), STRING_PARAMETER(11),
-+ STRING_PARAMETER(12), STRING_PARAMETER(13), STRING_PARAMETER(14), STRING_PARAMETER(15),
-+ G_TYPE_NONE));
-+#undef STRING_PARAMETER
-+
-+ checker.watch(result.get());
-+ GUniquePtr<char> resultString(jsc_value_to_string(result.get()));
-+ g_assert_cmpstr(resultString.get(), ==, "ok");
-+}
-+
-+// Above the argument array's inline capacity, where a stack buffer would be found by conservative
-+// scanning whether or not the collector knows about it.
-+static constexpr unsigned manyArgumentCount = 32;
-+static constexpr double recycledArgumentValue = 987654321;
-+
-+// Called from the toString() of the first argument, which JSC calls while it is still converting the
-+// remaining arguments of the function being invoked.
-+static void collectAndRecycleValues(int)
-+{
-+ JSCContext* context = jsc_context_get_current();
-+ jscContextGarbageCollect(context, true);
-+
-+ // Where a JSValue does not fit in a pointer a JSValueRef for a number is a JSAPIValueWrapper cell,
-+ // so these allocations recycle the wrappers that a dangling argument still points at. The unref
-+ // only unprotects the cell; it stays allocated until the next collection.
-+ for (unsigned i = 0; i < 4096; ++i)
-+ g_object_unref(jsc_value_new_number(context, recycledArgumentValue));
-+}
-+
-+static GRefPtr<JSCValue> collectFunction(JSCContext* context)
-+{
-+ return adoptGRef(jsc_value_new_function(context, "collect", G_CALLBACK(collectAndRecycleValues), nullptr, nullptr, G_TYPE_NONE, 1, G_TYPE_INT));
-+}
-+
-+// Converting the first argument to G_TYPE_STRING calls its toString(), so "collect(0)" runs before
-+// JSC converts the second argument.
-+static GUniquePtr<char> scriptCallingWithManyArguments(const char* callee)
-+{
-+ GString* script = g_string_new(callee);
-+ g_string_append(script, "({ toString: function() { collect(0); return 'trigger'; } }, 42");
-+ for (unsigned i = 2; i < manyArgumentCount; ++i)
-+ g_string_append_printf(script, ", %u", i);
-+ g_string_append(script, ")");
-+ return GUniquePtr<char>(g_string_free(script, FALSE));
-+}
-+
-+static double s_secondArgument;
-+
-+static void recordSecondArgument(const char*, double second)
-+{
-+ s_secondArgument = second;
-+}
-+
-+static void testJSCCallbackArgumentLifetime()
-+{
-+ LeakChecker checker;
-+ GRefPtr<JSCContext> context = adoptGRef(jsc_context_new());
-+ checker.watch(context.get());
-+ ExceptionHandler exceptionHandler(context.get());
-+
-+ GRefPtr<JSCValue> collect = collectFunction(context.get());
-+ checker.watch(collect.get());
-+ jsc_context_set_value(context.get(), "collect", collect.get());
-+
-+ GRefPtr<JSCValue> function = adoptGRef(jsc_value_new_function(context.get(), "check", G_CALLBACK(recordSecondArgument), nullptr, nullptr, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_DOUBLE));
-+ checker.watch(function.get());
-+ jsc_context_set_value(context.get(), "check", function.get());
-+
-+ s_secondArgument = 0;
-+ GUniquePtr<char> script = scriptCallingWithManyArguments("check");
-+ GRefPtr<JSCValue> result = adoptGRef(jsc_context_evaluate(context.get(), script.get(), -1));
-+ checker.watch(result.get());
-+ g_assert_cmpfloat(s_secondArgument, ==, 42);
-+}
-+
-+static Foo* fooCreateRecordingSecondArgument(const char*, double second)
-+{
-+ s_secondArgument = second;
-+ return fooCreate();
-+}
-+
-+static void testJSCConstructorArgumentLifetime()
-+{
-+ LeakChecker checker;
-+ GRefPtr<JSCContext> context = adoptGRef(jsc_context_new());
-+ checker.watch(context.get());
-+ ExceptionHandler exceptionHandler(context.get());
-+
-+ GRefPtr<JSCValue> collect = collectFunction(context.get());
-+ checker.watch(collect.get());
-+ jsc_context_set_value(context.get(), "collect", collect.get());
-+
-+ JSCClass* jscClass = jsc_context_register_class(context.get(), "Foo", nullptr, nullptr, reinterpret_cast<GDestroyNotify>(fooFree));
-+ checker.watch(jscClass);
-+ GRefPtr<JSCValue> constructor = adoptGRef(jsc_class_add_constructor(jscClass, nullptr, G_CALLBACK(fooCreateRecordingSecondArgument), nullptr, nullptr,
-+ G_TYPE_POINTER, 2, G_TYPE_STRING, G_TYPE_DOUBLE));
-+ checker.watch(constructor.get());
-+ jsc_context_set_value(context.get(), jsc_class_get_name(jscClass), constructor.get());
-+
-+ s_secondArgument = 0;
-+ GUniquePtr<char> script = scriptCallingWithManyArguments("new Foo");
-+ GRefPtr<JSCValue> result = adoptGRef(jsc_context_evaluate(context.get(), script.get(), -1));
-+ checker.watch(result.get());
-+ g_assert_cmpfloat(s_secondArgument, ==, 42);
-+}
-+
- int main(int argc, char** argv)
- {
- g_test_init(&argc, &argv, nullptr);
-+ WTF::initializeMainThread();
-
- // options should always be the first test, since changing options
- // is not allowed after the first VM instance is created.
-@@ -4846,6 +4985,9 @@ int main(int argc, char** argv)
- g_test_add_func("/jsc/autocleanups", testsJSCAutocleanups);
- #endif
- g_test_add_func("/jsc/json", testJSCJSON);
-+ g_test_add_func("/jsc/function-call-parameter-lifetime", testJSCFunctionCallParameterLifetime);
-+ g_test_add_func("/jsc/callback-argument-lifetime", testJSCCallbackArgumentLifetime);
-+ g_test_add_func("/jsc/constructor-argument-lifetime", testJSCConstructorArgumentLifetime);
-
- return g_test_run();
- }


原因说明:
1.master(2.52.6):正常修复
2.openEuler-20.03-LTS-SP4(2.22.2):暂不修复-暂无解决方案或补丁
3.openEuler-22.03-LTS-SP4(2.36.3):正常修复
4.openEuler-24.03-LTS-Next(2.50.6):正常修复
5.openEuler-24.03-LTS-SP1(2.38.2):正常修复
6.openEuler-24.03-LTS-SP3(2.38.2):正常修复
7.openEuler-24.03-LTS-SP4(2.50.6):正常修复


@yanan-rock 经过 cve-manager 解析, 已分析的内容如下表所示:
| 状态 | 分析项目 | 内容 |
|---|---|---|
| 已分析 | 1.影响性分析说明 | A flaw was found in WebKitGTK. Processing malicious web content can cause a use-after-free issue due to improper memory handling and result in memory corruption. |
| 已分析 | 2.openEulerScore | 8.8 |
| 已分析 | 3.openEulerVector | AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| 已分析 | 4.受影响版本排查 | master:受影响,openEuler-20.03-LTS-SP4:受影响,openEuler-22.03-LTS-SP4:受影响,openEuler-24.03-LTS-Next:受影响,openEuler-24.03-LTS-SP1:受影响,openEuler-24.03-LTS-SP3:受影响,openEuler-24.03-LTS-SP4:受影响 |
| 已分析 | 5.是否涉及abi变化 | master:否,openEuler-20.03-LTS-SP4:否,openEuler-22.03-LTS-SP4:否,openEuler-24.03-LTS-Next:否,openEuler-24.03-LTS-SP1:否,openEuler-24.03-LTS-SP3:否,openEuler-24.03-LTS-SP4:否 |
| 已分析 | 6.原因说明 | master:正常修复,openEuler-20.03-LTS-SP4:暂不修复-暂无解决方案或补丁,openEuler-22.03-LTS-SP4:正常修复,openEuler-24.03-LTS-Next:正常修复,openEuler-24.03-LTS-SP1:正常修复,openEuler-24.03-LTS-SP3:正常修复,openEuler-24.03-LTS-SP4:正常修复 |
请确认分析内容的准确性, 确认无误后, 您可以进行后续步骤, 否则您可以继续分析.


经过cve-manager解析,所有PR均已合入


🔍 CVE 项目匹配性分析结果
CVE: CVE-2026-78376
针对分支: master
结果: ❌ 不匹配
原因: CVE 存在:NVD totalResults=1(secalert@redhat.com,2026-08-24 发布,CVSS 8.8),MITRE 记录状态 PUBLISHED,标题 use-after-free of jscvalue function parameters,与 Issue body 描述一致;Issue 参考链接(NVD/Red Hat Bugzilla 2521858/Red Hat CVE/WebKit PR 72142/Debian tracker)均指向同一漏洞,无 GHSA 链接。组件匹配:受影响产品 WebKitGTK/webkitgtk,与项目包名 webkitgtk 一致。版本匹配:MITRE 标记 WebKitGTK >=2.21.1 均受影响,Issue 受影响版本列表含 2.52.1/2.52.3(与当前 2.52.6 同一次版本系列),且 Issue 自身排查标记 master(2.52.6) 为受影响,当前版本处于受影响范围。备注:master 分支 webkitgtk.spec(2.52.6-2)已含 Patch6000 backport-CVE-2026-78376.patch(changelog: fix CVE-2026-78376,2026-09-01,为上游 9fa946d9a72f / 319867@main 的 cherry-pick),后续方案设计阶段须先做存量检查(already_fixed),避免重复提交补丁。
建议:
- 此 CVE 实际影响的项目与当前 Issue 所在项目不一致
- 建议关闭此 Issue,或将其移至正确项目的 Issue 列表
- 如有疑问,请联系安全团队确认
此评论由 Claude Agent Team(项目经理)自动生成


一、漏洞信息
漏洞编号:CVE-2026-78376
漏洞归属组件:webkitgtk
漏洞归属的版本:2.46.6,2.50.3,2.50.4,2.50.6,2.52.1,2.52.3
CVSS评分:
BaseScore:8.8 High
Vector:CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
漏洞简述:
A flaw was found in WebKitGTK. Processing malicious web content can cause a use-after-free issue due to improper memory handling and result in memory corruption.
漏洞公开时间:2026-08-24 22:17:05
漏洞创建时间:2026-08-25 22:57:33
漏洞详情参考链接:
https://nvd.nist.gov/vuln/detail/CVE-2026-78376
更多参考(点击展开)
漏洞分析指导链接:
https://atomgit.com/openeuler/cve-manager/blob/master/cve-vulner-manager/doc/md/manual.md
漏洞数据来源:
七彩瞬析开源风险感知平台
漏洞补丁信息:
详情(点击展开)
二、漏洞分析结构反馈
影响性分析说明:
A flaw was found in WebKitGTK. Processing malicious web content can cause a use-after-free issue due to improper memory handling and result in memory corruption.
openEuler评分:
8.8
Vector:CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
受影响版本排查(受影响/不受影响):
1.master(2.52.6):受影响
2.openEuler-20.03-LTS-SP4:受影响
3.openEuler-22.03-LTS-SP4:受影响
4.openEuler-24.03-LTS-Next(2.50.6):受影响
5.openEuler-24.03-LTS-SP1:受影响
6.openEuler-24.03-LTS-SP3:受影响
7.openEuler-24.03-LTS-SP4(2.50.6):受影响
修复是否涉及abi变化(是/否):
1.master(2.52.6):否
2.openEuler-20.03-LTS-SP4:否
3.openEuler-22.03-LTS-SP4:否
4.openEuler-24.03-LTS-Next(2.50.6):否
5.openEuler-24.03-LTS-SP1:否
6.openEuler-24.03-LTS-SP3:否
7.openEuler-24.03-LTS-SP4(2.50.6):否
原因说明:
1.master(2.52.6):正常修复
2.openEuler-20.03-LTS-SP4:暂不修复-暂无解决方案或补丁
3.openEuler-22.03-LTS-SP4:正常修复
4.openEuler-24.03-LTS-Next(2.50.6):正常修复
5.openEuler-24.03-LTS-SP1:正常修复
6.openEuler-24.03-LTS-SP3:正常修复
7.openEuler-24.03-LTS-SP4(2.50.6):正常修复