2121//! [`bitmask-core`](https://github.com/diba-io/bitmask-core) BDK integration. Bring your own
2222//! wallet and http client.
2323
24+ use std:: io:: { BufRead , BufReader } ;
25+
2426use bitcoin:: psbt:: Psbt ;
2527use bitcoin:: { FeeRate , ScriptBuf , Weight } ;
2628use error:: { BuildSenderError , InternalBuildSenderError } ;
@@ -29,7 +31,7 @@ use url::Url;
2931use super :: * ;
3032use crate :: psbt:: PsbtExt ;
3133use crate :: request:: Request ;
32- use crate :: PjUri ;
34+ use crate :: { PjUri , MAX_CONTENT_LENGTH } ;
3335
3436#[ derive( Clone ) ]
3537pub struct SenderBuilder < ' a > {
@@ -272,9 +274,15 @@ impl V1Context {
272274 self ,
273275 response : & mut impl std:: io:: Read ,
274276 ) -> Result < Psbt , ResponseError > {
275- let mut res_str = String :: new ( ) ;
276- response. read_to_string ( & mut res_str) . map_err ( InternalValidationError :: Io ) ?;
277- let proposal = Psbt :: from_str ( & res_str) . map_err ( |_| ResponseError :: parse ( & res_str) ) ?;
277+ let mut buf_reader = BufReader :: with_capacity ( MAX_CONTENT_LENGTH + 1 , response) ;
278+ let buffer = buf_reader. fill_buf ( ) . map_err ( InternalValidationError :: Io ) ?;
279+
280+ if buffer. len ( ) > MAX_CONTENT_LENGTH {
281+ return Err ( ResponseError :: from ( InternalValidationError :: ContentTooLarge ) ) ;
282+ }
283+
284+ let res_str = std:: str:: from_utf8 ( buffer) . map_err ( |_| InternalValidationError :: Parse ) ?;
285+ let proposal = Psbt :: from_str ( res_str) . map_err ( |_| ResponseError :: parse ( & res_str) ) ?;
278286 self . psbt_context . process_proposal ( proposal) . map_err ( Into :: into)
279287 }
280288}
@@ -283,6 +291,12 @@ impl V1Context {
283291mod test {
284292 use crate :: send:: error:: { ResponseError , WellKnownError } ;
285293
294+ /// From BIP-174 test vector
295+ const INVALID_PSBT : & str = "AgAAAAEmgXE3Ht/yhek3re6ks3t4AAwFZsuzrWRkFxPKQhcb9gAAAABqRzBEAiBwsiRRI+a/R01gxbUMBD1MaRpdJDXwmjSnZiqdwlF5CgIgATKcqdrPKAvfMHQOwDkEIkIsgctFg5RXrrdvwS7dlbMBIQJlfRGNM1e44PTCzUbbezn22cONmnCry5st5dyNv+TOMf7///8C09/1BQAAAAAZdqkU0MWZA8W6woaHYOkP1SGkZlqnZSCIrADh9QUAAAAAF6kUNUXm4zuDLEcFDyTT7rk8nAOUi8eHsy4TAA==" ;
296+
297+ /// From the BIP-78 test vector
298+ const PJ_PROPOSAL_PSBT : & str = "cHNidP8BAJwCAAAAAo8nutGgJdyYGXWiBEb45Hoe9lWGbkxh/6bNiOJdCDuDAAAAAAD+////jye60aAl3JgZdaIERvjkeh72VYZuTGH/ps2I4l0IO4MBAAAAAP7///8CJpW4BQAAAAAXqRQd6EnwadJ0FQ46/q6NcutaawlEMIcACT0AAAAAABepFHdAltvPSGdDwi9DR+m0af6+i2d6h9MAAAAAAQEgqBvXBQAAAAAXqRTeTh6QYcpZE1sDWtXm1HmQRUNU0IcAAQEggIQeAAAAAAAXqRTI8sv5ymFHLIjkZNRrNXSEXZHY1YcBBxcWABRfgGZV5ZJMkgTC1RvlOU9L+e2iEAEIawJHMEQCIGe7e0DfJaVPRYEKWxddL2Pr0G37BoKz0lyNa02O2/tWAiB7ZVgBoF4s8MHocYWWmo4Q1cyV2wl7MX0azlqa8NBENAEhAmXWPPW0G3yE3HajBOb7gO7iKzHSmZ0o0w0iONowcV+tAAAA" ;
299+
286300 fn create_v1_context ( ) -> super :: V1Context {
287301 super :: V1Context { psbt_context : crate :: send:: test:: create_psbt_context ( ) }
288302 }
@@ -311,4 +325,33 @@ mod test {
311325 _ => panic ! ( "Expected unrecognized JSON error" ) ,
312326 }
313327 }
328+
329+ #[ test]
330+ fn process_response_valid ( ) {
331+ let mut cursor = std:: io:: Cursor :: new ( PJ_PROPOSAL_PSBT . as_bytes ( ) ) ;
332+
333+ let ctx = create_v1_context ( ) ;
334+ let response = ctx. process_response ( & mut cursor) ;
335+ assert ! ( response. is_ok( ) )
336+ }
337+
338+ #[ test]
339+ fn process_response_invalid_psbt ( ) {
340+ let mut cursor = std:: io:: Cursor :: new ( INVALID_PSBT . as_bytes ( ) ) ;
341+
342+ let ctx = create_v1_context ( ) ;
343+ let response = ctx. process_response ( & mut cursor) . unwrap_err ( ) ;
344+ assert ! ( matches!( response, ResponseError :: Validation ( _) ) )
345+ }
346+
347+ #[ test]
348+ fn process_response_invalid_utf8 ( ) {
349+ // In UTF-8, 0xF0 represents the start of a 4-byte sequence, so 0xF0 by itself is invalid
350+ let invalid_utf8 = [ 0xF0 ] ;
351+ let mut cursor = std:: io:: Cursor :: new ( invalid_utf8) ;
352+
353+ let ctx = create_v1_context ( ) ;
354+ let response = ctx. process_response ( & mut cursor) . unwrap_err ( ) ;
355+ assert ! ( matches!( response, ResponseError :: Validation ( _) ) )
356+ }
314357}
0 commit comments