4545 //TODO 'L' => array('zend_long*, '), // long
4646 'o ' => array ('zval** ' ), //object
4747 'O ' => array ('zval** ' , 'zend_class_entry* ' ), // object of given type
48- 'p ' => array ('char** ' , 'size_t* ' ), // valid path
4948 'P ' => array ('zend_string** ' ), // valid path
5049 'r ' => array ('zval** ' ), // resource
51- 's ' => array ('char** ' , 'size_t* ' ), // string
5250 'S ' => array ('zend_string** ' ), // string
5351 'z ' => array ('zval** ' ), // zval*
5452 'Z ' => array ('zval*** ' ) // zval**
53+ // 's', 'p' handled separately
5554);
5655
5756/** reports an error, according to its level */
@@ -131,7 +130,7 @@ function get_vars($txt)
131130
132131
133132/** run diagnostic checks against one var. */
134- function check_param ($ db , $ idx , $ exp , $ optional )
133+ function check_param_allow_uninit ($ db , $ idx , $ exp , $ optional )
135134{
136135 global $ error_few_vars_given ;
137136
@@ -149,14 +148,18 @@ function check_param($db, $idx, $exp, $optional)
149148 error ("{$ db [$ idx ][0 ]}: expected ' $ exp' but got ' {$ db [$ idx ][1 ]}' [ " .($ idx +1 ).'] ' );
150149 }
151150
152- if ($ optional && !$ db [$ idx ][2 ]) {
153- error ("optional var not initialized: {$ db [$ idx ][0 ]} [ " .($ idx +1 ).'] ' , 1 );
154-
155- } elseif (!$ optional && $ db [$ idx ][2 ]) {
151+ if (!$ optional && $ db [$ idx ][2 ]) {
156152 error ("not optional var is initialized: {$ db [$ idx ][0 ]} [ " .($ idx +1 ).'] ' , 2 );
157153 }
158154}
159155
156+ function check_param ($ db , $ idx , $ exp , $ optional )
157+ {
158+ check_param_allow_uninit ($ db , $ idx , $ exp , $ optional );
159+ if ($ optional && !$ db [$ idx ][2 ]) {
160+ error ("optional var not initialized: {$ db [$ idx ][0 ]} [ " .($ idx +1 ).'] ' , 1 );
161+ }
162+ }
160163
161164/** fetch params passed to zend_parse_params*() */
162165function get_params ($ vars , $ str )
@@ -227,15 +230,15 @@ function check_function($name, $txt, $offset)
227230
228231 // separate_zval_if_not_ref
229232 case '/ ' :
230- if (! in_array ($ last_char , array ('r ' , 'z ' ))) {
231- error ("the '/' specifier cannot be applied to ' $ last_char' " );
233+ if (in_array ($ last_char , array ('l ' , 'L ' , ' d ' , ' b ' ))) {
234+ error ("the '/' specifier should not be applied to ' $ last_char' " );
232235 }
233236 break ;
234237
235238 // nullable arguments
236239 case '! ' :
237- if (! in_array ($ last_char , array ('a ' , 'C ' , 'f ' , 'h ' , ' o ' , ' O ' , ' r ' , ' s ' , ' t ' , ' z ' , ' Z ' ))) {
238- error ( " the '!' specifier cannot be applied to ' $ last_char ' " );
240+ if (in_array ($ last_char , array ('l ' , 'L ' , 'd ' , 'b ' ))) {
241+ check_param ( $ params , ++ $ j , ' zend_bool* ' , $ optional );
239242 }
240243 break ;
241244
@@ -251,6 +254,15 @@ function check_function($name, $txt, $offset)
251254 }
252255 break ;
253256
257+ case 's ' :
258+ case 'p ' :
259+ check_param_allow_uninit ($ params , ++$ j , 'char** ' , $ optional );
260+ check_param_allow_uninit ($ params , ++$ j , 'size_t* ' , $ optional );
261+ if ($ optional && !$ params [$ j -1 ][2 ] && !$ params [$ j ][2 ]) {
262+ error ("one of optional vars {$ params [$ j -1 ][0 ]} or {$ params [$ j ][0 ]} must be initialized " , 1 );
263+ }
264+ break ;
265+
254266 default :
255267 if (isset ($ API_params [$ char ])) {
256268 foreach ($ API_params [$ char ] as $ exp ) {
0 commit comments