detached 9803305

fix: prevent SIGABRT crash on permission-request signal

Bump puregotk-webkit to v0.0.14 which registers the missing
DeviceInfoPermissionRequest GType function pointer. Without this, any
page calling navigator.mediaDevices.enumerateDevices() triggered a nil
function panic converted to SIGABRT by debug.SetTraceback("crash").

Also add safeGLibType() defensive wrapper around GType lookups in
detectPermissionRequestKind so future unregistered types degrade
gracefully instead of crashing.
commit
98033054f5e5e58e9fd498adc1902827ae93a42e
author
brice · · 2026-03-06 05:55 UTC
parent
3458ddd
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
3 files · +24 -5
M go.mod +1 -1
@@ -3,7 +3,7 @@ module github.com/bnema/dumber
33 go 1.26
44
55 require (
6- github.com/bnema/puregotk-webkit v0.0.13
6+ github.com/bnema/puregotk-webkit v0.0.14
77 github.com/charmbracelet/bubbles v1.0.0
88 github.com/charmbracelet/bubbletea v1.3.10
99 github.com/charmbracelet/lipgloss v1.1.0
@@ -3,7 +3,7 @@ module github.com/bnema/dumber
3 go 1.263 go 1.26
4 4
5 require (5 require (
6- github.com/bnema/puregotk-webkit v0.0.136+ github.com/bnema/puregotk-webkit v0.0.14
7 github.com/charmbracelet/bubbles v1.0.07 github.com/charmbracelet/bubbles v1.0.0
8 github.com/charmbracelet/bubbletea v1.3.108 github.com/charmbracelet/bubbletea v1.3.10
9 github.com/charmbracelet/lipgloss v1.1.09 github.com/charmbracelet/lipgloss v1.1.0
M go.sum +2 -0 generated file: collapsed
M internal/infrastructure/webkit/webview.go +21 -4
@@ -1092,15 +1092,32 @@ const (
10921092 )
10931093
10941094 func detectPermissionRequestKind(ctx context.Context, requestPtr uintptr) permissionRequestKind {
1095- if isPermissionRequestType(ctx, requestPtr, webkit.UserMediaPermissionRequestGLibType()) {
1096- return permissionRequestKindUserMedia
1095+ if gtype, ok := safeGLibType(webkit.UserMediaPermissionRequestGLibType); ok {
1096+ if isPermissionRequestType(ctx, requestPtr, gtype) {
1097+ return permissionRequestKindUserMedia
1098+ }
10971099 }
1098- if isPermissionRequestType(ctx, requestPtr, webkit.DeviceInfoPermissionRequestGLibType()) {
1099- return permissionRequestKindDeviceInfo
1100+ if gtype, ok := safeGLibType(webkit.DeviceInfoPermissionRequestGLibType); ok {
1101+ if isPermissionRequestType(ctx, requestPtr, gtype) {
1102+ return permissionRequestKindDeviceInfo
1103+ }
11001104 }
11011105 return permissionRequestKindUnknown
11021106 }
11031107
1108+// safeGLibType calls a GType accessor function, recovering from panics caused
1109+// by unregistered (nil) puregotk function pointers. Returns the GType and true
1110+// on success, or zero and false if the call panicked.
1111+func safeGLibType(fn func() gtypes.GType) (gtype gtypes.GType, ok bool) {
1112+ defer func() {
1113+ if r := recover(); r != nil {
1114+ gtype = 0
1115+ ok = false
1116+ }
1117+ }()
1118+ return fn(), true
1119+}
1120+
11041121 func isPermissionRequestType(ctx context.Context, requestPtr uintptr, requestType gtypes.GType) bool {
11051122 return gobjectTypeCheckInstanceIsAByPtr(ctx, requestPtr, requestType)
11061123 }
@@ -1092,15 +1092,32 @@ const (
1092 )1092 )
1093 1093
1094 func detectPermissionRequestKind(ctx context.Context, requestPtr uintptr) permissionRequestKind {1094 func detectPermissionRequestKind(ctx context.Context, requestPtr uintptr) permissionRequestKind {
1095- if isPermissionRequestType(ctx, requestPtr, webkit.UserMediaPermissionRequestGLibType()) {1095+ if gtype, ok := safeGLibType(webkit.UserMediaPermissionRequestGLibType); ok {
1096- return permissionRequestKindUserMedia1096+ if isPermissionRequestType(ctx, requestPtr, gtype) {
1097+ return permissionRequestKindUserMedia
1098+ }
1097 }1099 }
1098- if isPermissionRequestType(ctx, requestPtr, webkit.DeviceInfoPermissionRequestGLibType()) {1100+ if gtype, ok := safeGLibType(webkit.DeviceInfoPermissionRequestGLibType); ok {
1099- return permissionRequestKindDeviceInfo1101+ if isPermissionRequestType(ctx, requestPtr, gtype) {
1102+ return permissionRequestKindDeviceInfo
1103+ }
1100 }1104 }
1101 return permissionRequestKindUnknown1105 return permissionRequestKindUnknown
1102 }1106 }
1103 1107
1108+// safeGLibType calls a GType accessor function, recovering from panics caused
1109+// by unregistered (nil) puregotk function pointers. Returns the GType and true
1110+// on success, or zero and false if the call panicked.
1111+func safeGLibType(fn func() gtypes.GType) (gtype gtypes.GType, ok bool) {
1112+ defer func() {
1113+ if r := recover(); r != nil {
1114+ gtype = 0
1115+ ok = false
1116+ }
1117+ }()
1118+ return fn(), true
1119+}
1120+
1104 func isPermissionRequestType(ctx context.Context, requestPtr uintptr, requestType gtypes.GType) bool {1121 func isPermissionRequestType(ctx context.Context, requestPtr uintptr, requestType gtypes.GType) bool {
1105 return gobjectTypeCheckInstanceIsAByPtr(ctx, requestPtr, requestType)1122 return gobjectTypeCheckInstanceIsAByPtr(ctx, requestPtr, requestType)
1106 }1123 }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close