1
1
use std:: collections:: HashMap ;
2
+ use std:: convert:: TryFrom ;
2
3
use std:: fs:: { remove_file, File , OpenOptions } ;
3
4
use std:: io:: { Read , Write } ;
4
- use std:: convert:: TryFrom ;
5
5
6
6
use rustc:: ty:: layout:: Size ;
7
7
@@ -166,7 +166,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
166
166
167
167
this. check_no_isolation ( "read" ) ?;
168
168
169
- let count = this. read_scalar ( count_op) ?. to_machine_usize ( & * this. tcx ) ?;
169
+ let ptr_size = this. pointer_size ( ) . bits ( ) ;
170
+
171
+ let count = this
172
+ . read_scalar ( count_op) ?
173
+ . to_machine_usize ( & * this. tcx ) ?
174
+ . min ( 1 << ( ptr_size - 1 ) ) ;
170
175
// Reading zero bytes should not change `buf`.
171
176
if count == 0 {
172
177
return Ok ( 0 ) ;
@@ -175,22 +180,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
175
180
let buf = this. read_scalar ( buf_op) ?. not_undef ( ) ?;
176
181
177
182
if let Some ( handle) = this. machine . file_handler . handles . get_mut ( & fd) {
178
- let count = isize:: try_from ( count)
179
- . map_err ( |_| err_unsup_format ! ( "Program tries to read into buffer too big for this host platform" ) ) ?;
183
+ let count = isize:: try_from ( count) . unwrap ( ) ;
180
184
// We want to read at most `count` bytes. We are sure that `count` is not negative
181
185
// because it was a target's `usize`. Also we are sure that its smaller than
182
186
// `usize::max_value()` because it is a host's `isize`.
183
187
let mut bytes = vec ! [ 0 ; count as usize ] ;
184
- let result = handle. file . read ( & mut bytes) ;
188
+ let result = handle
189
+ . file
190
+ . read ( & mut bytes)
191
+ . map ( |c| i64:: try_from ( c) . unwrap ( ) ) ;
185
192
186
193
match result {
187
- Ok ( c) => {
188
- let read_bytes = i64:: try_from ( c)
189
- . map_err ( |_| err_unsup_format ! ( "Number of read bytes {} cannot be transformed to i64" , c) ) ?;
194
+ Ok ( read_bytes) => {
190
195
// If reading to `bytes` did not fail, we write those bytes to the buffer.
191
196
this. memory . write_bytes ( buf, bytes) ?;
192
197
Ok ( read_bytes)
193
- } ,
198
+ }
194
199
Err ( e) => {
195
200
this. set_last_error_from_io_error ( e) ?;
196
201
Ok ( -1 )
@@ -211,7 +216,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
211
216
212
217
this. check_no_isolation ( "write" ) ?;
213
218
214
- let count = this. read_scalar ( count_op) ?. to_machine_usize ( & * this. tcx ) ?;
219
+ let ptr_size = this. pointer_size ( ) . bits ( ) ;
220
+
221
+ let count = this
222
+ . read_scalar ( count_op) ?
223
+ . to_machine_usize ( & * this. tcx ) ?
224
+ . min ( 1 << ( ptr_size - 1 ) ) ;
215
225
// Writing zero bytes should not change `buf`.
216
226
if count == 0 {
217
227
return Ok ( 0 ) ;
@@ -221,16 +231,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
221
231
222
232
if let Some ( handle) = this. machine . file_handler . handles . get_mut ( & fd) {
223
233
let bytes = this. memory . read_bytes ( buf, Size :: from_bytes ( count) ) ?;
224
- let result = handle. file . write ( & bytes) ;
225
-
226
- match result {
227
- Ok ( c) => i64:: try_from ( c)
228
- . map_err ( |_| err_unsup_format ! ( "Number of written bytes {} cannot be transformed to i64" , c) . into ( ) ) ,
229
- Err ( e) => {
230
- this. set_last_error_from_io_error ( e) ?;
231
- Ok ( -1 )
232
- }
233
- }
234
+ let result = handle. file . write ( & bytes) . map ( |c| i64:: try_from ( c) . unwrap ( ) ) ;
235
+ this. try_unwrap_io_result ( result)
234
236
} else {
235
237
this. handle_not_found ( )
236
238
}
0 commit comments