1
- use futures_core:: ready;
2
1
use futures_core:: future:: Future ;
2
+ use futures_core:: ready;
3
3
use futures_core:: task:: { Context , Poll } ;
4
4
use futures_io:: AsyncRead ;
5
5
use std:: io;
@@ -28,11 +28,16 @@ impl<'a, R: AsyncRead + ?Sized + Unpin> ReadToEnd<'a, R> {
28
28
}
29
29
}
30
30
31
- struct Guard < ' a > { buf : & ' a mut Vec < u8 > , len : usize }
31
+ struct Guard < ' a > {
32
+ buf : & ' a mut Vec < u8 > ,
33
+ len : usize ,
34
+ }
32
35
33
36
impl Drop for Guard < ' _ > {
34
37
fn drop ( & mut self ) {
35
- unsafe { self . buf . set_len ( self . len ) ; }
38
+ unsafe {
39
+ self . buf . set_len ( self . len ) ;
40
+ }
36
41
}
37
42
}
38
43
@@ -51,8 +56,10 @@ pub(super) fn read_to_end_internal<R: AsyncRead + ?Sized>(
51
56
buf : & mut Vec < u8 > ,
52
57
start_len : usize ,
53
58
) -> Poll < io:: Result < usize > > {
54
- let mut g = Guard { len : buf. len ( ) , buf } ;
55
- let ret;
59
+ let mut g = Guard {
60
+ len : buf. len ( ) ,
61
+ buf,
62
+ } ;
56
63
loop {
57
64
if g. len == g. buf . len ( ) {
58
65
unsafe {
@@ -63,24 +70,24 @@ pub(super) fn read_to_end_internal<R: AsyncRead + ?Sized>(
63
70
}
64
71
}
65
72
66
- match ready ! ( rd . as_mut ( ) . poll_read ( cx , & mut g. buf[ g. len..] ) ) {
67
- Ok ( 0 ) => {
68
- ret = Poll :: Ready ( Ok ( g. len - start_len) ) ;
69
- break ;
70
- }
71
- Ok ( n ) => g . len += n ,
72
- Err ( e ) => {
73
- ret = Poll :: Ready ( Err ( e ) ) ;
74
- break ;
73
+ let buf = & mut g. buf [ g. len ..] ;
74
+ match ready ! ( rd . as_mut ( ) . poll_read ( cx , buf ) ) {
75
+ Ok ( 0 ) => return Poll :: Ready ( Ok ( g. len - start_len) ) ,
76
+ Ok ( n ) => {
77
+ // We can't allow bogus values from read. If it is too large, the returned vec could have its length
78
+ // set past its capacity, or if it overflows the vec could be shortened which could create an invalid
79
+ // string if this is called via read_to_string.
80
+ assert ! ( n <= buf . len ( ) ) ;
81
+ g . len += n ;
75
82
}
83
+ Err ( e) => return Poll :: Ready ( Err ( e) ) ,
76
84
}
77
85
}
78
-
79
- ret
80
86
}
81
87
82
88
impl < A > Future for ReadToEnd < ' _ , A >
83
- where A : AsyncRead + ?Sized + Unpin ,
89
+ where
90
+ A : AsyncRead + ?Sized + Unpin ,
84
91
{
85
92
type Output = io:: Result < usize > ;
86
93
0 commit comments