@@ -168,10 +168,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
168
168
169
169
let ptr_size = this. pointer_size ( ) . bits ( ) ;
170
170
171
+ // We cap the number of read bytes to the largest value that we are able to fit in both the
172
+ // host's and target's `isize`.
171
173
let count = this
172
174
. read_scalar ( count_op) ?
173
175
. to_machine_usize ( & * this. tcx ) ?
174
- . min ( 1 << ( ptr_size - 1 ) ) ;
176
+ . min ( 1 << ( ptr_size - 1 ) )
177
+ . min ( isize:: max_value ( ) as u64 ) ;
175
178
// Reading zero bytes should not change `buf`.
176
179
if count == 0 {
177
180
return Ok ( 0 ) ;
@@ -180,6 +183,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
180
183
let buf = this. read_scalar ( buf_op) ?. not_undef ( ) ?;
181
184
182
185
if let Some ( handle) = this. machine . file_handler . handles . get_mut ( & fd) {
186
+ // This can never fail because `count` was capped to be smaller than
187
+ // `isize::max_value()`.
183
188
let count = isize:: try_from ( count) . unwrap ( ) ;
184
189
// We want to read at most `count` bytes. We are sure that `count` is not negative
185
190
// because it was a target's `usize`. Also we are sure that its smaller than
@@ -188,6 +193,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
188
193
let result = handle
189
194
. file
190
195
. read ( & mut bytes)
196
+ // `File::read` never returns a value larger than `i64::max_value()`, so this
197
+ // unwrap cannot fail.
191
198
. map ( |c| i64:: try_from ( c) . unwrap ( ) ) ;
192
199
193
200
match result {
@@ -218,10 +225,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
218
225
219
226
let ptr_size = this. pointer_size ( ) . bits ( ) ;
220
227
228
+ // We cap the number of read bytes to the largest value that we are able to fit in both the
229
+ // host's and target's `isize`.
221
230
let count = this
222
231
. read_scalar ( count_op) ?
223
232
. to_machine_usize ( & * this. tcx ) ?
224
- . min ( 1 << ( ptr_size - 1 ) ) ;
233
+ . min ( 1 << ( ptr_size - 1 ) )
234
+ . min ( isize:: max_value ( ) as u64 ) ;
225
235
// Writing zero bytes should not change `buf`.
226
236
if count == 0 {
227
237
return Ok ( 0 ) ;
0 commit comments