#6129·wails

[v3] ICoreWebView2_N vtable structs in pkg/webview2 omit the inherited method chain, so calls hit the wrong slot

Author: 111111comonCreated Sep 16, 2026Updated Sep 16, 2026
LabelsBugv3

Description

In internal/webview2/pkg/webview2/, the vtable structs for the derived ICoreWebView2_N interfaces embed only IUnknownVtbl plus the methods that interface adds, omitting the inherited chain. A COM vtable contains every inherited method, so calling through these structs lands on the wrong slot.

Example — ICoreWebView2_22.go:

go
type ICoreWebView2_22Vtbl struct {
	IUnknownVtbl
	AddWebResourceRequestedFilterWithRequestSourceKinds    ComProc
	RemoveWebResourceRequestedFilterWithRequestSourceKinds ComProc
}

AddWebResourceRequestedFilterWithRequestSourceKinds therefore resolves to vtable slot 3, which is ICoreWebView2::get_Settings. The real slot is 123:

3   IUnknown
+58 ICoreWebView2
+ 7 ICoreWebView2_2      = 68
+ 5 ICoreWebView2_3      = 73
+ 4 _4, +2 _5, +1 _6, +1 _7, +7 _8, +9 _9, +2 _10, +3 _11, +3 _12,
+ 1 _13, +3 _14, +4 _15, +3 _16, +1 _17, +2 _18, +2 _19, +1 _20, +1 _21
                         = 123
+ 2 ICoreWebView2_22     = 125 slots total

The 68 cross-checks against internal/webview2/pkg/edge/ICoreWebView2_2.go, whose iCoreWebView2_2Vtbl does build the chain properly and has exactly 68 ComProc fields. The five _3 methods likewise land at slots 69–73 in both.

The same shape appears in the other ICoreWebView2_N.go files in that package (_4_23), and in some of the sibling interface files.

Impact

As far as I can tell this package is not on the runtime path today (pkg/edge is what pkg/application uses, and its _2/_3 vtables are correct), so nothing is broken for users right now. But anyone calling into these helpers gets a silent wrong-function call rather than an error.

I hit this while patching a local copy to test AddWebResourceRequestedFilterWithRequestSourceKinds: my first attempt copied this vtable shape, which called get_Settings with the filter arguments and left the asset server serving nothing, with no error anywhere. Rebuilding the full 125-slot vtable fixed the call.

Suggestion

Either build the inheritance chain the way pkg/edge does (embed the parent vtable struct), or generate these files with the chain included. A cheap guard while doing so: call a known inherited method (e.g. get_Settings) after QueryInterface and check it returns S_OK with a non-null out-param.

Found on v3.0.0-beta.22.