@@ -137,6 +137,17 @@ where
137137 // is the message name. strings (byte arrays) are length-prefixed,
138138 // so we've just read the length in the first 4 bytes
139139 let name_size = BigEndian :: read_i32 ( & first_bytes) as usize ;
140+ if let Some ( max_size) = self . config . max_string_size ( ) {
141+ if name_size > max_size {
142+ return Err ( crate :: Error :: Protocol ( ProtocolError :: new (
143+ ProtocolErrorKind :: SizeLimit ,
144+ format ! (
145+ "Message name size {} exceeds maximum allowed size of {}" ,
146+ name_size, max_size
147+ ) ,
148+ ) ) ) ;
149+ }
150+ }
140151 let mut name_buf: Vec < u8 > = vec ! [ 0 ; name_size] ;
141152 self . transport . read_exact ( & mut name_buf) ?;
142153 let name = String :: from_utf8 ( name_buf) ?;
@@ -1265,6 +1276,56 @@ mod tests {
12651276 }
12661277 }
12671278
1279+ #[ test]
1280+ fn must_enforce_string_size_limit_on_non_strict_message_name ( ) {
1281+ let mem = TBufferChannel :: with_capacity ( 100 , 100 ) ;
1282+ let ( r_mem, mut w_mem) = mem. split ( ) . unwrap ( ) ;
1283+
1284+ let config = TConfiguration :: builder ( )
1285+ . max_string_size ( Some ( 1000 ) )
1286+ . build ( )
1287+ . unwrap ( ) ;
1288+ // non-strict: the first 4 bytes are the (positive) message-name length
1289+ let mut i_prot = TBinaryInputProtocol :: with_config ( r_mem, false , config) ;
1290+
1291+ w_mem. set_readable_bytes ( & [ 0x00 , 0x00 , 0x07 , 0xD0 ] ) ;
1292+
1293+ let result = i_prot. read_message_begin ( ) ;
1294+ assert ! ( result. is_err( ) ) ;
1295+ match result {
1296+ Err ( crate :: Error :: Protocol ( e) ) => {
1297+ assert_eq ! ( e. kind, ProtocolErrorKind :: SizeLimit ) ;
1298+ assert ! ( e
1299+ . message
1300+ . contains( "Message name size 2000 exceeds maximum allowed size of 1000" ) ) ;
1301+ }
1302+ _ => panic ! ( "Expected protocol error with SizeLimit" ) ,
1303+ }
1304+ }
1305+
1306+ #[ test]
1307+ fn must_allow_non_strict_message_name_at_limit ( ) {
1308+ let mem = TBufferChannel :: with_capacity ( 100 , 100 ) ;
1309+ let ( r_mem, mut w_mem) = mem. split ( ) . unwrap ( ) ;
1310+
1311+ let config = TConfiguration :: builder ( )
1312+ . max_string_size ( Some ( 5 ) )
1313+ . build ( )
1314+ . unwrap ( ) ;
1315+ // non-strict: the first 4 bytes are the (positive) message-name length
1316+ let mut i_prot = TBinaryInputProtocol :: with_config ( r_mem, false , config) ;
1317+
1318+ // name length 5 (== limit), name "hello", message type Call, sequence 0
1319+ w_mem. set_readable_bytes ( & [
1320+ 0x00 , 0x00 , 0x00 , 0x05 , b'h' , b'e' , b'l' , b'l' , b'o' , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 ,
1321+ ] ) ;
1322+
1323+ let ident = i_prot. read_message_begin ( ) . unwrap ( ) ;
1324+ assert_eq ! ( ident. name, "hello" ) ;
1325+ assert_eq ! ( ident. message_type, TMessageType :: Call ) ;
1326+ assert_eq ! ( ident. sequence_number, 0 ) ;
1327+ }
1328+
12681329 #[ test]
12691330 fn must_allow_strings_within_limit ( ) {
12701331 let mem = TBufferChannel :: with_capacity ( 100 , 100 ) ;
0 commit comments