v0.33.2 57f21d6

runtime_safety.go RawHistoryFolder

1// Package process provides dependency-leaf process-environment helpers.
2//
3// This file must not import bootstrap, desktop, or any other internal
4// package: both cmd/dumber and internal/infrastructure/desktop import it, and
5// bootstrap already imports desktop. Keep it to the standard library so the
6// merge rule can be shared without an import cycle.
7package process
8
9import "strings"
10
11// RuntimeSafetySetting is the GODEBUG key that must be set before any
12// goroutine or CEF subprocess is created. Go stack shrinking can invalidate
13// frames retained across foreign CEF/GTK stacks.
14const RuntimeSafetySetting = "gcshrinkstackoff"
15
16// EnvironmentValue returns the value for name in an environ slice.
17func EnvironmentValue(environ []string, name string) string {
18	prefix := name + "="
19	for _, entry := range environ {
20		if strings.HasPrefix(entry, prefix) {
21			return strings.TrimPrefix(entry, prefix)
22		}
23	}
24	return ""
25}
26
27// ReplaceEnvironmentValue returns a copy of environ with name set to value.
28func ReplaceEnvironmentValue(environ []string, name, value string) []string {
29	prefix := name + "="
30	updated := make([]string, 0, len(environ)+1)
31	for _, entry := range environ {
32		if !strings.HasPrefix(entry, prefix) {
33			updated = append(updated, entry)
34		}
35	}
36	return append(updated, prefix+value)
37}
38
39// MergeRuntimeSafety returns a copy of environ with RuntimeSafetySetting=1
40// merged into GODEBUG, preserving all unrelated entries (including other
41// GODEBUG keys) and their relative order. It reports whether a change was
42// applied. An already-effective single setting entry is detected
43// independently of its position, so direct invocation never performs an
44// unnecessary self-exec; duplicate or conflicting entries still collapse to
45// one normalized trailing entry.
46func MergeRuntimeSafety(environ []string) ([]string, bool) {
47	updated := append([]string(nil), environ...)
48	// Collect every GODEBUG entry: duplicates are legal in an environ
49	// slice and the first entry alone never describes the effective
50	// setting, so normalization must merge them all before deciding.
51	godebugValues := make([]string, 0, 1)
52	for _, entry := range updated {
53		if strings.HasPrefix(entry, "GODEBUG=") {
54			godebugValues = append(godebugValues, strings.TrimPrefix(entry, "GODEBUG="))
55		}
56	}
57	current := strings.Join(godebugValues, ",")
58	parts := strings.Split(current, ",")
59	kept := make([]string, 0, len(parts)+1)
60	var settingParts []string
61	for _, part := range parts {
62		part = strings.TrimSpace(part)
63		if part == "" {
64			continue
65		}
66		key, _, _ := strings.Cut(part, "=")
67		if key == RuntimeSafetySetting {
68			settingParts = append(settingParts, part)
69			continue
70		}
71		kept = append(kept, part)
72	}
73	if len(godebugValues) == 1 && len(settingParts) == 1 && settingParts[0] == RuntimeSafetySetting+"=1" {
74		// Exactly one entry with one effective setting: already safe in
75		// place, independent of its position among the other keys. Leave
76		// the order untouched so direct invocation performs no self-exec.
77		return updated, false
78	}
79	// Zero, duplicate, conflicting, or valueless entries collapse to one
80	// normalized trailing entry.
81	merged := strings.Join(append(kept, RuntimeSafetySetting+"=1"), ",")
82	if current == merged {
83		return updated, false
84	}
85	return ReplaceEnvironmentValue(updated, "GODEBUG", merged), true
86}

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