@@ -127,17 +127,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
127
127
let tcx = & { this. tcx . tcx } ;
128
128
129
129
let buf = this. force_ptr ( this. read_scalar ( buf_op) ?. not_undef ( ) ?) ?;
130
- let size = this. read_scalar ( size_op) ?. to_usize ( & * this . tcx ) ?;
130
+ let size = this. read_scalar ( size_op) ?. to_usize ( & * tcx) ?;
131
131
// If we cannot get the current directory, we return null
132
132
match env:: current_dir ( ) {
133
133
Ok ( cwd) => {
134
134
// It is not clear what happens with non-utf8 paths here
135
135
let mut bytes = cwd. display ( ) . to_string ( ) . into_bytes ( ) ;
136
- // If the buffer is smaller or equal than the path, we return null.
136
+ // If `size` is smaller or equal than the `bytes.len()`, writing `bytes` plus the
137
+ // required null terminator to memory using the `buf` pointer would cause an
138
+ // overflow. The desired behavior in this case is to return null.
137
139
if ( bytes. len ( ) as u64 ) < size {
138
140
// We add a `/0` terminator
139
141
bytes. push ( 0 ) ;
140
- // This is ok because the buffer is larger than the path with the null terminator.
142
+ // This is ok because the buffer was strictly larger than `bytes`, so after
143
+ // adding the null terminator, the buffer size is larger or equal to
144
+ // `bytes.len()`, meaning that `bytes` actually fit inside tbe buffer.
141
145
this. memory_mut ( )
142
146
. get_mut ( buf. alloc_id ) ?
143
147
. write_bytes ( tcx, buf, & bytes) ?;
@@ -148,7 +152,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
148
152
}
149
153
Err ( e) => this. consume_io_error ( e) ?,
150
154
}
151
- Ok ( Scalar :: ptr_null ( & * this . tcx ) )
155
+ Ok ( Scalar :: ptr_null ( & * tcx) )
152
156
}
153
157
154
158
fn chdir ( & mut self , path_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , i32 > {
0 commit comments