Rollup merge of #127763 - ChrisDenton:safe-unsafe-unsafe, r=tgross35 · model-checking/verify-rust-std@aeae332 (original) (raw)

1

1

`#![unstable(issue = "none", feature = "windows_handle")]

`

2

``

`-

#![allow(unsafe_op_in_unsafe_fn)]

`

3

2

``

4

3

`#[cfg(test)]

`

5

4

`mod tests;

`

`@@ -73,7 +72,7 @@ impl IntoRawHandle for Handle {

`

73

72

``

74

73

`impl FromRawHandle for Handle {

`

75

74

`unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {

`

76

``

`-

Self(FromRawHandle::from_raw_handle(raw_handle))

`

``

75

`+

unsafe { Self(FromRawHandle::from_raw_handle(raw_handle)) }

`

77

76

`}

`

78

77

`}

`

79

78

``

`@@ -139,13 +138,23 @@ impl Handle {

`

139

138

``

140

139

`pub unsafe fn read_overlapped(

`

141

140

`&self,

`

142

``

`-

buf: &mut [u8],

`

``

141

`+

buf: &mut [mem::MaybeUninit],

`

143

142

`overlapped: *mut c::OVERLAPPED,

`

144

143

`) -> io::Result<Option> {

`

145

``

`-

let len = cmp::min(buf.len(), u32::MAX as usize) as u32;

`

146

``

`-

let mut amt = 0;

`

147

``

`-

let res =

`

148

``

`-

cvt(c::ReadFile(self.as_raw_handle(), buf.as_mut_ptr(), len, &mut amt, overlapped));

`

``

144

`+

// SAFETY: We have exclusive access to the buffer and it's up to the caller to

`

``

145

`+

// ensure the OVERLAPPED pointer is valid for the lifetime of this function.

`

``

146

`+

let (res, amt) = unsafe {

`

``

147

`+

let len = cmp::min(buf.len(), u32::MAX as usize) as u32;

`

``

148

`+

let mut amt = 0;

`

``

149

`+

let res = cvt(c::ReadFile(

`

``

150

`+

self.as_raw_handle(),

`

``

151

`+

buf.as_mut_ptr().cast::(),

`

``

152

`+

len,

`

``

153

`+

&mut amt,

`

``

154

`+

overlapped,

`

``

155

`+

));

`

``

156

`+

(res, amt)

`

``

157

`+

};

`

149

158

`match res {

`

150

159

`Ok(_) => Ok(Some(amt as usize)),

`

151

160

`Err(e) => {

`

`@@ -230,20 +239,24 @@ impl Handle {

`

230

239

``

231

240

`// The length is clamped at u32::MAX.

`

232

241

`let len = cmp::min(len, u32::MAX as usize) as u32;

`

233

``

`-

let status = c::NtReadFile(

`

234

``

`-

self.as_handle(),

`

235

``

`-

ptr::null_mut(),

`

236

``

`-

None,

`

237

``

`-

ptr::null_mut(),

`

238

``

`-

&mut io_status,

`

239

``

`-

buf,

`

240

``

`-

len,

`

241

``

`-

offset.map(|n| n as _).as_ref(),

`

242

``

`-

None,

`

243

``

`-

);

`

``

242

`` +

// SAFETY: It's up to the caller to ensure buf is writeable up to

``

``

243

`` +

// the provided len.

``

``

244

`+

let status = unsafe {

`

``

245

`+

c::NtReadFile(

`

``

246

`+

self.as_handle(),

`

``

247

`+

ptr::null_mut(),

`

``

248

`+

None,

`

``

249

`+

ptr::null_mut(),

`

``

250

`+

&mut io_status,

`

``

251

`+

buf,

`

``

252

`+

len,

`

``

253

`+

offset.map(|n| n as _).as_ref(),

`

``

254

`+

None,

`

``

255

`+

)

`

``

256

`+

};

`

244

257

``

245

258

`let status = if status == c::STATUS_PENDING {

`

246

``

`-

c::WaitForSingleObject(self.as_raw_handle(), c::INFINITE);

`

``

259

`+

unsafe { c::WaitForSingleObject(self.as_raw_handle(), c::INFINITE) };

`

247

260

` io_status.status()

`

248

261

`} else {

`

249

262

` status

`

`@@ -261,7 +274,7 @@ impl Handle {

`

261

274

` status if c::nt_success(status) => Ok(io_status.Information),

`

262

275

``

263

276

` status => {

`

264

``

`-

let error = c::RtlNtStatusToDosError(status);

`

``

277

`+

let error = unsafe { c::RtlNtStatusToDosError(status) };

`

265

278

`Err(io::Error::from_raw_os_error(error as _))

`

266

279

`}

`

267

280

`}

`