@@ -18,11 +18,13 @@ const { BlockstoreAdapter } = require('interface-blockstore')
1818 * @returns {Key }
1919 */
2020function cidToKey ( cid ) {
21- if ( ! ( cid instanceof CID ) ) {
21+ const c = CID . asCID ( cid )
22+
23+ if ( ! ( c instanceof CID ) ) {
2224 throw errcode ( new Error ( 'Not a valid cid' ) , 'ERR_INVALID_CID' )
2325 }
2426
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 )
2628}
2729
2830/**
@@ -50,32 +52,53 @@ function keyToCid (key) {
5052 * @returns {string }
5153 */
5254function convertPrefix ( prefix ) {
53- let bytes
5455 const firstChar = prefix . substring ( 0 , 1 )
5556
5657 if ( firstChar === '/' ) {
5758 return convertPrefix ( prefix . substring ( 1 ) )
5859 }
5960
61+ /** @type {(input: string) => Uint8Array } */
62+ let decoder
63+
6064 if ( firstChar . toLowerCase ( ) === 'b' ) {
6165 // 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 )
6367 } else if ( firstChar . toLowerCase ( ) === 'c' ) {
6468 // 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 )
6670 } else if ( firstChar === 'z' ) {
6771 // v1 cid
68- bytes = base58btc . decode ( prefix ) . subarray ( 2 )
72+ decoder = ( input ) => base58btc . decode ( input ) . subarray ( 2 )
6973 } else if ( firstChar === 'Q' ) {
7074 // v0 cid prefix
71- bytes = base58btc . decode ( 'z' + prefix )
75+ decoder = ( input ) => base58btc . decode ( 'z' + input )
7276 } else {
73- bytes = base32 . decode ( 'b' + prefix . toLowerCase ( ) ) . subarray ( 2 )
77+ decoder = ( input ) => base32 . decode ( 'b' + input . toLowerCase ( ) ) . subarray ( 2 )
7478 }
7579
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+ }
77100
78- return str || 'C'
101+ return str
79102}
80103
81104/**
@@ -85,7 +108,7 @@ function convertPrefix (prefix) {
85108function convertQuery ( query ) {
86109 return {
87110 ...query ,
88- prefix : query . prefix ? `/ ${ convertPrefix ( query . prefix ) } ` : undefined ,
111+ prefix : query . prefix ? convertPrefix ( query . prefix ) : undefined ,
89112 filters : query . filters
90113 ? query . filters . map (
91114 filter => ( pair ) => {
@@ -110,7 +133,7 @@ function convertQuery (query) {
110133function convertKeyQuery ( query ) {
111134 return {
112135 ...query ,
113- prefix : query . prefix ? `/ ${ convertPrefix ( query . prefix ) } ` : undefined ,
136+ prefix : query . prefix ? convertPrefix ( query . prefix ) : undefined ,
114137 filters : query . filters
115138 ? query . filters . map (
116139 filter => ( key ) => {
0 commit comments