Skip to content

Commit fae8119

Browse files
committed
feat(iaviewer): Quote key components that could be misinterpreted (as e.g. hexadecimal)
1 parent dde193c commit fae8119

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

cmd/iaviewer/main.go

+22-13
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package main
33
import (
44
"bytes"
55
"crypto/sha256"
6-
"encoding/hex"
76
"fmt"
87
"os"
98
"path/filepath"
@@ -161,26 +160,39 @@ func PrintKeys(tree *iavl.ImmutableTree) {
161160
})
162161
}
163162

164-
// parseWeaveKey assumes a separating : where all in front should be ascii,
165-
// and all afterwards may be ascii or binary
163+
// parseWeaveKey returns a string representation of a key, splitting on the first ":"
164+
// into a prefix (presumably an all-ASCII type label) followed by a possibly-binary suffix.
166165
func parseWeaveKey(key []byte) string {
167166
cut := bytes.IndexRune(key, ':')
168167
if cut == -1 {
169-
return encodeID(key)
168+
return encodeData(key)
170169
}
171170
prefix := key[:cut]
172171
id := key[cut+1:]
173-
return fmt.Sprintf("%s:%s", encodeID(prefix), encodeID(id))
172+
return fmt.Sprintf("%s:%s", encodeData(prefix), encodeData(id))
174173
}
175174

176-
// casts to a string if it is printable ascii, hex-encodes otherwise
177-
func encodeID(id []byte) string {
178-
for _, b := range id {
175+
// encodeData returns a printable ASCII representation of its input;
176+
// hexadecimal if it is not already printable ASCII, otherwise plain
177+
// or quoted as necessary to avoid misinterpretation.
178+
func encodeData(src []byte) string {
179+
hexConfusable := true
180+
forceQuotes := false
181+
for _, b := range src {
179182
if b < 0x20 || b >= 0x80 {
180-
return strings.ToUpper(hex.EncodeToString(id))
183+
return fmt.Sprintf("%X", src)
181184
}
185+
if b < '0' || (b > '9' && b < 'A') || (b > 'F') {
186+
hexConfusable = false
187+
if b == ' ' || b == '"' || b == '\\' {
188+
forceQuotes = true
189+
}
190+
}
191+
}
192+
if hexConfusable || forceQuotes {
193+
return fmt.Sprintf("%q", src)
182194
}
183-
return string(id)
195+
return string(src)
184196
}
185197

186198
func PrintShape(tree *iavl.ImmutableTree) {
@@ -195,9 +207,6 @@ func nodeEncoder(id []byte, depth int, isLeaf bool) string {
195207
if isLeaf {
196208
prefix = fmt.Sprintf("*%d ", depth)
197209
}
198-
if len(id) == 0 {
199-
return fmt.Sprintf("%s<nil>", prefix)
200-
}
201210
return fmt.Sprintf("%s%s", prefix, parseWeaveKey(id))
202211
}
203212

0 commit comments

Comments
 (0)