main ece7682

json.go RawHistoryFolder

1package brokerstore
2
3import (
4	"bytes"
5	"encoding/json"
6	"errors"
7	"io"
8	"os"
9	"syscall"
10	"unicode/utf8"
11)
12
13func readBounded(path string) ([]byte, error) {
14	fd, err := syscall.Open(path, syscall.O_RDONLY|syscall.O_CLOEXEC|syscall.O_NOFOLLOW|syscall.O_NONBLOCK, 0)
15	if err != nil {
16		return nil, err
17	}
18	f := os.NewFile(uintptr(fd), path)
19	defer f.Close()
20	st, err := f.Stat()
21	if err != nil {
22		return nil, err
23	}
24	if !st.Mode().IsRegular() || st.Size() > MaxFileBytes {
25		return nil, errors.New("brokerstore: invalid file type or size")
26	}
27	b, err := io.ReadAll(io.LimitReader(f, MaxFileBytes+1))
28	if len(b) > MaxFileBytes {
29		return nil, errors.New("brokerstore: oversized input")
30	}
31	return b, err
32}
33
34// strict rejects duplicate keys as well as unknown fields, trailing JSON,
35// invalid UTF-8 and excessive nesting. Byte bounds apply before decoding.
36func strict(raw []byte, dst any) error {
37	if len(raw) > MaxFileBytes || !utf8.Valid(raw) {
38		return errors.New("brokerstore: invalid JSON size or encoding")
39	}
40	scan := json.NewDecoder(bytes.NewReader(raw))
41	if err := scanValue(scan, 0); err != nil {
42		return err
43	}
44	if _, err := scan.Token(); err != io.EOF {
45		return errors.New("brokerstore: trailing JSON")
46	}
47	dec := json.NewDecoder(bytes.NewReader(raw))
48	dec.DisallowUnknownFields()
49	return dec.Decode(dst)
50}
51func scanValue(d *json.Decoder, depth int) error {
52	if depth > 64 {
53		return errors.New("brokerstore: JSON nesting limit")
54	}
55	t, err := d.Token()
56	if err != nil {
57		return err
58	}
59	delim, ok := t.(json.Delim)
60	if !ok {
61		return nil
62	}
63	switch delim {
64	case '{':
65		seen := map[string]bool{}
66		for d.More() {
67			key, err := d.Token()
68			if err != nil {
69				return err
70			}
71			k, ok := key.(string)
72			if !ok || seen[k] {
73				return errors.New("brokerstore: duplicate JSON key")
74			}
75			seen[k] = true
76			if err := scanValue(d, depth+1); err != nil {
77				return err
78			}
79		}
80	case '[':
81		for d.More() {
82			if err := scanValue(d, depth+1); err != nil {
83				return err
84			}
85		}
86	default:
87		return errors.New("brokerstore: unexpected delimiter")
88	}
89	_, err = d.Token()
90	return err
91}

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 12

Tags 11

↑↓ moveenter openesc close