@@ -351,6 +351,23 @@ static zend_string *php_stream_http_response_headers_parse(php_stream_wrapper *w
351351 return NULL ;
352352}
353353
354+ static inline void smart_str_append_header_value (smart_str * dest , const zend_string * value , const char * header_name )
355+ {
356+ const char * src = ZSTR_VAL (value );
357+ size_t len = ZSTR_LEN (value );
358+ size_t i = 0 ;
359+ while (i < len && src [i ] != '\r' && src [i ] != '\n' ) {
360+ i ++ ;
361+ }
362+ if (i < len ) {
363+ smart_str_appendl (dest , src , i );
364+ php_error_docref (NULL , E_WARNING ,
365+ "Header %s value contains newline characters and has been truncated" , header_name );
366+ } else {
367+ smart_str_append (dest , value );
368+ }
369+ }
370+
354371static php_stream * php_stream_url_wrap_http_ex (php_stream_wrapper * wrapper ,
355372 const char * path , const char * mode , int options , zend_string * * opened_path ,
356373 php_stream_context * context , int redirect_max , int flags ,
@@ -361,7 +378,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
361378 int use_ssl ;
362379 int use_proxy = 0 ;
363380 zend_string * tmp = NULL ;
364- char * ua_str = NULL ;
381+ zend_string * ua_str = NULL ;
365382 zval * ua_zval = NULL , * tmpzval = NULL , ssl_proxy_peer_name ;
366383 int reqok = 0 ;
367384 char * http_header_line = NULL ;
@@ -788,7 +805,7 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
788805 /* if the user has configured who they are, send a From: line */
789806 if (!(have_header & HTTP_HEADER_FROM ) && FG (from_address )) {
790807 smart_str_appends (& req_buf , "From: " );
791- smart_str_appends (& req_buf , FG (from_address ));
808+ smart_str_append_header_value (& req_buf , FG (from_address ), "From" );
792809 smart_str_appends (& req_buf , "\r\n" );
793810 }
794811
@@ -817,30 +834,15 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
817834 if (context &&
818835 (ua_zval = php_stream_context_get_option (context , "http" , "user_agent" )) != NULL &&
819836 Z_TYPE_P (ua_zval ) == IS_STRING ) {
820- ua_str = Z_STRVAL_P (ua_zval );
837+ ua_str = Z_STR_P (ua_zval );
821838 } else if (FG (user_agent )) {
822839 ua_str = FG (user_agent );
823840 }
824841
825- if (((have_header & HTTP_HEADER_USER_AGENT ) == 0 ) && ua_str ) {
826- #define _UA_HEADER "User-Agent: %s\r\n"
827- char * ua ;
828- size_t ua_len ;
829-
830- ua_len = sizeof (_UA_HEADER ) + strlen (ua_str );
831-
832- /* ensure the header is only sent if user_agent is not blank */
833- if (ua_len > sizeof (_UA_HEADER )) {
834- ua = emalloc (ua_len + 1 );
835- if ((ua_len = slprintf (ua , ua_len , _UA_HEADER , ua_str )) > 0 ) {
836- ua [ua_len ] = 0 ;
837- smart_str_appendl (& req_buf , ua , ua_len );
838- } else {
839- php_stream_wrapper_warn_nt (wrapper , context , options , InvalidHeader ,
840- "Cannot construct User-agent header" );
841- }
842- efree (ua );
843- }
842+ if (((have_header & HTTP_HEADER_USER_AGENT ) == 0 ) && ua_str && ZSTR_LEN (ua_str )) {
843+ smart_str_appends (& req_buf , "User-Agent: " );
844+ smart_str_append_header_value (& req_buf , ua_str , "User-Agent" );
845+ smart_str_appends (& req_buf , "\r\n" );
844846 }
845847
846848 if (user_headers ) {
0 commit comments