Skip to content

Commit c1ddcbb

Browse files
Merge pull request #632 from palaviv/socket-errors
Socket OSError
2 parents 56bb6d2 + 8df0e46 commit c1ddcbb

File tree

3 files changed

+80
-48
lines changed

3 files changed

+80
-48
lines changed

tests/snippets/stdlib_socket.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,29 @@
2929
with assertRaises(TypeError):
3030
s.connect(("127.0.0.1", 8888, 8888))
3131

32+
with assertRaises(OSError):
33+
# Lets hope nobody is listening on port 1
34+
s.connect(("127.0.0.1", 1))
35+
3236
with assertRaises(TypeError):
3337
s.bind(("127.0.0.1", 8888, 8888))
3438

39+
with assertRaises(OSError):
40+
# Lets hope nobody run this test on machine with ip 1.2.3.4
41+
s.bind(("1.2.3.4", 8888))
42+
3543
with assertRaises(TypeError):
3644
s.bind((888, 8888))
3745

46+
s.close()
47+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
48+
s.bind(("127.0.0.1", 0))
49+
with assertRaises(OSError):
50+
s.recv(100)
51+
52+
with assertRaises(OSError):
53+
s.send(MESSAGE_A)
54+
3855
s.close()
3956

4057
# UDP
@@ -73,3 +90,15 @@
7390
assert recv_b == MESSAGE_B
7491
sock1.close()
7592
sock3.close()
93+
94+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
95+
with assertRaises(OSError):
96+
s.bind(("1.2.3.4", 888))
97+
98+
s.close()
99+
### Errors
100+
with assertRaises(OSError):
101+
socket.socket(100, socket.SOCK_STREAM)
102+
103+
with assertRaises(OSError):
104+
socket.socket(socket.AF_INET, 1000)

vm/src/builtins.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
802802
"StopIteration" => ctx.exceptions.stop_iteration.clone(),
803803
"ZeroDivisionError" => ctx.exceptions.zero_division_error.clone(),
804804
"KeyError" => ctx.exceptions.key_error.clone(),
805+
"OSError" => ctx.exceptions.os_error.clone(),
805806
});
806807

807808
#[cfg(not(target_arch = "wasm32"))]

vm/src/stdlib/socket.rs

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ enum AddressFamily {
2424
}
2525

2626
impl AddressFamily {
27-
fn from_i32(value: i32) -> AddressFamily {
27+
fn from_i32(vm: &mut VirtualMachine, value: i32) -> Result<AddressFamily, PyObjectRef> {
2828
match value {
29-
1 => AddressFamily::Unix,
30-
2 => AddressFamily::Inet,
31-
3 => AddressFamily::Inet6,
32-
_ => panic!("Unknown value: {}", value),
29+
1 => Ok(AddressFamily::Unix),
30+
2 => Ok(AddressFamily::Inet),
31+
3 => Ok(AddressFamily::Inet6),
32+
_ => Err(vm.new_os_error(format!("Unknown address family value: {}", value))),
3333
}
3434
}
3535
}
@@ -41,11 +41,11 @@ enum SocketKind {
4141
}
4242

4343
impl SocketKind {
44-
fn from_i32(value: i32) -> SocketKind {
44+
fn from_i32(vm: &mut VirtualMachine, value: i32) -> Result<SocketKind, PyObjectRef> {
4545
match value {
46-
1 => SocketKind::Stream,
47-
2 => SocketKind::Dgram,
48-
_ => panic!("Unknown value: {}", value),
46+
1 => Ok(SocketKind::Stream),
47+
2 => Ok(SocketKind::Dgram),
48+
_ => Err(vm.new_os_error(format!("Unknown socket kind value: {}", value))),
4949
}
5050
}
5151
}
@@ -146,8 +146,9 @@ fn socket_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
146146
]
147147
);
148148

149-
let address_family = AddressFamily::from_i32(objint::get_value(family_int).to_i32().unwrap());
150-
let kind = SocketKind::from_i32(objint::get_value(kind_int).to_i32().unwrap());
149+
let address_family =
150+
AddressFamily::from_i32(vm, objint::get_value(family_int).to_i32().unwrap())?;
151+
let kind = SocketKind::from_i32(vm, objint::get_value(kind_int).to_i32().unwrap())?;
151152

152153
let socket = RefCell::new(Socket::new(address_family, kind));
153154

@@ -171,21 +172,18 @@ fn socket_connect(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
171172
let mut socket = get_socket(zelf);
172173

173174
match socket.socket_kind {
174-
SocketKind::Stream => {
175-
if let Ok(stream) = TcpStream::connect(address_string) {
175+
SocketKind::Stream => match TcpStream::connect(address_string) {
176+
Ok(stream) => {
176177
socket.con = Some(Connection::TcpStream(stream));
177178
Ok(vm.get_none())
178-
} else {
179-
// TODO: Socket error
180-
Err(vm.new_type_error("socket failed".to_string()))
181179
}
182-
}
180+
Err(s) => Err(vm.new_os_error(s.to_string())),
181+
},
183182
SocketKind::Dgram => {
184183
if let Some(Connection::UdpSocket(con)) = &socket.con {
185184
match con.connect(address_string) {
186185
Ok(_) => Ok(vm.get_none()),
187-
// TODO: Socket error
188-
Err(_) => Err(vm.new_type_error("socket failed".to_string())),
186+
Err(s) => Err(vm.new_os_error(s.to_string())),
189187
}
190188
} else {
191189
Err(vm.new_type_error("".to_string()))
@@ -206,24 +204,20 @@ fn socket_bind(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
206204
let mut socket = get_socket(zelf);
207205

208206
match socket.socket_kind {
209-
SocketKind::Stream => {
210-
if let Ok(stream) = TcpListener::bind(address_string) {
207+
SocketKind::Stream => match TcpListener::bind(address_string) {
208+
Ok(stream) => {
211209
socket.con = Some(Connection::TcpListener(stream));
212210
Ok(vm.get_none())
213-
} else {
214-
// TODO: Socket error
215-
Err(vm.new_type_error("socket failed".to_string()))
216211
}
217-
}
218-
SocketKind::Dgram => {
219-
if let Ok(dgram) = UdpSocket::bind(address_string) {
212+
Err(s) => Err(vm.new_os_error(s.to_string())),
213+
},
214+
SocketKind::Dgram => match UdpSocket::bind(address_string) {
215+
Ok(dgram) => {
220216
socket.con = Some(Connection::UdpSocket(dgram));
221217
Ok(vm.get_none())
222-
} else {
223-
// TODO: Socket error
224-
Err(vm.new_type_error("socket failed".to_string()))
225218
}
226-
}
219+
Err(s) => Err(vm.new_os_error(s.to_string())),
220+
},
227221
}
228222
}
229223

@@ -272,7 +266,7 @@ fn socket_accept(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
272266

273267
let (tcp_stream, addr) = match ret {
274268
Ok((socket, addr)) => (socket, addr),
275-
_ => return Err(vm.new_type_error("".to_string())),
269+
Err(s) => return Err(vm.new_os_error(s.to_string())),
276270
};
277271

278272
let socket = RefCell::new(Socket {
@@ -303,7 +297,10 @@ fn socket_recv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
303297

304298
let mut buffer = vec![0u8; objint::get_value(bufsize).to_usize().unwrap()];
305299
match socket.con {
306-
Some(ref mut v) => v.read_exact(&mut buffer).unwrap(),
300+
Some(ref mut v) => match v.read_exact(&mut buffer) {
301+
Ok(_) => (),
302+
Err(s) => return Err(vm.new_os_error(s.to_string())),
303+
},
307304
None => return Err(vm.new_type_error("".to_string())),
308305
};
309306
Ok(vm.ctx.new_bytes(buffer))
@@ -326,7 +323,7 @@ fn socket_recvfrom(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
326323

327324
let addr = match ret {
328325
Ok((_size, addr)) => addr,
329-
_ => return Err(vm.new_type_error("".to_string())),
326+
Err(s) => return Err(vm.new_os_error(s.to_string())),
330327
};
331328

332329
let addr_tuple = get_addr_tuple(vm, addr)?;
@@ -343,7 +340,10 @@ fn socket_send(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
343340
let mut socket = get_socket(zelf);
344341

345342
match socket.con {
346-
Some(ref mut v) => v.write(&objbytes::get_value(&bytes)).unwrap(),
343+
Some(ref mut v) => match v.write(&objbytes::get_value(&bytes)) {
344+
Ok(_) => (),
345+
Err(s) => return Err(vm.new_os_error(s.to_string())),
346+
},
347347
None => return Err(vm.new_type_error("".to_string())),
348348
};
349349
Ok(vm.get_none())
@@ -366,22 +366,24 @@ fn socket_sendto(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
366366
match socket.socket_kind {
367367
SocketKind::Dgram => {
368368
match socket.con {
369-
Some(ref mut v) => {
370-
if let Ok(_) = v.send_to(&objbytes::get_value(&bytes), address_string) {
371-
Ok(vm.get_none())
372-
} else {
373-
Err(vm.new_type_error("socket failed".to_string()))
374-
}
375-
}
369+
Some(ref mut v) => match v.send_to(&objbytes::get_value(&bytes), address_string) {
370+
Ok(_) => Ok(vm.get_none()),
371+
Err(s) => Err(vm.new_os_error(s.to_string())),
372+
},
376373
None => {
377374
// Doing implicit bind
378-
if let Ok(dgram) = UdpSocket::bind("0.0.0.0:0") {
379-
if let Ok(_) = dgram.send_to(&objbytes::get_value(&bytes), address_string) {
380-
socket.con = Some(Connection::UdpSocket(dgram));
381-
return Ok(vm.get_none());
375+
match UdpSocket::bind("0.0.0.0:0") {
376+
Ok(dgram) => {
377+
match dgram.send_to(&objbytes::get_value(&bytes), address_string) {
378+
Ok(_) => {
379+
socket.con = Some(Connection::UdpSocket(dgram));
380+
Ok(vm.get_none())
381+
}
382+
Err(s) => Err(vm.new_os_error(s.to_string())),
383+
}
382384
}
385+
Err(s) => Err(vm.new_os_error(s.to_string())),
383386
}
384-
Err(vm.new_type_error("socket failed".to_string()))
385387
}
386388
}
387389
}
@@ -408,7 +410,7 @@ fn socket_getsockname(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
408410

409411
match addr {
410412
Ok(addr) => get_addr_tuple(vm, addr),
411-
_ => Err(vm.new_type_error("".to_string())),
413+
Err(s) => Err(vm.new_os_error(s.to_string())),
412414
}
413415
}
414416

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy