Medium CVSS 8.8 webkit Other 🔧 Commit mapped

Overview

Medium
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionProcessing maliciously crafted web content may lead to memory corruption
ComponentWebKit
Sub-componentThirdParty ANGLE
Bug ClassOther
Tracker293895
Fix commitbcb47de34ff7 (WebKit/WebKit) +9940/-2446
CWECWE-119 (Buffer bounds error)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
CreditedIgnacio Sanmillan (@ulexec)
Disclosed2025-09-15

Background

ANGLE
The Almost Native Graphics Layer Engine, the library WebKit uses to implement WebGL by translating GL ES calls/shaders to the platform backend (Metal, Vulkan, D3D).
Dependency roll
A wholesale update of a bundled third-party component to a newer upstream revision, which mixes many unrelated changes so an individual security fix is hard to isolate.
Shader translator (MSL/SPIR-V)
The ANGLE compiler stage that converts GLSL ES into Metal Shading Language or SPIR-V; bugs here can produce miscompiled shaders with unsafe behavior.
gl_PerVertex
The built-in interface block carrying gl_Position/gl_PointSize/gl_ClipDistance/gl_CullDistance between shader stages; its members require special built-in qualifier handling.
Contents observer
ANGLE’s mechanism by which VertexArray/Texture objects are notified when a bound Buffer’s contents change, so dirty state is tracked; stale observer pointers are a UAF risk.
GPU process
The sandboxed WebKit process that hosts WebGL/ANGLE on modern macOS/iOS, isolating GPU work from WebContent.

Root Cause Analysis

This commit is a bulk roll of the bundled ANGLE dependency (Source/ThirdParty/ANGLE/*): angle_commit.h, DEPS, changes.diff and dozens of autogenerated tables are bumped wholesale, and the shown source diff is a mixture of many unrelated upstream changes rather than one isolated security patch. Because the security-relevant change is imported as part of a large dependency update, it is NOT cleanly isolable from the diff, and I will not claim a single definitive corruption mechanism; the following are the security-plausible candidates, explicitly marked as inference.

  1. Shader-translator correctness in the Metal backend: EmitMetal.cpp/ProgramPrelude.cpp replace the shared ANGLE_iadd/ANGLE_isub helpers (which were wrongly used for both EOpAdd/EOpSub and their compound-assign forms) with distinct value-returning add/sub and in-place addAssign/subAssign helpers plus dedicated pre/post increment/decrement helpers, all doing arithmetic through unsigned types to avoid signed-integer overflow UB; miscompiling a compound assignment as a by-value expression could corrupt generated MSL and thus GPU-side behavior for crafted WebGL shaders.
  2. gl_PerVertex handling: ParseContext.cpp now applies the proper built-in qualifiers (EvqPosition/EvqPointSize/EvqClipDistance/EvqCullDistance) to per-vertex members and tags the block EvqPerVertexIn/Out, CollectVariables.cpp skips per-vertex in/out from variable collection, and TranslatorSPIRV.cpp assigns the reserved input/output PerVertex SPIR-V IDs — mishandling built-in redeclaration is a classic shader-compiler memory-safety area.
  3. Reserved-name hardening: Context.cpp now returns -1 from getAttribLocation/getUniformLocation when the name starts with a reserved (gl_) prefix.
  4. Buffer contents-observer refactor: Buffer::onContentsChange now takes a Context*, asserts that only texture contents-observers remain, and notifies the context of the buffer binding mask, while State.cpp delegates element-array binding to VertexArray::bindElementBuffer — this is the observer/dirty-tracking machinery that has historically been a source of use-after-free/stale-pointer bugs between Buffer, VertexArray and Texture.
  5. Depth clamping: Context::clearBufferfv/clearBufferfi now clamp01 the depth value. The violated invariant and precise fix therefore cannot be pinned from this diff alone; the honest conclusion is that a specific ANGLE-upstream fix (most plausibly in the shader translator or the buffer/vertex-array observer path) rode in with the roll and the surrounding table/enum churn is noise.
Key insight
This is a bulk ANGLE dependency roll, not a surgical patch: no single memory-corruption mechanism is isolable from the diff, and the security-relevant fix (most plausibly a shader-translator correctness bug or a Buffer/VertexArray contents-observer lifetime bug) is buried among large autogenerated enum/table churn.

Attack Path

  1. Serve malicious WebGL/WebGL2 content Get a victim to load a page that creates a WebGL context; ANGLE is the GL implementation backing WebGL in WebKit (GPU process on macOS/iOS).
  2. Feed crafted shaders or GL state Submit GLSL that exercises the changed translator paths — signed-integer compound assignments / increment-decrement (Metal backend) or gl_PerVertex built-in redeclaration (SPIR-V/Metal) — or drive the buffer/vertex-array binding and contents-change paths that were refactored.
  3. Reach the vulnerable ANGLE code Inference: the crafted input drives either a miscompiled shader (bad generated MSL/SPIR-V) or a stale observer/dirty-state interaction in Buffer/VertexArray/Texture.
  4. Induce memory corruption Inference: depending on the true root cause this yields either GPU-side out-of-bounds behavior from a miscompiled shader or a use-after-free/stale-pointer in the ANGLE object graph; the exact primitive is not determinable from this bulk-roll diff.
  5. Escalate within the GPU process Standard exploitation background: groom the GPU-process heap and convert the corruption toward arbitrary R/W and code execution inside the sandboxed GPU process, then chain a separate escape.

Impact Assessment

Because the fix is delivered inside a bulk ANGLE roll, the strength of the primitive cannot be established from this diff with confidence; the CVE is rated medium with ‘memory corruption from crafted web content’. The most plausible reachable surface is WebGL shader compilation (Metal/SPIR-V translator) or the buffer/vertex-array/texture observer machinery, reached from crafted JS+GLSL. On modern WebKit ANGLE/WebGL runs in the sandboxed GPU process, so a resulting OOB or use-after-free would be confined there and would require a further sandbox escape for full compromise; escalation to code execution is conceivable but not demonstrable from this diff. This assessment is partly inference given the roll cannot be reduced to one mechanism.

Files Changed

  • Source/ThirdParty/ANGLE/.gn
  • Source/ThirdParty/ANGLE/ANGLE.plist
  • Source/ThirdParty/ANGLE/CONTRIBUTORS
  • Source/ThirdParty/ANGLE/DEPS
  • Source/ThirdParty/ANGLE/GLESv2.cmake
  • Source/ThirdParty/ANGLE/WATCHLISTS
  • Source/ThirdParty/ANGLE/WebKit/ANGLEShaderProgramVersion.h
  • Source/ThirdParty/ANGLE/WebKit/angle_commit.h
  • Source/ThirdParty/ANGLE/changes.diff
  • Source/ThirdParty/ANGLE/doc/ExtensionSupport.md
  • Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_device_webgpu.txt
  • Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_platform_angle_webgpu.txt
  • Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_webgpu_texture_client_buffer.txt
  • Source/ThirdParty/ANGLE/gni/angle.gni
  • Source/ThirdParty/ANGLE/include/EGL/eglext_angle.h
  • Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h
  • Source/ThirdParty/ANGLE/include/GLES2/gl2ext_angle.h
  • Source/ThirdParty/ANGLE/include/export.h
  • Source/ThirdParty/ANGLE/include/platform/Feature.h
  • Source/ThirdParty/ANGLE/include/platform/autogen/FeaturesVk_autogen.h
  • Source/ThirdParty/ANGLE/include/platform/autogen/FeaturesWgpu_autogen.h
  • Source/ThirdParty/ANGLE/include/platform/gen_features.py
  • Source/ThirdParty/ANGLE/include/platform/vk_features.json
  • Source/ThirdParty/ANGLE/include/platform/wgpu_features.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/Extension_files.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_CTS_(dEQP)_build_files.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_WGL_loader.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GL_EGL_entry_points.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/GLenum_value_to_string_map.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/OpenGL_dispatch_table.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/SPIR-V_helpers.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/WebGPU_format.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/interpreter_utils.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/packed_enum.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/proc_table.json
  • Source/ThirdParty/ANGLE/scripts/code_generation_hashes/restricted_traces.json
  • Source/ThirdParty/ANGLE/scripts/generate_entry_points.py
  • Source/ThirdParty/ANGLE/scripts/registry_xml.py
  • Source/ThirdParty/ANGLE/scripts/roll_aosp.sh
  • Source/ThirdParty/ANGLE/src/android_system_settings/res/layout/fragment.xml
  • Source/ThirdParty/ANGLE/src/android_system_settings/src/com/android/angle/AndroidManifest.xml
  • Source/ThirdParty/ANGLE/src/android_system_settings/src/com/android/angle/MainActivity.java
  • Source/ThirdParty/ANGLE/src/android_system_settings/src/com/android/angle/common/MainFragment.java
  • Source/ThirdParty/ANGLE/src/common/PackedGLEnums_autogen.cpp
  • Source/ThirdParty/ANGLE/src/common/PackedGLEnums_autogen.h
  • Source/ThirdParty/ANGLE/src/common/angleutils.cpp
  • Source/ThirdParty/ANGLE/src/common/angleutils.h
  • Source/ThirdParty/ANGLE/src/common/gl_enum_utils_autogen.cpp
  • Source/ThirdParty/ANGLE/src/common/packed_gl_enums.json
  • Source/ThirdParty/ANGLE/src/common/system_utils.h
  • Source/ThirdParty/ANGLE/src/common/utilities.cpp
  • Source/ThirdParty/ANGLE/src/compiler/translator/CollectVariables.cpp
  • Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp
  • Source/ThirdParty/ANGLE/src/compiler/translator/Types.h
  • Source/ThirdParty/ANGLE/src/compiler/translator/msl/EmitMetal.cpp
  • Source/ThirdParty/ANGLE/src/compiler/translator/msl/ProgramPrelude.cpp
  • Source/ThirdParty/ANGLE/src/compiler/translator/spirv/TranslatorSPIRV.cpp
  • Source/ThirdParty/ANGLE/src/gpu_info_util/SystemInfo.h
  • Source/ThirdParty/ANGLE/src/libANGLE/Buffer.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/Buffer.h
  • Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/Caps.h
  • Source/ThirdParty/ANGLE/src/libANGLE/Context.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/Context.h
  • Source/ThirdParty/ANGLE/src/libANGLE/Context.inl.h
  • Source/ThirdParty/ANGLE/src/libANGLE/Context_gles_ext_autogen.h
  • Source/ThirdParty/ANGLE/src/libANGLE/ErrorStrings.h
  • Source/ThirdParty/ANGLE/src/libANGLE/Framebuffer.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/State.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/Surface.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/Texture.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/Texture.h
  • Source/ThirdParty/ANGLE/src/libANGLE/TransformFeedback.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/VertexArray.h
  • Source/ThirdParty/ANGLE/src/libANGLE/VertexArray_unittest.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/angletypes.h
  • Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_autogen.h
  • Source/ThirdParty/ANGLE/src/libANGLE/capture/capture_gles_ext_params.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/gles_extensions_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/gles_extensions_autogen.h
  • Source/ThirdParty/ANGLE/src/libANGLE/queryutils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/SurfaceImpl.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/SurfaceImpl.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/VertexArrayImpl.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/SurfaceD3D.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/Query9.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/driver_utils.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/ContextGL.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DispatchTableGL_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/DispatchTableGL_autogen.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/QueryGL.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/functionsgl_typedefs.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/gl_bindings_data.json
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/null_functions.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/null_functions.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/renderergl_utils.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/gl/wgl/D3DTextureSurfaceWGL.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ProvokingVertexHelper.mm
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/VertexArrayMtl.mm
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_command_buffer.mm
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ContextVk.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/ProgramExecutableVk.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/SurfaceVk.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/TextureVk.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/UtilsVk.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/spv_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/spv_utils.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_caps_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_format_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_helpers.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_renderer.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_renderer.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/vulkan/vk_utils.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/BUILD.gn
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/BufferWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/ContextWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/ContextWgpu.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/DeviceWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/DisplayWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/DisplayWgpu.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/ImageWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/ImageWgpu.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/ProgramExecutableWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/ProgramWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/RenderbufferWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/RenderbufferWgpu.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/SurfaceWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/SurfaceWgpu.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/TextureWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/TextureWgpu.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/VertexArrayWgpu.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/linux/x11/WindowSurfaceWgpuX11.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/mac/WindowSurfaceWgpuMetalLayer.mm
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_command_buffer.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_command_buffer.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_format_map.json
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_format_table_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_format_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_format_utils.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_helpers.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_helpers.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_pipeline_state.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_proc_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_proc_utils.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_sources.gni
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_utils.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/wgpu_utils.h
  • Source/ThirdParty/ANGLE/src/libANGLE/renderer/wgpu/win32/WindowSurfaceWgpuWin32.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/validationES.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/validationES2.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/validationES3.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/validationES31.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/validationES31.h
  • Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT.cpp
  • Source/ThirdParty/ANGLE/src/libANGLE/validationESEXT_autogen.h
  • Source/ThirdParty/ANGLE/src/libGLESv2.gni
  • Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_1_0_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_3_1_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_3_2_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libGLESv2/entry_points_gles_ext_autogen.h
  • Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.cpp
  • Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_autogen.def
  • Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_no_capture_autogen.def
  • Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_vulkan_secondaries_autogen.def
  • Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2_with_capture_autogen.def
  • Source/ThirdParty/ANGLE/src/tests/BUILD.gn
  • Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni
  • Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt
  • Source/ThirdParty/ANGLE/src/tests/compiler_tests/Parse_test.cpp
  • Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp.gni
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/ClearTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/DrawBaseVertexBaseInstanceTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/ErrorMessages.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/GLSLTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/GLSLUBTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/MipmapTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/MultiDrawTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/SyncQueriesTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/TextureTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/TransformFeedbackTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/gl_tests/WebGLCompatibilityTest.cpp
  • Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_trace_perf.py
  • Source/ThirdParty/ANGLE/src/tests/restricted_traces/restricted_traces.json
  • Source/ThirdParty/ANGLE/src/tests/test_utils/angle_test_instantiate.cpp
  • Source/ThirdParty/ANGLE/src/tests/test_utils/angle_test_platform.cpp
  • Source/ThirdParty/ANGLE/src/tests/test_utils/angle_test_platform.h
  • Source/ThirdParty/ANGLE/util/autogen/angle_features_autogen.cpp
  • Source/ThirdParty/ANGLE/util/autogen/angle_features_autogen.h
  • Source/ThirdParty/ANGLE/util/capture/frame_capture_replay_autogen.cpp

Audit Directions

  • Diff the ANGLE roll against upstream
    Recover the two ANGLE commit hashes from Source/ThirdParty/ANGLE/WebKit/angle_commit.h before/after and review only the upstream commits between them; grep the roll’s changes.diff for security-tagged commits to find the actual fix rather than the table noise.
  • Metal/SPIR-V translator arithmetic and built-ins
    Audit EmitMetal.cpp/ProgramPrelude.cpp for any remaining operator that still routes compound-assign through a by-value helper, and TranslatorSPIRV.cpp/ParseContext.cpp/CollectVariables.cpp for EvqPerVertexIn/Out handling; grep for ANGLE_iadd/ANGLE_isub, EOpAddAssign, isGLPerVertex, kIdInputPerVertexBlock.
  • Buffer/VertexArray/Texture contents-observer lifetimes
    In libANGLE trace onContentsChange/onDataChanged(Context*), addContentsObserver/removeContentsObserver, bindElementBuffer and mContentsObservers for stale-pointer/UAF risk; grep for kBufferTextureIndex and getBufferBindingMask across renderer backends listed in COVERAGE NOTES (VertexArrayVk/Mtl, TextureVk).
  • Reserved-name and clamp hardening as fix markers
    Treat the new nameStartsWithReservedPrefix guards in getAttribLocation/getUniformLocation and the clamp01 depth guards in clearBufferfv/clearBufferfi as hints to the intended bug class; grep the omitted validationES*.cpp files for missing reserved-prefix or range checks on the same entry points.
diff --git a/Source/ThirdParty/ANGLE/ANGLE.plist b/Source/ThirdParty/ANGLE/ANGLE.plist
index 66cf3f562231..774bc8030b7c 100644
--- a/Source/ThirdParty/ANGLE/ANGLE.plist
+++ b/Source/ThirdParty/ANGLE/ANGLE.plist
@@ -6,13 +6,13 @@
 		<key>OpenSourceProject</key>
 		<string>ANGLE</string>
 		<key>OpenSourceVersion</key>
-		<string>dcbcee8ab32af9ddc7ae1e91c42d995e5281602c</string>
+		<string>b1359277066648c3577ea8b57cc5e0bccee7b6cc</string>
 		<key>OpenSourceWebsiteURL</key>
 		<string>http://code.google.com/p/angleproject/</string>
 		<key>OpenSourceSCM</key>
-		<string>git clone https://chromium.googlesource.com/angle/angle &amp;&amp; cd angle &amp;&amp; git checkout dcbcee8ab32af9ddc7ae1e91c42d995e5281602c</string>
+		<string>git clone https://chromium.googlesource.com/angle/angle &amp;&amp; cd angle &amp;&amp; git checkout b1359277066648c3577ea8b57cc5e0bccee7b6cc</string>
 		<key>OpenSourceImportDate</key>
-		<string>2025-05-20</string>
+		<string>2025-06-02</string>
 		<key>OpenSourceLicense</key>
 		<string>BSD</string>
 		<key>OpenSourceLicenseFile</key>
diff --git a/Source/ThirdParty/ANGLE/CONTRIBUTORS b/Source/ThirdParty/ANGLE/CONTRIBUTORS
index 95f1f6d4440c..01ca94a9acc1 100644
--- a/Source/ThirdParty/ANGLE/CONTRIBUTORS
+++ b/Source/ThirdParty/ANGLE/CONTRIBUTORS
@@ -176,6 +176,7 @@ Samsung Electronics, Inc.
  Colin Peter
  Hyunchang Kim
  Hyunseok Ko
+ Hyunwoo Yu
  Igor Nazarov
  Jaedon Lee
  Jaewoo Kim
diff --git a/Source/ThirdParty/ANGLE/GLESv2.cmake b/Source/ThirdParty/ANGLE/GLESv2.cmake
index 47028998f053..a28f20c9c637 100644
--- a/Source/ThirdParty/ANGLE/GLESv2.cmake
+++ b/Source/ThirdParty/ANGLE/GLESv2.cmake
@@ -246,6 +246,7 @@ set(libangle_includes
     "include/platform/autogen/FeaturesGL_autogen.h"
     "include/platform/autogen/FeaturesMtl_autogen.h"
     "include/platform/autogen/FeaturesVk_autogen.h"
+    "include/platform/autogen/FeaturesWgpu_autogen.h"
     "include/platform/autogen/FrontendFeatures_autogen.h"
     "include/platform/PlatformMethods.h"
     "include/vulkan/vulkan_fuchsia_ext.h"
diff --git a/Source/ThirdParty/ANGLE/WATCHLISTS b/Source/ThirdParty/ANGLE/WATCHLISTS
index f0e7d8a3a0e6..f7e80956f66f 100644
--- a/Source/ThirdParty/ANGLE/WATCHLISTS
+++ b/Source/ThirdParty/ANGLE/WATCHLISTS
@@ -10,6 +10,9 @@
 
 {
   'WATCHLIST_DEFINITIONS': {
+    'angle-features': {
+      'filepath': 'util/autogen/angle_features_autogen.h',
+    },
     'vulkan': {
       'filepath': 'src/libANGLE/renderer/vulkan/',
     },
@@ -19,6 +22,10 @@
   # Please keep alphabetical
   ##############################################################################
   'WATCHLISTS': {
+    'angle-features': [
+      'kaiyili+[email protected]',
+      '[email protected]'
+    ],
     'vulkan': ['cclao+[email protected]'],
   },
 }
diff --git a/Source/ThirdParty/ANGLE/WebKit/ANGLEShaderProgramVersion.h b/Source/ThirdParty/ANGLE/WebKit/ANGLEShaderProgramVersion.h
index 93f6e720d37a..ec54c29657b7 100644
--- a/Source/ThirdParty/ANGLE/WebKit/ANGLEShaderProgramVersion.h
+++ b/Source/ThirdParty/ANGLE/WebKit/ANGLEShaderProgramVersion.h
@@ -1,2 +1,2 @@
-#define ANGLE_PROGRAM_VERSION "56555a38a4b92c6c0e8dfcb7f8f02cc3"
+#define ANGLE_PROGRAM_VERSION "ab7a7ba88bccfbf0b87ab405179bc25c"
 #define ANGLE_PROGRAM_VERSION_HASH_SIZE 16
diff --git a/Source/ThirdParty/ANGLE/WebKit/angle_commit.h b/Source/ThirdParty/ANGLE/WebKit/angle_commit.h
index f48923e537ce..01018e686b6a 100644
--- a/Source/ThirdParty/ANGLE/WebKit/angle_commit.h
+++ b/Source/ThirdParty/ANGLE/WebKit/angle_commit.h
@@ -1,4 +1,4 @@
-#define ANGLE_COMMIT_HASH "dcbcee8ab32a"
+#define ANGLE_COMMIT_HASH "b13592770666"
 #define ANGLE_COMMIT_HASH_SIZE 12
-#define ANGLE_COMMIT_DATE "2025-05-19 13:43:29 -0700"
-#define ANGLE_COMMIT_POSITION 25482
+#define ANGLE_COMMIT_DATE "2025-05-30 20:12:17 -0700"
+#define ANGLE_COMMIT_POSITION 25547
diff --git a/Source/ThirdParty/ANGLE/changes.diff b/Source/ThirdParty/ANGLE/changes.diff
index 14d027e55887..38e702dd0fe5 100644
--- a/Source/ThirdParty/ANGLE/changes.diff
+++ b/Source/ThirdParty/ANGLE/changes.diff
@@ -1,5 +1,5 @@
 diff --git a/doc/ExtensionSupport.md b/doc/ExtensionSupport.md
-index 54c9f5094e67859b8d69d38026f03becb381bc45..6fe14a3a0a68d3b095c8ba8a42a3d6304752b13c 100644
+index db98abc0e7318a935b920c8f6d79c5a9950272f1..94728c3d214fa3e1aa4ffade3f711604aaa71daf 100644
 --- a/doc/ExtensionSupport.md
 +++ b/doc/ExtensionSupport.md
 @@ -231,6 +231,7 @@ using data from registry_xml.py and gl.xml.
@@ -10,7 +10,7 @@ index 54c9f5094e67859b8d69d38026f03becb381bc45..6fe14a3a0a68d3b095c8ba8a42a3d630
  | [GL_CHROMIUM_framebuffer_mixed_samples](https://chromium.googlesource.com/angle/angle/+/refs/heads/main/extensions/CHROMIUM_framebuffer_mixed_samples.txt) |  |  |  |  |  |  |  |
  | [GL_ANGLE_framebuffer_multisample](https://chromium.googlesource.com/angle/angle/+/refs/heads/main/extensions/ANGLE_framebuffer_multisample.txt) | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; |
  | [GL_ANGLE_get_image](https://chromium.googlesource.com/angle/angle/+/refs/heads/main/extensions/ANGLE_get_image.txt) | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; |
-@@ -268,6 +269,7 @@ using data from registry_xml.py and gl.xml.
+@@ -267,6 +268,7 @@ using data from registry_xml.py and gl.xml.
  | [GL_ANGLE_texture_external_update](https://chromium.googlesource.com/angle/angle/+/refs/heads/main/extensions/ANGLE_texture_external_update.txt) |  |  |  |  |  |  |  |
  | [GL_ANGLE_texture_multisample](https://chromium.googlesource.com/angle/angle/+/refs/heads/main/extensions/ANGLE_texture_multisample.txt) | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; |
  | [GL_ANGLE_texture_rectangle](https://chromium.googlesource.com/angle/angle/+/refs/heads/main/extensions/ANGLE_texture_rectangle.txt) |  |  |  |  |  |  |  |
@@ -19,10 +19,10 @@ index 54c9f5094e67859b8d69d38026f03becb381bc45..6fe14a3a0a68d3b095c8ba8a42a3d630
  | [GL_ANGLE_webgl_compatibility](https://chromium.googlesource.com/angle/angle/+/refs/heads/main/extensions/ANGLE_webgl_compatibility.txt) |  |  |  |  |  |  |  |
  | [GL_ANGLE_yuv_internal_format](https://chromium.googlesource.com/angle/angle/+/refs/heads/main/extensions/ANGLE_yuv_internal_format.txt) | &#x2714; |  | &#x2714; | &#x2714; | &#x2714; | &#x2714; | &#x2714; |
 diff --git a/include/GLES2/gl2ext_angle.h b/include/GLES2/gl2ext_angle.h
-index e0d4c99c3d7a5dc7f44006134cff681045f425c1..2f955f9bae9e47da061d0013553154c7cdd1fa59 100644
+index 46b52b05a9f490f1ea686d1915aef7508878d77a..7ac187ffe7048404f7f3fd16bb93cfe74f4b3eed 100644
 --- a/include/GLES2/gl2ext_angle.h
 +++ b/include/GLES2/gl2ext_angle.h
-@@ -748,5 +748,23 @@ GL_APICALL void GL_APIENTRY glGetPointervANGLE (GLenum pname, void **params);
+@@ -743,5 +743,23 @@ GL_APICALL void GL_APIENTRY glGetPointervANGLE (GLenum pname, void **params);
  #endif
  #endif /* GL_ANGLE_blob_cache */
  
@@ -96,7 +96,7 @@ index b258660ba4367032e592ab8d6397ee5edca0a661..fe961d3125259b015d3d005a6d45443e
          "renderbuffer": "RenderbufferID"
      },
 diff --git a/scripts/generate_entry_points.py b/scripts/generate_entry_points.py
-index c8f039000955f509402ba79927efd50d5e54af61..b5c11adbbb27d6e15ed7f0f387eab73cc376adad 100755
+index ffdbb309936a8686ac7b33dc865d42fa3919b1ff..58487e7006f9734621239084f24f400f6e1f9092 100755
 --- a/scripts/generate_entry_points.py
 +++ b/scripts/generate_entry_points.py
 @@ -999,6 +999,7 @@ FORMAT_DICT = {
@@ -165,10 +165,10 @@ index 0389244dd9232e3b4cd18bfd7d8a03721643eeb8..66dc4ec4919bacaeea23a3705e52f04d
 +    </enums>
  </registry>
 diff --git a/scripts/registry_xml.py b/scripts/registry_xml.py
-index ad05a740c3de57590780bb5a333338016439549d..698b6f78787e5b3763e1be90a9db1f945ce921ec 100644
+index 20290dfb85b24c072d509e5f9f5ee9f95802fdb2..cda20facee4b307d9b5c40a8752d61a2b5678ddf 100644
 --- a/scripts/registry_xml.py
 +++ b/scripts/registry_xml.py
-@@ -73,13 +73,14 @@ angle_requestable_extensions = [
+@@ -73,12 +73,13 @@ angle_requestable_extensions = [
      "GL_ANGLE_texture_compression_dxt5",
      "GL_ANGLE_texture_external_update",
      "GL_ANGLE_texture_multisample",
@@ -179,7 +179,6 @@ index ad05a740c3de57590780bb5a333338016439549d..698b6f78787e5b3763e1be90a9db1f94
      "GL_CHROMIUM_color_buffer_float_rgb",
      "GL_CHROMIUM_color_buffer_float_rgba",
      "GL_CHROMIUM_lose_context",
-     "GL_CHROMIUM_sync_query",
 +    "GL_WEBKIT_explicit_resolve_target",
  ]
  
@@ -346,7 +345,7 @@ index aba4c7679065ec3e56a9ba1128edeffebd8408a0..5cd749581ab62e350ce4ecedc0f954b7
              SetParamVal<ParamType::TGLbitfield>(valueIn, valueOut);
              break;
 diff --git a/src/common/gl_enum_utils_autogen.cpp b/src/common/gl_enum_utils_autogen.cpp
-index 20a9a2dbb029eeb9e1dca73ff52e054fe045d61b..ae80b96a62de6ec2a5cb6135e01d049710b5a4e5 100644
+index a5bc003ea96f15e3819b526d117e888d68b10eb6..dad677d9c72c19ab5322ac9cce1a86ae97656bb9 100644
 --- a/src/common/gl_enum_utils_autogen.cpp
 +++ b/src/common/gl_enum_utils_autogen.cpp
 @@ -2818,6 +2818,10 @@ const char *GLenumToString(GLESEnum enumGroup, unsigned int value)
@@ -360,7 +359,7 @@ index 20a9a2dbb029eeb9e1dca73ff52e054fe045d61b..ae80b96a62de6ec2a5cb6135e01d0497
                  case 0x96BE:
                      return "GL_PROGRAM_BINARY_READY_ANGLE";
                  case 0x96C0:
-@@ -22271,6 +22275,7 @@ static StringEnumEntry g_stringEnumTable[] = {
+@@ -22315,6 +22319,7 @@ static StringEnumEntry g_stringEnumTable[] = {
      {"GL_MESH_SUBROUTINE_UNIFORM_NV", 0x957E},
      {"GL_MESH_VERTICES_OUT_NV", 0x9579},
      {"GL_MESH_WORK_GROUP_SIZE_NV", 0x953E},
@@ -368,7 +367,7 @@ index 20a9a2dbb029eeb9e1dca73ff52e054fe045d61b..ae80b96a62de6ec2a5cb6135e01d0497
      {"GL_MIN", 0x8007},
      {"GL_MINMAX", 0x802E},
      {"GL_MINMAX_EXT", 0x802E},
-@@ -24922,6 +24927,7 @@ static StringEnumEntry g_stringEnumTable[] = {
+@@ -24984,6 +24989,7 @@ static StringEnumEntry g_stringEnumTable[] = {
      {"GL_VARIABLE_E_NV", 0x8527},
      {"GL_VARIABLE_F_NV", 0x8528},
      {"GL_VARIABLE_G_NV", 0x8529},
@@ -408,7 +407,7 @@ index 9600bae1a49fc9b6c409dfe311439a630b3b29f2..b66a225f407cc74f50e0be4015692a8c
  using namespace ABI::Windows::System::Threading;
  
 diff --git a/src/common/utilities.cpp b/src/common/utilities.cpp
-index 1155db6bfa8a46d4c3d2a7d765b82b397454a039..aa97c35d59b9efb291c751aff80f160b62ee1946 100644
+index 268ef72b2e82923b99b88e6e1b6d480c4d5e206a..32e264e9f3102354ccc65d8cd49453f7ac1b708e 100644
 --- a/src/common/utilities.cpp
 +++ b/src/common/utilities.cpp
 @@ -6,6 +6,12 @@
@@ -497,18 +496,6 @@ index 8d3b1c0cf16e7ad912263ca4f3b37e6f0e808523..680e5cbb38886b6915cf1a0643319bfe
  inline float fractionalPart(float f)
  {
      float intPart = 0.0f;
-diff --git a/src/compiler/translator/Types.h b/src/compiler/translator/Types.h
-index c312bcbb09583a15577186b0ec592fdf3282e722..2b889ac55672bb9eb658f83bdbb41860ef666515 100644
---- a/src/compiler/translator/Types.h
-+++ b/src/compiler/translator/Types.h
-@@ -254,6 +254,7 @@ class TType
-     }
-     bool isScalarFloat() const { return isScalar() && type == EbtFloat; }
-     bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
-+    bool isSignedInt() const { return (isScalar() || isVector()) && type == EbtInt; }
- 
-     bool canBeConstructed() const;
- 
 diff --git a/src/compiler/translator/glslang_tab_autogen.cpp b/src/compiler/translator/glslang_tab_autogen.cpp
 index 15e399b6556026a8ef7f632175607b56eefca55b..f10bb7abc48dfde26c6634daf7af9a5ad2ec1da1 100644
 --- a/src/compiler/translator/glslang_tab_autogen.cpp
@@ -536,7 +523,7 @@ index d5a48edd40f382359db76acf1a1ce75b6a6dc6d5..907c62e0bb659292b391270790498186
  
     Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
 diff --git a/src/compiler/translator/msl/EmitMetal.cpp b/src/compiler/translator/msl/EmitMetal.cpp
-index adef17611b2a32b3aeb0db799bd1da4002ce2639..2770e1e8fc30157e08fb1b4c90e54c44014c77d3 100644
+index 664e8d49b3e010011e1530371acb29088fb84964..fb37499b94687c69ce72ce7adfbd4f9cd889d9db 100644
 --- a/src/compiler/translator/msl/EmitMetal.cpp
 +++ b/src/compiler/translator/msl/EmitMetal.cpp
 @@ -181,12 +181,17 @@ class GenMetalTraverser : public TIntermTraverser
@@ -618,14 +605,10 @@ index adef17611b2a32b3aeb0db799bd1da4002ce2639..2770e1e8fc30157e08fb1b4c90e54c44
  
  void GenMetalTraverser::emitIndentation()
  {
-@@ -278,40 +321,12 @@ static const char *GetOperatorString(TOperator op,
-             return "=";
-         case TOperator::EOpInitialize:
-             return "=";
--        case TOperator::EOpAddAssign:
--            return "+=";
--        case TOperator::EOpSubAssign:
--            return "-=";
+@@ -282,16 +325,6 @@ static const char *GetOperatorString(TOperator op,
+             return resultType.isSignedInt() ? "ANGLE_addAssignInt" : "+=";
+         case TOperator::EOpSubAssign:
+             return resultType.isSignedInt() ? "ANGLE_subAssignInt" : "-=";
 -        case TOperator::EOpMulAssign:
 -            return "*=";
 -        case TOperator::EOpDivAssign:
@@ -639,13 +622,10 @@ index adef17611b2a32b3aeb0db799bd1da4002ce2639..2770e1e8fc30157e08fb1b4c90e54c44
          case TOperator::EOpBitwiseAndAssign:
              return "&=";
          case TOperator::EOpBitwiseXorAssign:
-             return "^=";
-         case TOperator::EOpBitwiseOrAssign:
-             return "|=";
--        case TOperator::EOpAdd:
--            return "+";
--        case TOperator::EOpSub:
--            return "-";
+@@ -302,16 +335,6 @@ static const char *GetOperatorString(TOperator op,
+             return resultType.isSignedInt() ? "ANGLE_addInt" : "+";
+         case TOperator::EOpSub:
+             return resultType.isSignedInt() ? "ANGLE_subInt" : "-";
 -        case TOperator::EOpMul:
 -            return "*";
 -        case TOperator::EOpDiv:
@@ -659,10 +639,10 @@ index adef17611b2a32b3aeb0db799bd1da4002ce2639..2770e1e8fc30157e08fb1b4c90e54c44
          case TOperator::EOpBitwiseAnd:
              return "&";
          case TOperator::EOpBitwiseXor:
-@@ -363,16 +378,12 @@ static const char *GetOperatorString(TOperator op,
-             return "++";
+@@ -363,16 +386,12 @@ static const char *GetOperatorString(TOperator op,
+             return resultType.isSignedInt() ? "ANGLE_preIncrementInt" : "++";
          case TOperator::EOpPreDecrement:
-             return "--";
+             return resultType.isSignedInt() ? "ANGLE_preDecrementInt" : "--";
 -        case TOperator::EOpVectorTimesScalarAssign:
 -            return "*=";
          case TOperator::EOpVectorTimesMatrixAssign:
@@ -676,7 +656,7 @@ index adef17611b2a32b3aeb0db799bd1da4002ce2639..2770e1e8fc30157e08fb1b4c90e54c44
          case TOperator::EOpVectorTimesMatrix:
              return "*";
          case TOperator::EOpMatrixTimesVector:
-@@ -386,6 +397,38 @@ static const char *GetOperatorString(TOperator op,
+@@ -386,6 +405,30 @@ static const char *GetOperatorString(TOperator op,
          case TOperator::EOpNotEqualComponentWise:
              return "!=";
  
@@ -690,14 +670,6 @@ index adef17611b2a32b3aeb0db799bd1da4002ce2639..2770e1e8fc30157e08fb1b4c90e54c44
 +            // TODO: Check logical vs arithmetic shifting.
 +            return resultType.isSignedInt() ? "ANGLE_ilshift" : "ANGLE_ulshift";
 +
-+        case TOperator::EOpAddAssign:
-+        case TOperator::EOpAdd:
-+            return resultType.isSignedInt() ? "ANGLE_iadd" : "+";
-+
-+        case TOperator::EOpSubAssign:
-+        case TOperator::EOpSub:
-+            return resultType.isSignedInt() ? "ANGLE_isub" : "-";
-+
 +        case TOperator::EOpMulAssign:
 +        case TOperator::EOpMul:
 +        case TOperator::EOpVectorTimesScalarAssign:
@@ -756,10 +728,11 @@ index adef17611b2a32b3aeb0db799bd1da4002ce2639..2770e1e8fc30157e08fb1b4c90e54c44
          default:
          {
              const TType &resultType = binaryNode->getType();
-@@ -2249,7 +2301,27 @@ bool GenMetalTraverser::visitAggregate(Visit, TIntermAggregate *aggregateNode)
+@@ -2248,8 +2300,28 @@ bool GenMetalTraverser::visitAggregate(Visit, TIntermAggregate *aggregateNode)
+             emitArgList("{", "}");
          }
          else
-         {
++        {
 +            bool isFtoi = [&]() {
 +                if ((!retType.isScalar() && !retType.isVector()) ||
 +                    !IsInteger(retType.getBasicType()))
@@ -774,12 +747,12 @@ index adef17611b2a32b3aeb0db799bd1da4002ce2639..2770e1e8fc30157e08fb1b4c90e54c44
 +            if (isFtoi)
 +            {
 +                mOut << "ANGLE_ftoi<";
-                 emitType(retType, etConfig);
++                emitType(retType, etConfig);
 +                mOut << ">";
 +            }
 +            else
-+            {
-+                emitType(retType, etConfig);
+             {
+                 emitType(retType, etConfig);
 +            }
              emitArgList("(", ")");
          }
@@ -837,18 +810,16 @@ index adef17611b2a32b3aeb0db799bd1da4002ce2639..2770e1e8fc30157e08fb1b4c90e54c44
      mOut << "do\n";
      emitLoopBody(loopNode->getBody());
 diff --git a/src/compiler/translator/msl/ProgramPrelude.cpp b/src/compiler/translator/msl/ProgramPrelude.cpp
-index ec117053caf8ef376f0f5e27729b46964c6a2d26..bdb6f98f3e11f7e6e911ebc3da11e89c9fc1b648 100644
+index 90a8bca03b4488543bfe474a5a54bc22d42e65df..eddb10cf7f74a04cdd03dac74ee37266488dfe82 100644
 --- a/src/compiler/translator/msl/ProgramPrelude.cpp
 +++ b/src/compiler/translator/msl/ProgramPrelude.cpp
-@@ -113,6 +113,15 @@ class ProgramPrelude : public TIntermTraverser
+@@ -113,6 +113,13 @@ class ProgramPrelude : public TIntermTraverser
      void degrees();
      void radians();
      void mod();
 +    void div();
 +    void imod();
 +    void imul();
-+    void iadd();
-+    void isub();
 +    void ilshift();
 +    void ulshift();
 +    void rshift();
@@ -856,7 +827,7 @@ index ec117053caf8ef376f0f5e27729b46964c6a2d26..bdb6f98f3e11f7e6e911ebc3da11e89c
      void mixBool();
      void postIncrementMatrix();
      void preIncrementMatrix();
-@@ -431,6 +440,136 @@ ANGLE_ALWAYS_INLINE X ANGLE_mod(X x, Y y)
+@@ -439,6 +446,116 @@ ANGLE_ALWAYS_INLINE X ANGLE_mod(X x, Y y)
  }
  )")
  
@@ -933,26 +904,6 @@ index ec117053caf8ef376f0f5e27729b46964c6a2d26..bdb6f98f3e11f7e6e911ebc3da11e89c
 +}
 +)")
 +
-+// Avoid undefined behavior due to integer overflow
-+PROGRAM_PRELUDE_DECLARE(iadd,
-+                        R"(
-+template<typename X, typename Y, typename Z = metal::conditional_t<metal::is_scalar_v<Y>, X, Y>>
-+ANGLE_ALWAYS_INLINE Z ANGLE_iadd(X x, Y y)
-+{
-+    return as_type<Z>(metal::make_unsigned_t<Z>(x) + metal::make_unsigned_t<Z>(y));
-+}
-+)")
-+
-+// Avoid undefined behavior due to integer underflow
-+PROGRAM_PRELUDE_DECLARE(isub,
-+                        R"(
-+template<typename X, typename Y, typename Z = metal::conditional_t<metal::is_scalar_v<Y>, X, Y>>
-+ANGLE_ALWAYS_INLINE Z ANGLE_isub(X x, Y y)
-+{
-+    return as_type<Z>(metal::make_unsigned_t<Z>(x) - metal::make_unsigned_t<Z>(y));
-+}
-+)")
-+
 +// Avoid undefined behavior in e1 << e2 when:
 +// 1) e2 is larger than the bit width of the type
 +// 2) e2 is a negative value.
@@ -993,7 +944,7 @@ index ec117053caf8ef376f0f5e27729b46964c6a2d26..bdb6f98f3e11f7e6e911ebc3da11e89c
  PROGRAM_PRELUDE_DECLARE(mixBool,
                          R"(
  template <typename T, int N>
-@@ -3279,6 +3418,10 @@ void ProgramPrelude::visitOperator(TOperator op,
+@@ -3371,6 +3488,10 @@ void ProgramPrelude::visitOperator(TOperator op,
          case TOperator::EOpMod:
              mod();
              break;
@@ -1004,63 +955,30 @@ index ec117053caf8ef376f0f5e27729b46964c6a2d26..bdb6f98f3e11f7e6e911ebc3da11e89c
          case TOperator::EOpRefract:
              if (argType0->isScalar())
              {
-@@ -3422,6 +3565,7 @@ void ProgramPrelude::visitOperator(TOperator op,
-             break;
- 
-         case TOperator::EOpAdd:
-+        case TOperator::EOpAddAssign:
-             if (argType0->isMatrix() && argType1->isScalar())
-             {
-                 addMatrixScalar();
... (file diff truncated)
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/Source/ThirdParty/ANGLE/src/tests/BUILD.gn b/Source/ThirdParty/ANGLE/src/tests/BUILD.gn
index 11733c50384d..bff2b7e04a8f 100644
--- a/Source/ThirdParty/ANGLE/src/tests/BUILD.gn
+++ b/Source/ThirdParty/ANGLE/src/tests/BUILD.gn
@@ -377,6 +377,15 @@ if (is_win || is_linux || is_chromeos || is_android || is_fuchsia || is_apple) {
       # Need to bundle the libraries inside the .app.
       deps += [ "$angle_root:angle" ]
     }
+
+    if (angle_enable_wgpu) {
+      deps += [
+        "${angle_dawn_dir}/include/dawn:headers",
+        "${angle_dawn_dir}/src/dawn:proc",
+        "${angle_dawn_dir}/src/dawn/native",
+      ]
+      defines += [ "ANGLE_ENABLE_WGPU" ]
+    }
   }
 }
 
@@ -1346,10 +1355,7 @@ if (build_angle_deqp_tests && !is_fuchsia) {
     if (is_android) {
       include_dirs += [ "$deqp_path/framework/platform/android" ]
 
-      _android_api = android64_ndk_api_level
-      if (!angle_64bit_current_cpu) {
-        _android_api = android32_ndk_api_level
-      }
+      _android_api = android_ndk_api_level
 
       defines += [ "DE_ANDROID_API=" + "${_android_api}" ]
     }
@@ -1756,6 +1762,11 @@ if (build_angle_deqp_tests && !is_fuchsia) {
       ":angle_deqp_framework_egl",
       ":angle_deqp_glshared",
     ]
+
+    # TODO(http://anglebug.com/420728429): It should be removed once the issue is resolved on the CTS code.
+    if (is_clang) {
+      cflags_cc = [ "-Wno-unused-private-field" ]
+    }
   }
 
   angle_deqp_source_set("angle_deqp_gles3_common") {
@@ -1772,6 +1783,11 @@ if (build_angle_deqp_tests && !is_fuchsia) {
       ":angle_deqp_framework_egl",
       ":angle_deqp_glshared",
     ]
+
+    # TODO(http://anglebug.com/420728429): It should be removed once the issue is resolved on the CTS code.
+    if (is_clang) {
+      cflags_cc = [ "-Wno-unused-private-field" ]
+    }
   }
 
   template("angle_deqp_core_gtest") {
diff --git a/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni b/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni
index b3fdc71cb783..a46514a9f1da 100644
--- a/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni
+++ b/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests.gni
@@ -90,6 +90,7 @@ angle_end2end_tests_sources = [
   "gl_tests/FramebufferResolveTest.cpp",
   "gl_tests/FramebufferTest.cpp",
   "gl_tests/GLSLTest.cpp",
+  "gl_tests/GLSLUBTest.cpp",
   "gl_tests/GeometryShaderTest.cpp",
   "gl_tests/GetImageTest.cpp",
   "gl_tests/GetTexLevelParameterTest.cpp",
@@ -160,7 +161,6 @@ angle_end2end_tests_sources = [
   "gl_tests/SixteenBppTextureTest.cpp",
   "gl_tests/StateChangeTest.cpp",
   "gl_tests/SwizzleTest.cpp",
-  "gl_tests/SyncQueriesTest.cpp",
   "gl_tests/TextureExternalUpdateTest.cpp",
   "gl_tests/TextureFixedRateCompressionTest.cpp",
   "gl_tests/TextureMultisampleTest.cpp",
diff --git a/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt b/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt
index c7be7c8c794d..85ac5ee6bcd6 100644
--- a/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt
+++ b/Source/ThirdParty/ANGLE/src/tests/angle_end2end_tests_expectations.txt
@@ -1634,6 +1634,11 @@ b/292285899 PIXEL4ORXL GLES : EGLSurfaceTest.DestroyAndRecreateWhileCurrent/* =
 389145696 WGPU MAC NVIDIA : BasicSamplersTest* = SKIP
 389145696 WGPU MAC NVIDIA : SampleFromRenderedTextureTest* = SKIP
 389145696 WGPU MAC NVIDIA : Texture2DTest.*Multiple* = SKIP
+389145696 WGPU MAC NVIDIA : ImageTest* = SKIP
+// Unimplemented cube map and non-zero mipmap EGLImages
+418022112 WGPU : ImageTest.MipLevels/* = SKIP
+418022112 WGPU : ImageTest.RespecificationOfOtherLevel/* = SKIP
+418022112 WGPU : ImageTest.SourceCubeAndSameTargetTextureWithEachCubeFace/* = SKIP
 
 // SPIR-V compilation error
 384593678 VULKAN : SimpleUniformUsageTestES3.CopyOfUniformsWithArrays/* = SKIP
@@ -1695,7 +1700,6 @@ b/292285899 PIXEL4ORXL GLES : EGLSurfaceTest.DestroyAndRecreateWhileCurrent/* =
 404958320 WIN NVIDIA VULKAN : BlitFramebufferTest.BlitSmallColorLargeDepthAttachments/* = SKIP
 
 // EGLImage colorspace renderbuffer failures on NVIDIA, INTEL and ANDROID
-40644776 D3D11                : ImageTest.SourceRenderbufferTargetTexture* = SKIP
 40644776 D3D11                : ImageTestES3.SourceRenderbufferTargetTextureExternalESSL3* = SKIP
 40644776 WIN INTEL VULKAN     : ImageTest.SourceRenderbufferTargetTexture* = SKIP
 40644776 WIN INTEL VULKAN     : ImageTestES3.SourceRenderbufferTargetTextureExternalESSL3* = SKIP
@@ -1758,6 +1762,9 @@ b/292285899 PIXEL4ORXL GLES : EGLSurfaceTest.DestroyAndRecreateWhileCurrent/* =
 351867710 NVIDIA VULKAN : CopyImageTestES31.CompressedToNorm16/* = SKIP
 351867710 NVIDIA VULKAN : CopyImageTestES31.Norm16ToCompressed/* = SKIP
 
+// Pixel4's GLES driver fails new test: TransformFeedbackTest.CaptureThenUseAsUBO.
+419403192 PIXEL4ORXL GLES : TransformFeedbackTest.CaptureThenUseAsUBO/* = SKIP
+
 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 // Slow tests, should appear last in this file
 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/Source/ThirdParty/ANGLE/src/tests/compiler_tests/Parse_test.cpp b/Source/ThirdParty/ANGLE/src/tests/compiler_tests/Parse_test.cpp
index f9198e937ad8..dc12840a18aa 100644
--- a/Source/ThirdParty/ANGLE/src/tests/compiler_tests/Parse_test.cpp
+++ b/Source/ThirdParty/ANGLE/src/tests/compiler_tests/Parse_test.cpp
@@ -125,6 +125,100 @@ void main() { }
     EXPECT_TRUE(foundInIntermediateTree("'index' : invalid layout qualifier"));
 }
 
+// Test that with the conservative depth extension, gl_FragDepth
+// can be redeclared successfully.
+TEST_F(ParseTest, RedeclareFragDepthSuccess)
+{
+    mShaderSpec                       = SH_WEBGL2_SPEC;
+    mResources.EXT_conservative_depth = 1;
+    mCompileOptions.validateAST       = 1;
+    const char kShader[]              = R"(#version 300 es
+#extension GL_EXT_conservative_depth: enable
+precision mediump float;
+layout (depth_any) out float gl_FragDepth;
+void main() {
+}
+)";
+    EXPECT_TRUE(compile(kShader));
+}
+
+// Test that without the conservative depth extension, gl_FragDepth,
+// cannot be redeclared.
+TEST_F(ParseTest, RedeclareFragDepthNoExtFail)
+{
+    mShaderSpec                       = SH_WEBGL2_SPEC;
+    mResources.EXT_conservative_depth = 1;
+    mCompileOptions.validateAST       = 1;
+    const char kShader[]              = R"(#version 300 es
+precision mediump float;
+layout (depth_any) out float gl_FragDepth;
+void main() {
+}
+)";
+    EXPECT_FALSE(compile(kShader));
+    EXPECT_TRUE(foundErrorInIntermediateTree());
+    EXPECT_TRUE(foundInIntermediateTree("reserved built-in name"));
+}
+
+// Test that even with the conservative depth extension, gl_FragDepth
+// cannot be redeclared locally.
+TEST_F(ParseTest, RedeclareFragDepthLocallyFail)
+{
+    mShaderSpec                       = SH_WEBGL2_SPEC;
+    mResources.EXT_conservative_depth = 1;
+    mCompileOptions.validateAST       = 1;
+    const char kShader[]              = R"(#version 300 es
+#extension GL_EXT_conservative_depth: enable
+precision mediump float;
+void main() {
+    layout (depth_any) out float gl_FragDepth;
+}
+)";
+    EXPECT_FALSE(compile(kShader));
+    EXPECT_TRUE(foundErrorInIntermediateTree());
+    EXPECT_TRUE(foundInIntermediateTree("gl_FragDepth can only be redeclared as fragment output"));
+}
+
+// Test that with the conservative depth extension, gl_FragDepth
+// can only be redeclared once.
+TEST_F(ParseTest, RedeclareFragDepthTwiceFail)
+{
+    mShaderSpec                       = SH_WEBGL2_SPEC;
+    mResources.EXT_conservative_depth = 1;
+    mCompileOptions.validateAST       = 1;
+    const char kShader[]              = R"(#version 300 es
+#extension GL_EXT_conservative_depth: enable
+precision mediump float;
+layout (depth_any) out float gl_FragDepth;
+layout (depth_any) out float gl_FragDepth;
+void main() {
+}
+)";
+    EXPECT_FALSE(compile(kShader));
+    EXPECT_TRUE(foundErrorInIntermediateTree());
+    EXPECT_TRUE(foundInIntermediateTree("redefinition"));
+}
+
+// Test that with the conservative depth extension gl_FragDepth
+// can only be redeclared globally.
+TEST_F(ParseTest, RedeclareFragDepthGlobalAndLocalFail)
+{
+    mShaderSpec                       = SH_WEBGL2_SPEC;
+    mResources.EXT_conservative_depth = 1;
+    mCompileOptions.validateAST       = 1;
+    const char kShader[]              = R"(#version 300 es
+#extension GL_EXT_conservative_depth: enable
+precision mediump float;
+layout (depth_any) out float gl_FragDepth;
+void main() {
+    float gl_FragDepth = 1.0;
+}
+)";
+    EXPECT_FALSE(compile(kShader));
+    EXPECT_TRUE(foundErrorInIntermediateTree());
+    EXPECT_TRUE(foundInIntermediateTree("reserved built-in name"));
+}
+
 TEST_F(ParseTest, Radians320NoCrash)
 {
     const char kShader[] = R"(#version 320 es
diff --git a/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp.gni b/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp.gni
index 0c6a87a24dd7..b58b933d1964 100644
--- a/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp.gni
+++ b/Source/ThirdParty/ANGLE/src/tests/deqp_support/deqp.gni
@@ -1111,6 +1111,8 @@ deqp_khr_gl_sources = [
   "$deqp_path/external/openglcts/modules/gl/gl4cComputeShaderTests.hpp",
   "$deqp_path/external/openglcts/modules/gl/gl4cConditionalRenderInvertedTests.cpp",
   "$deqp_path/external/openglcts/modules/gl/gl4cConditionalRenderInvertedTests.hpp",
+  "$deqp_path/external/openglcts/modules/gl/gl4cTextureBufferTests.cpp",
+  "$deqp_path/external/openglcts/modules/gl/gl4cTextureBufferTests.hpp",
 
   # These tests are also disabled in the dEQP CMake build.
   # "$deqp_path/external/openglcts/modules/gl/gl4cContextFlushControlTests.cpp",
diff --git a/Source/ThirdParty/ANGLE/src/tests/gl_tests/ClearTest.cpp b/Source/ThirdParty/ANGLE/src/tests/gl_tests/ClearTest.cpp
index 7c17360714c4..502c3d5a3ac9 100644
--- a/Source/ThirdParty/ANGLE/src/tests/gl_tests/ClearTest.cpp
+++ b/Source/ThirdParty/ANGLE/src/tests/gl_tests/ClearTest.cpp
@@ -118,8 +118,27 @@ class ClearTestES3 : public ClearTestBase
             glDepthMask(GL_FALSE);
         }
         glDepthFunc(GL_LESS);
-        drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), depthValue * 2 - 1 - 0.01f);
-        drawQuad(depthTestProgramFail, essl1_shaders::PositionAttrib(), depthValue * 2 - 1 + 0.01f);
+
+        GLfloat normalizedDepth = depthValue * 2 - 1;
+
+        // A depth value clamped to 0.0 will be normalized to -1.0. In this case, clear the color
+        // buffer to blue and then attempt to draw red only. Otherwise, attempt to draw blue and
+        // red.
+        if (normalizedDepth < -0.999999f)
+        {
+            glClearColor(0.0, 0.0, 1.0, 1.0);
+            glClear(GL_COLOR_BUFFER_BIT);
+            GLfloat redNormalizedDepth = normalizedDepth + 0.01f;
+            drawQuad(depthTestProgramFail, essl1_shaders::PositionAttrib(), redNormalizedDepth);
+        }
+        else
+        {
+            GLfloat blueNormalizedDepth = normalizedDepth - 0.01f;
+            GLfloat redNormalizedDepth  = normalizedDepth + 0.01f;
+            drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), blueNormalizedDepth);
+            drawQuad(depthTestProgramFail, essl1_shaders::PositionAttrib(), redNormalizedDepth);
+        }
+
         if (!hasDepthTest)
         {
             glDisable(GL_DEPTH_TEST);
@@ -4216,6 +4235,60 @@ TEST_P(ClearTestES3, RepeatedDepthClear)
     ASSERT_GL_NO_ERROR();
 }
 
+// Tests that calls to glClearBufferfi clamp the depth value.
+TEST_P(ClearTestES3, ClampDepthClearBufferfi)
+{
+    glClearBufferfi(GL_DEPTH_STENCIL, 0, -0.01f, 0x55);
+    verifyDepth(0.00f, 1);
+
+    glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.00f, 0x55);
+    verifyDepth(0.00f, 1);
+
+    glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.01f, 0x55);
+    verifyDepth(0.01f, 1);
+
+    glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.99f, 0x55);
+    verifyDepth(0.99f, 1);
+
+    glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.00f, 0x55);
+    verifyDepth(1.00f, 1);
+
+    glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.01f, 0x55);
+    verifyDepth(1.0f, 1);
+
+    ASSERT_GL_NO_ERROR();
+}
+
+// Tests that calls to glClearBufferfv clamp the depth value.
+TEST_P(ClearTestES3, ClampDepthClearBufferfv)
+{
+    float depthClearValue = -0.01f;
+    glClearBufferfv(GL_DEPTH, 0, &depthClearValue);
+    verifyDepth(0.00f, 1);
+
+    depthClearValue = 0.00f;
+    glClearBufferfv(GL_DEPTH, 0, &depthClearValue);
+    verifyDepth(0.00f, 1);
... (truncated)
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker.