@@ -50,11 +50,15 @@ PHP_FUNCTION(stream_socket_pair)
5050 zend_long domain , type , protocol ;
5151 php_stream * s1 , * s2 ;
5252 php_socket_t pair [2 ];
53+ zval * zcontext = NULL ;
54+ php_stream_context * context = NULL ;
5355
54- ZEND_PARSE_PARAMETERS_START (3 , 3 )
56+ ZEND_PARSE_PARAMETERS_START (3 , 4 )
5557 Z_PARAM_LONG (domain )
5658 Z_PARAM_LONG (type )
5759 Z_PARAM_LONG (protocol )
60+ Z_PARAM_OPTIONAL
61+ Z_PARAM_RESOURCE_OR_NULL (zcontext )
5862 ZEND_PARSE_PARAMETERS_END ();
5963
6064 if (0 != socketpair ((int )domain , (int )type , (int )protocol , pair )) {
@@ -65,20 +69,21 @@ PHP_FUNCTION(stream_socket_pair)
6569 }
6670
6771 php_stream_error_operation_begin ();
72+ context = php_stream_context_from_zval (zcontext , 0 );
6873
6974 s1 = php_stream_sock_open_from_socket (pair [0 ], 0 );
7075 if (s1 == NULL ) {
7176 close (pair [0 ]);
7277 close (pair [1 ]);
73- php_stream_error_operation_end (NULL );
78+ php_stream_error_operation_end (context );
7479 php_error_docref (NULL , E_WARNING , "Failed to open stream from socketpair" );
7580 RETURN_FALSE ;
7681 }
7782 s2 = php_stream_sock_open_from_socket (pair [1 ], 0 );
7883 if (s2 == NULL ) {
7984 php_stream_free (s1 , PHP_STREAM_FREE_CLOSE );
8085 close (pair [1 ]);
81- php_stream_error_operation_end (NULL );
86+ php_stream_error_operation_end (context );
8287 php_error_docref (NULL , E_WARNING , "Failed to open stream from socketpair" );
8388 RETURN_FALSE ;
8489 }
@@ -93,7 +98,7 @@ PHP_FUNCTION(stream_socket_pair)
9398 add_next_index_resource (return_value , s1 -> res );
9499 add_next_index_resource (return_value , s2 -> res );
95100
96- php_stream_error_operation_end (NULL );
101+ php_stream_error_operation_end (context );
97102}
98103/* }}} */
99104#endif
@@ -506,23 +511,27 @@ PHP_FUNCTION(stream_copy_to_stream)
506511 zend_long maxlen , pos = 0 ;
507512 bool maxlen_is_null = 1 ;
508513 size_t len ;
514+ zval * zcontext = NULL ;
515+ php_stream_context * context = NULL ;
509516
510- ZEND_PARSE_PARAMETERS_START (2 , 4 )
517+ ZEND_PARSE_PARAMETERS_START (2 , 5 )
511518 PHP_Z_PARAM_STREAM (src )
512519 PHP_Z_PARAM_STREAM (dest )
513520 Z_PARAM_OPTIONAL
514521 Z_PARAM_LONG_OR_NULL (maxlen , maxlen_is_null )
515522 Z_PARAM_LONG (pos )
523+ Z_PARAM_RESOURCE_OR_NULL (zcontext )
516524 ZEND_PARSE_PARAMETERS_END ();
517525
518526 if (maxlen_is_null ) {
519527 maxlen = PHP_STREAM_COPY_ALL ;
520528 }
521529
522530 php_stream_error_operation_begin ();
531+ context = php_stream_context_from_zval (zcontext , 0 ) ;
523532
524533 if (pos > 0 && php_stream_seek (src , pos , SEEK_SET ) < 0 ) {
525- php_stream_error_operation_end (NULL );
534+ php_stream_error_operation_end (context );
526535 php_error_docref (NULL , E_WARNING , "Failed to seek to position " ZEND_LONG_FMT " in the stream" , pos );
527536 RETURN_FALSE ;
528537 }
@@ -532,7 +541,7 @@ PHP_FUNCTION(stream_copy_to_stream)
532541 } else {
533542 RETVAL_LONG (len );
534543 }
535- php_stream_error_operation_end (NULL );
544+ php_stream_error_operation_end (context );
536545}
537546/* }}} */
538547
@@ -778,7 +787,7 @@ static int stream_array_emulate_read_fd_set(zval *stream_array)
778787/* {{{ Runs the select() system call on the sets of streams with a timeout specified by tv_sec and tv_usec */
779788PHP_FUNCTION (stream_select )
780789{
781- zval * r_array , * w_array , * e_array ;
790+ zval * r_array , * w_array , * e_array , * zcontext = NULL ;
782791 struct timeval tv , * tv_p = NULL ;
783792 fd_set rfds , wfds , efds ;
784793 php_socket_t max_fd = 0 ;
@@ -787,21 +796,24 @@ PHP_FUNCTION(stream_select)
787796 bool secnull ;
788797 bool usecnull = 1 ;
789798 int set_count , max_set_count = 0 ;
799+ php_stream_context * context = NULL ;
790800
791- ZEND_PARSE_PARAMETERS_START (4 , 5 )
801+ ZEND_PARSE_PARAMETERS_START (4 , 6 )
792802 Z_PARAM_ARRAY_EX2 (r_array , 1 , 1 , 0 )
793803 Z_PARAM_ARRAY_EX2 (w_array , 1 , 1 , 0 )
794804 Z_PARAM_ARRAY_EX2 (e_array , 1 , 1 , 0 )
795805 Z_PARAM_LONG_OR_NULL (sec , secnull )
796806 Z_PARAM_OPTIONAL
797807 Z_PARAM_LONG_OR_NULL (usec , usecnull )
808+ Z_PARAM_RESOURCE_OR_NULL (zcontext )
798809 ZEND_PARSE_PARAMETERS_END ();
799810
800811 FD_ZERO (& rfds );
801812 FD_ZERO (& wfds );
802813 FD_ZERO (& efds );
803814
804815 php_stream_error_operation_begin ();
816+ context = php_stream_context_from_zval (zcontext , 0 );
805817
806818 if (r_array != NULL) {
807819 set_count = stream_array_to_fd_set (Z_ARR_P (r_array ), & rfds , & max_fd );
@@ -825,7 +837,7 @@ PHP_FUNCTION(stream_select)
825837 }
826838
827839 if (!sets ) {
828- php_stream_error_operation_end (NULL );
840+ php_stream_error_operation_end (context );
829841 zend_value_error ("No stream arrays were passed" );
830842 RETURN_THROWS ();
831843 }
@@ -836,7 +848,7 @@ PHP_FUNCTION(stream_select)
836848
837849 if (secnull && !usecnull ) {
838850 if (usec != 0 ) {
839- php_stream_error_operation_end (NULL );
851+ php_stream_error_operation_end (context );
840852 zend_argument_value_error (5 , "must be null when argument #4 ($seconds) is null" );
841853 RETURN_THROWS ();
842854 }
@@ -845,11 +857,11 @@ PHP_FUNCTION(stream_select)
845857 /* If seconds is not set to null, build the timeval, else we wait indefinitely */
846858 if (!secnull ) {
847859 if (sec < 0 ) {
848- php_stream_error_operation_end (NULL );
860+ php_stream_error_operation_end (context );
849861 zend_argument_value_error (4 , "must be greater than or equal to 0" );
850862 RETURN_THROWS ();
851863 } else if (usec < 0 ) {
852- php_stream_error_operation_end (NULL );
864+ php_stream_error_operation_end (context );
853865 zend_argument_value_error (5 , "must be greater than or equal to 0" );
854866 RETURN_THROWS ();
855867 }
@@ -866,7 +878,7 @@ PHP_FUNCTION(stream_select)
866878 if (r_array != NULL ) {
867879 retval = stream_array_emulate_read_fd_set (r_array );
868880 if (retval > 0 ) {
869- php_stream_error_operation_end (NULL );
881+ php_stream_error_operation_end (context );
870882 if (w_array != NULL ) {
871883 zval_ptr_dtor (w_array );
872884 ZVAL_EMPTY_ARRAY (w_array );
@@ -880,7 +892,7 @@ PHP_FUNCTION(stream_select)
880892 }
881893
882894 retval = php_select (max_fd + 1 , & rfds , & wfds , & efds , tv_p );
883- php_stream_error_operation_end (NULL );
895+ php_stream_error_operation_end (context );
884896
885897 if (retval == -1 ) {
886898 php_error_docref (NULL , E_WARNING , "Unable to select [%d]: %s (max_fd=" PHP_SOCKET_FMT ")" ,
@@ -1207,6 +1219,23 @@ PHP_FUNCTION(stream_context_get_default)
12071219}
12081220/* }}} */
12091221
1222+ /* Check if options contain stream error handling settings */
1223+ static bool php_stream_context_options_has_error_settings (const HashTable * options )
1224+ {
1225+ zval * stream_options = zend_hash_str_find (options , ZEND_STRL ("stream" ));
1226+ if (!stream_options ) {
1227+ return false;
1228+ }
1229+
1230+ ZVAL_DEREF (stream_options );
1231+ if (Z_TYPE_P (stream_options ) != IS_ARRAY ) {
1232+ return false;
1233+ }
1234+
1235+ return zend_hash_str_exists (Z_ARRVAL_P (stream_options ), ZEND_STRL ("error_mode" ))
1236+ || zend_hash_str_exists (Z_ARRVAL_P (stream_options ), ZEND_STRL ("error_store" ));
1237+ }
1238+
12101239/* {{{ Set default file/stream context, returns the context as a resource */
12111240PHP_FUNCTION (stream_context_set_default )
12121241{
@@ -1222,6 +1251,11 @@ PHP_FUNCTION(stream_context_set_default)
12221251 }
12231252 context = FG (default_context );
12241253
1254+ if (php_stream_context_options_has_error_settings (options )) {
1255+ zend_value_error ("Stream error handling options cannot be set on the default context" );
1256+ RETURN_THROWS ();
1257+ }
1258+
12251259 if (parse_context_options (context , options ) == FAILURE ) {
12261260 RETURN_THROWS ();
12271261 }
@@ -1636,12 +1670,15 @@ PHP_FUNCTION(stream_resolve_include_path)
16361670/* {{{ */
16371671PHP_FUNCTION (stream_is_local )
16381672{
1639- zval * zstream ;
1673+ zval * zstream , * zcontext = NULL ;
16401674 php_stream * stream = NULL ;
16411675 php_stream_wrapper * wrapper = NULL ;
1676+ php_stream_context * context = NULL ;
16421677
1643- ZEND_PARSE_PARAMETERS_START (1 , 1 )
1678+ ZEND_PARSE_PARAMETERS_START (1 , 2 )
16441679 Z_PARAM_ZVAL (zstream )
1680+ Z_PARAM_OPTIONAL
1681+ Z_PARAM_RESOURCE_OR_NULL (zcontext )
16451682 ZEND_PARSE_PARAMETERS_END ();
16461683
16471684 if (Z_TYPE_P (zstream ) == IS_RESOURCE ) {
@@ -1653,8 +1690,9 @@ PHP_FUNCTION(stream_is_local)
16531690 }
16541691
16551692 php_stream_error_operation_begin ();
1693+ context = php_stream_context_from_zval (zcontext , 0 );
16561694 wrapper = php_stream_locate_url_wrapper (Z_STRVAL_P (zstream ), NULL , 0 );
1657- php_stream_error_operation_end (NULL );
1695+ php_stream_error_operation_end (context );
16581696 }
16591697
16601698 RETURN_BOOL (wrapper && wrapper -> is_url == 0 );
0 commit comments