@@ -107,8 +107,9 @@ def _get_source_code(
107
107
:return:
108
108
"""
109
109
src_mapping = contract .source_mapping
110
- # TODO: this needs to be encoded before it gets indexed!
111
- src_bytes = self ._compilation_unit .core .source_code [src_mapping .filename .absolute ]
110
+ src_bytes = self ._compilation_unit .core .source_code [src_mapping .filename .absolute ].encode (
111
+ "utf8"
112
+ )
112
113
113
114
to_patch = []
114
115
# interface must use external
@@ -123,8 +124,8 @@ def _get_source_code(
123
124
+ f .parameters_src ().source_mapping .length
124
125
)
125
126
attributes_end = f .returns_src ().source_mapping .start
126
- attributes = src_bytes [attributes_start :attributes_end ]
127
- regex = re .search (r"((\sexternal)\s+)|(\sexternal)$|(\)external)$" , attributes . decode ( "utf8" ) )
127
+ attributes = src_bytes [attributes_start :attributes_end ]. decode ( "utf8" )
128
+ regex = re .search (r"((\sexternal)\s+)|(\sexternal)$|(\)external)$" , attributes )
128
129
if regex :
129
130
to_patch .append (
130
131
Patch (
@@ -133,7 +134,7 @@ def _get_source_code(
133
134
)
134
135
)
135
136
else :
136
- raise SlitherException (f"External keyword not found { f .name } { attributes . decode ( "utf8" ) } " )
137
+ raise SlitherException (f"External keyword not found { f .name } { attributes } " )
137
138
138
139
for var in f .parameters :
139
140
if var .location == "calldata" :
@@ -157,11 +158,11 @@ def _get_source_code(
157
158
+ f .parameters_src ().source_mapping ["length" ]
158
159
)
159
160
attributes_end = f .returns_src ().source_mapping ["start" ]
160
- attributes = src_bytes [attributes_start :attributes_end ]
161
+ attributes = src_bytes [attributes_start :attributes_end ]. decode ( "utf8" )
161
162
regex = (
162
- re .search (r"((\sexternal)\s+)|(\sexternal)$|(\)external)$" , attributes . decode ( "utf8" ) )
163
+ re .search (r"((\sexternal)\s+)|(\sexternal)$|(\)external)$" , attributes )
163
164
if visibility == "external"
164
- else re .search (r"((\spublic)\s+)|(\spublic)$|(\)public)$" , attributes . decode ( "utf8" ) )
165
+ else re .search (r"((\spublic)\s+)|(\spublic)$|(\)public)$" , attributes )
165
166
)
166
167
if regex :
167
168
to_patch .append (
@@ -174,16 +175,16 @@ def _get_source_code(
174
175
)
175
176
else :
176
177
raise SlitherException (
177
- f"{ visibility } keyword not found { f .name } { attributes . decode ( "utf8" ) } "
178
+ f"{ visibility } keyword not found { f .name } { attributes } "
178
179
)
179
180
180
181
if self ._private_to_internal :
181
182
for variable in contract .state_variables_declared :
182
183
if variable .visibility == "private" :
183
184
attributes_start = variable .source_mapping .start
184
185
attributes_end = attributes_start + variable .source_mapping .length
185
- attributes = src_bytes [attributes_start :attributes_end ]
186
- regex = re .search (r" private " , attributes . decode ( "utf8" ) )
186
+ attributes = src_bytes [attributes_start :attributes_end ]. decode ( "utf8" )
187
+ regex = re .search (r" private " , attributes )
187
188
if regex :
188
189
to_patch .append (
189
190
Patch (
@@ -193,7 +194,7 @@ def _get_source_code(
193
194
)
194
195
else :
195
196
raise SlitherException (
196
- f"private keyword not found { variable .name } { attributes . decode ( "utf8" ) } "
197
+ f"private keyword not found { variable .name } { attributes } "
197
198
)
198
199
199
200
if self ._remove_assert :
@@ -210,28 +211,42 @@ def _get_source_code(
210
211
211
212
to_patch .sort (key = lambda x : x .index , reverse = True )
212
213
213
- # Note: foundry and solc and everything else return srcmap offsets per-byte
214
- # and it seems the rest of slither operates on bytes also
215
- # it might just be the mutator and flattener that are incorrectly applying offsets directly to strings
216
- # I think I just need to do the following (and similar for mutations)
217
- # content = content.encode("utf8")[start:end].decode("utf8")
218
-
219
214
content = src_mapping .content .encode ("utf8" )
220
215
start = src_mapping .start
221
216
for patch in to_patch :
222
217
patch_type = patch .patch_type
223
218
index = patch .index
224
219
index = index - start
225
220
if patch_type == "public_to_external" :
226
- content = content [:index ].decode ("utf8" ) + "public" + content [index + len ("external" ) :].decode ("utf8" )
221
+ content = (
222
+ content [:index ].decode ("utf8" )
223
+ + "public"
224
+ + content [index + len ("external" ) :].decode ("utf8" )
225
+ )
227
226
elif patch_type == "external_to_internal" :
228
- content = content [:index ].decode ("utf8" ) + "internal" + content [index + len ("external" ) :].decode ("utf8" )
227
+ content = (
228
+ content [:index ].decode ("utf8" )
229
+ + "internal"
230
+ + content [index + len ("external" ) :].decode ("utf8" )
231
+ )
229
232
elif patch_type == "public_to_internal" :
230
- content = content [:index ].decode ("utf8" ) + "internal" + content [index + len ("public" ) :].decode ("utf8" )
233
+ content = (
234
+ content [:index ].decode ("utf8" )
235
+ + "internal"
236
+ + content [index + len ("public" ) :].decode ("utf8" )
237
+ )
231
238
elif patch_type == "private_to_internal" :
232
- content = content [:index ].decode ("utf8" ) + "internal" + content [index + len ("private" ) :].decode ("utf8" )
239
+ content = (
240
+ content [:index ].decode ("utf8" )
241
+ + "internal"
242
+ + content [index + len ("private" ) :].decode ("utf8" )
243
+ )
233
244
elif patch_type == "calldata_to_memory" :
234
- content = content [:index ].decode ("utf8" ) + "memory" + content [index + len ("calldata" ) :].decode ("utf8" )
245
+ content = (
246
+ content [:index ].decode ("utf8" )
247
+ + "memory"
248
+ + content [index + len ("calldata" ) :].decode ("utf8" )
249
+ )
235
250
else :
236
251
assert patch_type == "line_removal"
237
252
content = content [:index ].decode ("utf8" ) + " // " + content [index :].decode ("utf8" )
0 commit comments