Skip to content

Commit 1ef63b5

Browse files
authored
refactor!: make the API harder to misuse (#261)
1 parent d19cf5d commit 1ef63b5

File tree

15 files changed

+562
-498
lines changed

15 files changed

+562
-498
lines changed

codec.go

Lines changed: 40 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ func stringToBytes(s string) ([]byte, error) {
5353
if err != nil {
5454
return nil, fmt.Errorf("failed to parse multiaddr %q: invalid value %q for protocol %s: %s", s, sp[0], p.Name, err)
5555
}
56+
err = p.Transcoder.ValidateBytes(a)
57+
if err != nil {
58+
return nil, err
59+
}
5660
if p.Size < 0 { // varint size.
5761
_, _ = b.Write(varint.ToUvarint(uint64(len(a))))
5862
}
@@ -63,51 +67,6 @@ func stringToBytes(s string) ([]byte, error) {
6367
return b.Bytes(), nil
6468
}
6569

66-
func validateBytes(b []byte) (err error) {
67-
if len(b) == 0 {
68-
return fmt.Errorf("empty multiaddr")
69-
}
70-
for len(b) > 0 {
71-
code, n, err := ReadVarintCode(b)
72-
if err != nil {
73-
return err
74-
}
75-
76-
b = b[n:]
77-
p := ProtocolWithCode(code)
78-
if p.Code == 0 {
79-
return fmt.Errorf("no protocol with code %d", code)
80-
}
81-
82-
if p.Size == 0 {
83-
continue
84-
}
85-
86-
n, size, err := sizeForAddr(p, b)
87-
if err != nil {
88-
return err
89-
}
90-
91-
b = b[n:]
92-
93-
if len(b) < size || size < 0 {
94-
return fmt.Errorf("invalid value for size %d", len(b))
95-
}
96-
if p.Path && len(b) != size {
97-
return fmt.Errorf("invalid size of component for path protocol %d: expected %d", size, len(b))
98-
}
99-
100-
err = p.Transcoder.ValidateBytes(b[:size])
101-
if err != nil {
102-
return err
103-
}
104-
105-
b = b[size:]
106-
}
107-
108-
return nil
109-
}
110-
11170
func readComponent(b []byte) (int, Component, error) {
11271
var offset int
11372
code, n, err := ReadVarintCode(b)
@@ -122,60 +81,64 @@ func readComponent(b []byte) (int, Component, error) {
12281
}
12382

12483
if p.Size == 0 {
125-
return offset, Component{
126-
bytes: b[:offset],
84+
c, err := validateComponent(Component{
85+
bytes: string(b[:offset]),
12786
offset: offset,
12887
protocol: p,
129-
}, nil
130-
}
88+
})
13189

132-
n, size, err := sizeForAddr(p, b[offset:])
133-
if err != nil {
134-
return 0, Component{}, err
90+
return offset, c, err
13591
}
13692

137-
offset += n
93+
var size int
94+
if p.Size < 0 {
95+
// varint
96+
var n int
97+
size, n, err = ReadVarintCode(b[offset:])
98+
if err != nil {
99+
return 0, Component{}, err
100+
}
101+
offset += n
102+
} else {
103+
// Size is in bits, but we operate on bytes
104+
size = p.Size / 8
105+
}
138106

139-
if len(b[offset:]) < size || size < 0 {
107+
if len(b[offset:]) < size || size <= 0 {
140108
return 0, Component{}, fmt.Errorf("invalid value for size %d", len(b[offset:]))
141109
}
142110

143-
return offset + size, Component{
144-
bytes: b[:offset+size],
111+
c, err := validateComponent(Component{
112+
bytes: string(b[:offset+size]),
145113
protocol: p,
146114
offset: offset,
147-
}, nil
115+
})
116+
117+
return offset + size, c, err
148118
}
149119

150-
func bytesToString(b []byte) (ret string, err error) {
120+
func readMultiaddr(b []byte) (int, Multiaddr, error) {
151121
if len(b) == 0 {
152-
return "", fmt.Errorf("empty multiaddr")
122+
return 0, nil, fmt.Errorf("empty multiaddr")
153123
}
154-
var buf strings.Builder
155124

125+
var res Multiaddr
126+
bytesRead := 0
127+
sawPathComponent := false
156128
for len(b) > 0 {
157129
n, c, err := readComponent(b)
158130
if err != nil {
159-
return "", err
131+
return 0, nil, err
160132
}
161133
b = b[n:]
162-
c.writeTo(&buf)
163-
}
134+
bytesRead += n
164135

165-
return buf.String(), nil
166-
}
167-
168-
func sizeForAddr(p Protocol, b []byte) (skip, size int, err error) {
169-
switch {
170-
case p.Size > 0:
171-
return 0, (p.Size / 8), nil
172-
case p.Size == 0:
173-
return 0, 0, nil
174-
default:
175-
size, n, err := ReadVarintCode(b)
176-
if err != nil {
177-
return 0, 0, err
136+
if sawPathComponent {
137+
// It is an error to have another component after a path component.
138+
return bytesRead, nil, fmt.Errorf("unexpected component after path component")
178139
}
179-
return n, size, nil
140+
sawPathComponent = c.protocol.Path
141+
res = append(res, c)
180142
}
143+
return bytesRead, res, nil
181144
}

0 commit comments

Comments
 (0)