Skip to content

Commit

Permalink
std: Cap read/write limits on Windows networking
Browse files Browse the repository at this point in the history
Similar to #31825 where the read/write limits were capped for files, this
implements similar limits when reading/writing networking types. On Unix this
shouldn't affect anything because the write size is already a `usize`, but on
Windows this will cap the read/write amounts to `i32::max_value`.

cc #31841
  • Loading branch information
alexcrichton committed Feb 24, 2016
1 parent 281f9d8 commit f3be73c
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
10 changes: 7 additions & 3 deletions src/libstd/sys/common/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use prelude::v1::*;

use cmp;
use ffi::{CStr, CString};
use fmt;
use io::{self, Error, ErrorKind};
Expand Down Expand Up @@ -198,10 +199,11 @@ impl TcpStream {
}

pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
let ret = try!(cvt(unsafe {
c::send(*self.inner.as_inner(),
buf.as_ptr() as *const c_void,
buf.len() as wrlen_t,
len,
0)
}));
Ok(ret as usize)
Expand Down Expand Up @@ -358,21 +360,23 @@ impl UdpSocket {
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
let mut addrlen = mem::size_of_val(&storage) as c::socklen_t;
let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;

let n = try!(cvt(unsafe {
c::recvfrom(*self.inner.as_inner(),
buf.as_mut_ptr() as *mut c_void,
buf.len() as wrlen_t, 0,
len, 0,
&mut storage as *mut _ as *mut _, &mut addrlen)
}));
Ok((n as usize, try!(sockaddr_to_addr(&storage, addrlen as usize))))
}

pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
let (dstp, dstlen) = dst.into_inner();
let ret = try!(cvt(unsafe {
c::sendto(*self.inner.as_inner(),
buf.as_ptr() as *const c_void, buf.len() as wrlen_t,
buf.as_ptr() as *const c_void, len,
0, dstp, dstlen)
}));
Ok(ret as usize)
Expand Down
5 changes: 3 additions & 2 deletions src/libstd/sys/windows/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use cmp;
use io;
use libc::{c_int, c_void};
use mem;
Expand Down Expand Up @@ -131,9 +132,9 @@ impl Socket {
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
// On unix when a socket is shut down all further reads return 0, so we
// do the same on windows to map a shut down socket to returning EOF.
let len = cmp::min(buf.len(), i32::max_value() as usize) as i32;
unsafe {
match c::recv(self.0, buf.as_mut_ptr() as *mut c_void,
buf.len() as i32, 0) {
match c::recv(self.0, buf.as_mut_ptr() as *mut c_void, len, 0) {
-1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0),
-1 => Err(last_error()),
n => Ok(n as usize)
Expand Down

0 comments on commit f3be73c

Please sign in to comment.