@@ -3,7 +3,6 @@ package main
3
3
import (
4
4
"bytes"
5
5
"crypto/sha256"
6
- "encoding/hex"
7
6
"fmt"
8
7
"os"
9
8
"path/filepath"
@@ -161,26 +160,39 @@ func PrintKeys(tree *iavl.ImmutableTree) {
161
160
})
162
161
}
163
162
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.
166
165
func parseWeaveKey (key []byte ) string {
167
166
cut := bytes .IndexRune (key , ':' )
168
167
if cut == - 1 {
169
- return encodeID (key )
168
+ return encodeData (key )
170
169
}
171
170
prefix := key [:cut ]
172
171
id := key [cut + 1 :]
173
- return fmt .Sprintf ("%s:%s" , encodeID (prefix ), encodeID (id ))
172
+ return fmt .Sprintf ("%s:%s" , encodeData (prefix ), encodeData (id ))
174
173
}
175
174
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 {
179
182
if b < 0x20 || b >= 0x80 {
180
- return strings . ToUpper ( hex . EncodeToString ( id ) )
183
+ return fmt . Sprintf ( "%X" , src )
181
184
}
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 )
182
194
}
183
- return string (id )
195
+ return string (src )
184
196
}
185
197
186
198
func PrintShape (tree * iavl.ImmutableTree ) {
@@ -195,9 +207,6 @@ func nodeEncoder(id []byte, depth int, isLeaf bool) string {
195
207
if isLeaf {
196
208
prefix = fmt .Sprintf ("*%d " , depth )
197
209
}
198
- if len (id ) == 0 {
199
- return fmt .Sprintf ("%s<nil>" , prefix )
200
- }
201
210
return fmt .Sprintf ("%s%s" , prefix , parseWeaveKey (id ))
202
211
}
203
212
0 commit comments