@@ -45,6 +45,18 @@ func parseIPLDNotFoundWithFallbackToError(msg error) error {
45
45
return msg
46
46
}
47
47
48
+ // Use a string to move it into RODATA
49
+ // print("".join("\\x01" if chr(i) not in string.ascii_letters + string.digits else "\\x00" for i in range(ord('z')+1)))
50
+ const notAsciiLetterOrDigitsLUT = "\x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x01 \x01 \x01 \x01 \x01 \x01 \x01 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x01 \x01 \x01 \x01 \x01 \x01 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 "
51
+
52
+ func notAsciiLetterOrDigits (r rune ) bool {
53
+ if r > 'z' {
54
+ return true
55
+ }
56
+
57
+ return notAsciiLetterOrDigitsLUT [r ] > 0
58
+ }
59
+
48
60
// This file handle parsing and returning the correct ABI based errors from error messages
49
61
//lint:ignore ST1008 this function is not using the error as a mean to return failure but it massages it to return the correct type
50
62
func parseIPLDNotFound (msg string ) (error , bool ) {
@@ -53,46 +65,46 @@ func parseIPLDNotFound(msg string) (error, bool) {
53
65
}
54
66
55
67
// The patern we search for is:
56
- // node not found (fallback)
57
- // or
58
- // CID not found (here we parse the CID)
59
- notFoundIndex := strings .LastIndex (msg , " not found" )
68
+ const ipldErrNotFoundKey = "ipld: could not find " /*CID*/
69
+ // We try to parse the CID, if it's invalid we give up and return a simple text error.
70
+ // We also accept "node" in place of the CID because that means it's an Undefined CID.
60
71
61
- if notFoundIndex == - 1 {
62
- // Unknown, ot found not found
72
+ keyIndex := strings .Index (msg , ipldErrNotFoundKey )
73
+
74
+ if keyIndex < 0 { // Unknown error
63
75
return nil , false
64
76
}
65
77
66
- preNotFound := msg [: notFoundIndex ]
78
+ cidStart := keyIndex + len ( ipldErrNotFoundKey )
67
79
80
+ msgPostKey := msg [cidStart :]
68
81
var c cid.Cid
69
- var preIndex int
70
- if strings .HasSuffix ( preNotFound , "node" ) {
82
+ var postIndex int
83
+ if strings .HasPrefix ( msgPostKey , "node" ) {
71
84
// Fallback case
72
85
c = cid .Undef
73
- preIndex = notFoundIndex - len ("node" )
86
+ postIndex = len ("node" )
74
87
} else {
75
- // Assume that CIDs does not include whitespace to pull out the CID
76
- preIndex = strings .LastIndexByte (preNotFound , ' ' )
77
- // + 1 is to normalise not founds to zeros and point to the start of the CID, not the previous space
78
- preIndex ++
88
+ // Assume that CIDs only contain a-zA-Z0-9 characters.
89
+ // This is true because go-ipld-format use go-cid#Cid.String which use base{3{2,6},58}.
90
+ postIndex = strings .IndexFunc (msgPostKey , notAsciiLetterOrDigits )
91
+ if postIndex < 0 {
92
+ postIndex = len (msgPostKey )
93
+ }
94
+
79
95
var err error
80
- c , err = cid .Decode (preNotFound [ preIndex : ])
96
+ c , err = cid .Decode (msgPostKey [: postIndex ])
81
97
if err != nil {
82
98
// Unknown
83
99
return nil , false
84
100
}
85
101
}
86
102
87
- postIndex := notFoundIndex + len (" not found" )
88
-
89
103
err := ipld.ErrNotFound {Cid : c }
90
-
91
- pre := msg [:preIndex ]
92
- post := msg [postIndex :]
104
+ pre := msg [:keyIndex ]
105
+ post := msgPostKey [postIndex :]
93
106
94
107
if len (pre ) > 0 || len (post ) > 0 {
95
- // We have some text to wrap arround the ErrNotFound one
96
108
return prePostWrappedNotFoundError {
97
109
pre : pre ,
98
110
post : post ,
0 commit comments