File tree 2 files changed +24
-0
lines changed 2 files changed +24
-0
lines changed Original file line number Diff line number Diff line change @@ -1506,6 +1506,15 @@ impl<S: Read + Write> SslStream<S> {
1506
1506
/// This is particularly useful with a nonblocking socket, where the error
1507
1507
/// value will identify if OpenSSL is waiting on read or write readiness.
1508
1508
pub fn ssl_read ( & mut self , buf : & mut [ u8 ] ) -> Result < usize , Error > {
1509
+ // The intepretation of the return code here is a little odd with a
1510
+ // zero-length write. OpenSSL will likely correctly report back to us
1511
+ // that it read zero bytes, but zero is also the sentinel for "error".
1512
+ // To avoid that confusion short-circuit that logic and return quickly
1513
+ // if `buf` has a length of zero.
1514
+ if buf. len ( ) == 0 {
1515
+ return Ok ( 0 )
1516
+ }
1517
+
1509
1518
let ret = self . ssl . read ( buf) ;
1510
1519
if ret > 0 {
1511
1520
Ok ( ret as usize )
@@ -1523,6 +1532,11 @@ impl<S: Read + Write> SslStream<S> {
1523
1532
/// This is particularly useful with a nonblocking socket, where the error
1524
1533
/// value will identify if OpenSSL is waiting on read or write readiness.
1525
1534
pub fn ssl_write ( & mut self , buf : & [ u8 ] ) -> Result < usize , Error > {
1535
+ // See above for why we short-circuit on zero-length buffers
1536
+ if buf. len ( ) == 0 {
1537
+ return Ok ( 0 )
1538
+ }
1539
+
1526
1540
let ret = self . ssl . write ( buf) ;
1527
1541
if ret > 0 {
1528
1542
Ok ( ret as usize )
Original file line number Diff line number Diff line change @@ -421,6 +421,16 @@ fn test_write() {
421
421
stream. flush ( ) . unwrap ( ) ;
422
422
}
423
423
424
+ #[ test]
425
+ fn zero_length_buffers ( ) {
426
+ let ( _s, stream) = Server :: new ( ) ;
427
+ let ctx = SslContext :: builder ( SslMethod :: tls ( ) ) . unwrap ( ) ;
428
+ let mut stream = Ssl :: new ( & ctx. build ( ) ) . unwrap ( ) . connect ( stream) . unwrap ( ) ;
429
+
430
+ assert_eq ! ( stream. write( b"" ) . unwrap( ) , 0 ) ;
431
+ assert_eq ! ( stream. read( & mut [ ] ) . unwrap( ) , 0 ) ;
432
+ }
433
+
424
434
run_test ! ( get_peer_certificate, |method, stream| {
425
435
let ctx = SslContext :: builder( method) . unwrap( ) ;
426
436
let stream = Ssl :: new( & ctx. build( ) ) . unwrap( ) . connect( stream) . unwrap( ) ;
You can’t perform that action at this time.
0 commit comments