Merge pull request #184 from bnema/fix/permission-request-crash
fix: prevent SIGABRT crash on permission-request signal
3 files · +28 -5
M go.mod +1 -1
| @@ -3,7 +3,7 @@ module github.com/bnema/dumber | |||
| 3 | 3 | go 1.26 | |
| 4 | 4 | ||
| 5 | 5 | require ( | |
| 6 | - | github.com/bnema/puregotk-webkit v0.0.13 | |
| 6 | + | github.com/bnema/puregotk-webkit v0.0.14 | |
| 7 | 7 | github.com/charmbracelet/bubbles v1.0.0 | |
| 8 | 8 | github.com/charmbracelet/bubbletea v1.3.10 | |
| 9 | 9 | github.com/charmbracelet/lipgloss v1.1.0 | |
| @@ -3,7 +3,7 @@ module github.com/bnema/dumber | |||||
| 3 | go 1.26 | 3 | go 1.26 | ||
| 4 | 4 | ||||
| 5 | require ( | 5 | require ( | ||
| 6 | - | github.com/bnema/puregotk-webkit v0.0.13 | 6 | + | github.com/bnema/puregotk-webkit v0.0.14 |
| 7 | github.com/charmbracelet/bubbles v1.0.0 | 7 | github.com/charmbracelet/bubbles v1.0.0 | ||
| 8 | github.com/charmbracelet/bubbletea v1.3.10 | 8 | github.com/charmbracelet/bubbletea v1.3.10 | ||
| 9 | github.com/charmbracelet/lipgloss v1.1.0 | 9 | github.com/charmbracelet/lipgloss v1.1.0 | ||
M go.sum +2 -0
| @@ -8,6 +8,8 @@ github.com/bnema/puregotk v0.1.0 h1:fNdoWi0wAEk5/rfwtpSeQuuB4AgAxkpiPPlivXXQk3I= | |||
| 8 | 8 | github.com/bnema/puregotk v0.1.0/go.mod h1:mZu8qSvCSqtVL+xoiebZuicnJijwrLfGRs6/eTVgFlc= | |
| 9 | 9 | github.com/bnema/puregotk-webkit v0.0.13 h1:0j99i2a7GPhCQiIaV2LQ4n2p3Tw0q//V/CccDDU4M3A= | |
| 10 | 10 | github.com/bnema/puregotk-webkit v0.0.13/go.mod h1:wc+zzGdAy51YgyG1N3iwkQIusgCY4lFHGJUQgi4svJ0= | |
| 11 | + | github.com/bnema/puregotk-webkit v0.0.14 h1:fwJ9fE3UKWQ8+VWFueddtfLMvcmO3EvfieIX/AYgHhY= | |
| 12 | + | github.com/bnema/puregotk-webkit v0.0.14/go.mod h1:wc+zzGdAy51YgyG1N3iwkQIusgCY4lFHGJUQgi4svJ0= | |
| 11 | 13 | github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc= | |
| 12 | 14 | github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E= | |
| 13 | 15 | github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= | |
| @@ -8,6 +8,8 @@ github.com/bnema/puregotk v0.1.0 h1:fNdoWi0wAEk5/rfwtpSeQuuB4AgAxkpiPPlivXXQk3I= | |||||
| 8 | github.com/bnema/puregotk v0.1.0/go.mod h1:mZu8qSvCSqtVL+xoiebZuicnJijwrLfGRs6/eTVgFlc= | 8 | github.com/bnema/puregotk v0.1.0/go.mod h1:mZu8qSvCSqtVL+xoiebZuicnJijwrLfGRs6/eTVgFlc= | ||
| 9 | github.com/bnema/puregotk-webkit v0.0.13 h1:0j99i2a7GPhCQiIaV2LQ4n2p3Tw0q//V/CccDDU4M3A= | 9 | github.com/bnema/puregotk-webkit v0.0.13 h1:0j99i2a7GPhCQiIaV2LQ4n2p3Tw0q//V/CccDDU4M3A= | ||
| 10 | github.com/bnema/puregotk-webkit v0.0.13/go.mod h1:wc+zzGdAy51YgyG1N3iwkQIusgCY4lFHGJUQgi4svJ0= | 10 | github.com/bnema/puregotk-webkit v0.0.13/go.mod h1:wc+zzGdAy51YgyG1N3iwkQIusgCY4lFHGJUQgi4svJ0= | ||
| 11 | + | github.com/bnema/puregotk-webkit v0.0.14 h1:fwJ9fE3UKWQ8+VWFueddtfLMvcmO3EvfieIX/AYgHhY= | |||
| 12 | + | github.com/bnema/puregotk-webkit v0.0.14/go.mod h1:wc+zzGdAy51YgyG1N3iwkQIusgCY4lFHGJUQgi4svJ0= | |||
| 11 | github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc= | 13 | github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc= | ||
| 12 | github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E= | 14 | github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E= | ||
| 13 | github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= | 15 | github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= | ||
M internal/infrastructure/webkit/webview.go +25 -4
| @@ -1092,15 +1092,36 @@ const ( | |||
| 1092 | 1092 | ) | |
| 1093 | 1093 | ||
| 1094 | 1094 | func detectPermissionRequestKind(ctx context.Context, requestPtr uintptr) permissionRequestKind { | |
| 1095 | - | if isPermissionRequestType(ctx, requestPtr, webkit.UserMediaPermissionRequestGLibType()) { | |
| 1096 | - | return permissionRequestKindUserMedia | |
| 1095 | + | if gtype, ok := safeGLibType(ctx, webkit.UserMediaPermissionRequestGLibType); ok { | |
| 1096 | + | if isPermissionRequestType(ctx, requestPtr, gtype) { | |
| 1097 | + | return permissionRequestKindUserMedia | |
| 1098 | + | } | |
| 1097 | 1099 | } | |
| 1098 | - | if isPermissionRequestType(ctx, requestPtr, webkit.DeviceInfoPermissionRequestGLibType()) { | |
| 1099 | - | return permissionRequestKindDeviceInfo | |
| 1100 | + | if gtype, ok := safeGLibType(ctx, webkit.DeviceInfoPermissionRequestGLibType); ok { | |
| 1101 | + | if isPermissionRequestType(ctx, requestPtr, gtype) { | |
| 1102 | + | return permissionRequestKindDeviceInfo | |
| 1103 | + | } | |
| 1100 | 1104 | } | |
| 1101 | 1105 | 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(ctx context.Context, fn func() gtypes.GType) (gtype gtypes.GType, ok bool) { | |
| 1112 | + | defer func() { | |
| 1113 | + | if r := recover(); r != nil { | |
| 1114 | + | logging.FromContext(ctx).Warn(). | |
| 1115 | + | Str("component", "permission"). | |
| 1116 | + | Interface("panic", r). | |
| 1117 | + | Msg("GType accessor panicked (unregistered puregotk binding?)") | |
| 1118 | + | gtype = 0 | |
| 1119 | + | ok = false | |
| 1120 | + | } | |
| 1121 | + | }() | |
| 1122 | + | return fn(), true | |
| 1123 | + | } | |
| 1124 | + | ||
| 1104 | 1125 | func isPermissionRequestType(ctx context.Context, requestPtr uintptr, requestType gtypes.GType) bool { | |
| 1105 | 1126 | return gobjectTypeCheckInstanceIsAByPtr(ctx, requestPtr, requestType) | |
| 1106 | 1127 | } | |
| @@ -1092,15 +1092,36 @@ 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(ctx, webkit.UserMediaPermissionRequestGLibType); ok { |
| 1096 | - | return permissionRequestKindUserMedia | 1096 | + | if isPermissionRequestType(ctx, requestPtr, gtype) { |
| 1097 | + | return permissionRequestKindUserMedia | |||
| 1098 | + | } | |||
| 1097 | } | 1099 | } | ||
| 1098 | - | if isPermissionRequestType(ctx, requestPtr, webkit.DeviceInfoPermissionRequestGLibType()) { | 1100 | + | if gtype, ok := safeGLibType(ctx, webkit.DeviceInfoPermissionRequestGLibType); ok { |
| 1099 | - | return permissionRequestKindDeviceInfo | 1101 | + | if isPermissionRequestType(ctx, requestPtr, gtype) { |
| 1102 | + | return permissionRequestKindDeviceInfo | |||
| 1103 | + | } | |||
| 1100 | } | 1104 | } | ||
| 1101 | return permissionRequestKindUnknown | 1105 | 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(ctx context.Context, fn func() gtypes.GType) (gtype gtypes.GType, ok bool) { | |||
| 1112 | + | defer func() { | |||
| 1113 | + | if r := recover(); r != nil { | |||
| 1114 | + | logging.FromContext(ctx).Warn(). | |||
| 1115 | + | Str("component", "permission"). | |||
| 1116 | + | Interface("panic", r). | |||
| 1117 | + | Msg("GType accessor panicked (unregistered puregotk binding?)") | |||
| 1118 | + | gtype = 0 | |||
| 1119 | + | ok = false | |||
| 1120 | + | } | |||
| 1121 | + | }() | |||
| 1122 | + | return fn(), true | |||
| 1123 | + | } | |||
| 1124 | + | ||||
| 1104 | func isPermissionRequestType(ctx context.Context, requestPtr uintptr, requestType gtypes.GType) bool { | 1125 | func isPermissionRequestType(ctx context.Context, requestPtr uintptr, requestType gtypes.GType) bool { | ||
| 1105 | return gobjectTypeCheckInstanceIsAByPtr(ctx, requestPtr, requestType) | 1126 | return gobjectTypeCheckInstanceIsAByPtr(ctx, requestPtr, requestType) | ||
| 1106 | } | 1127 | } | ||