@@ -18,11 +18,13 @@ const { BlockstoreAdapter } = require('interface-blockstore')
18
18
* @returns {Key }
19
19
*/
20
20
function cidToKey ( cid ) {
21
- if ( ! ( cid instanceof CID ) ) {
21
+ const c = CID . asCID ( cid )
22
+
23
+ if ( ! ( c instanceof CID ) ) {
22
24
throw errcode ( new Error ( 'Not a valid cid' ) , 'ERR_INVALID_CID' )
23
25
}
24
26
25
- return new Key ( '/' + base32 . encode ( cid . multihash . bytes ) . slice ( 1 ) . toUpperCase ( ) , false )
27
+ return new Key ( '/' + base32 . encode ( c . multihash . bytes ) . slice ( 1 ) . toUpperCase ( ) , false )
26
28
}
27
29
28
30
/**
@@ -50,32 +52,53 @@ function keyToCid (key) {
50
52
* @returns {string }
51
53
*/
52
54
function convertPrefix ( prefix ) {
53
- let bytes
54
55
const firstChar = prefix . substring ( 0 , 1 )
55
56
56
57
if ( firstChar === '/' ) {
57
58
return convertPrefix ( prefix . substring ( 1 ) )
58
59
}
59
60
61
+ /** @type {(input: string) => Uint8Array } */
62
+ let decoder
63
+
60
64
if ( firstChar . toLowerCase ( ) === 'b' ) {
61
65
// v1 cid prefix, remove version and codec bytes
62
- bytes = base32 . decode ( prefix . toLowerCase ( ) ) . subarray ( 2 )
66
+ decoder = ( input ) => base32 . decode ( input . toLowerCase ( ) ) . subarray ( 2 )
63
67
} else if ( firstChar . toLowerCase ( ) === 'c' ) {
64
68
// v1 cid prefix, remove version and codec bytes
65
- bytes = base32pad . decode ( prefix . toLowerCase ( ) ) . subarray ( 2 )
69
+ decoder = ( input ) => base32pad . decode ( input . toLowerCase ( ) ) . subarray ( 2 )
66
70
} else if ( firstChar === 'z' ) {
67
71
// v1 cid
68
- bytes = base58btc . decode ( prefix ) . subarray ( 2 )
72
+ decoder = ( input ) => base58btc . decode ( input ) . subarray ( 2 )
69
73
} else if ( firstChar === 'Q' ) {
70
74
// v0 cid prefix
71
- bytes = base58btc . decode ( 'z' + prefix )
75
+ decoder = ( input ) => base58btc . decode ( 'z' + input )
72
76
} else {
73
- bytes = base32 . decode ( 'b' + prefix . toLowerCase ( ) ) . subarray ( 2 )
77
+ decoder = ( input ) => base32 . decode ( 'b' + input . toLowerCase ( ) ) . subarray ( 2 )
74
78
}
75
79
76
- const str = base32 . encode ( bytes ) . substring ( 1 ) . toUpperCase ( )
80
+ let bytes
81
+
82
+ // find the longest prefix that we can safely decode
83
+ for ( let i = 1 ; i < prefix . length ; i ++ ) {
84
+ try {
85
+ bytes = decoder ( prefix . substring ( 0 , i ) )
86
+ } catch ( err ) {
87
+ if ( err . message !== 'Unexpected end of data' ) {
88
+ throw err
89
+ }
90
+ }
91
+ }
92
+
93
+ let str = '/C'
94
+
95
+ if ( bytes ) {
96
+ // slice one character from the end of the string to ensure we don't end up
97
+ // with a padded value which could have a non-matching string at the end
98
+ str = `/${ base32 . encode ( bytes ) . slice ( 1 , - 1 ) . toUpperCase ( ) || 'C' } `
99
+ }
77
100
78
- return str || 'C'
101
+ return str
79
102
}
80
103
81
104
/**
@@ -85,7 +108,7 @@ function convertPrefix (prefix) {
85
108
function convertQuery ( query ) {
86
109
return {
87
110
...query ,
88
- prefix : query . prefix ? `/ ${ convertPrefix ( query . prefix ) } ` : undefined ,
111
+ prefix : query . prefix ? convertPrefix ( query . prefix ) : undefined ,
89
112
filters : query . filters
90
113
? query . filters . map (
91
114
filter => ( pair ) => {
@@ -110,7 +133,7 @@ function convertQuery (query) {
110
133
function convertKeyQuery ( query ) {
111
134
return {
112
135
...query ,
113
- prefix : query . prefix ? `/ ${ convertPrefix ( query . prefix ) } ` : undefined ,
136
+ prefix : query . prefix ? convertPrefix ( query . prefix ) : undefined ,
114
137
filters : query . filters
115
138
? query . filters . map (
116
139
filter => ( key ) => {
0 commit comments