@@ -279,9 +279,11 @@ static void php_zval_filter(zval *value, zend_long filter, zend_long flags, zval
279
279
280
280
static unsigned int php_sapi_filter (int arg , const char * var , char * * val , size_t val_len , size_t * new_val_len ) /* {{{ */
281
281
{
282
- zval new_var , raw_var ;
282
+ zval raw_var , new_var ;
283
283
zval * array_ptr = NULL , * orig_array_ptr = NULL ;
284
284
int retval = 0 ;
285
+ int is_raw = (IF_G (default_filter ) == FILTER_UNSAFE_RAW );
286
+ size_t var_len = strlen (var );
285
287
286
288
assert (* val != NULL );
287
289
@@ -313,10 +315,54 @@ static unsigned int php_sapi_filter(int arg, const char *var, char **val, size_t
313
315
* more specific cookies with the less specific ones.
314
316
*/
315
317
if (arg == PARSE_COOKIE && orig_array_ptr &&
316
- zend_symtable_str_exists (Z_ARRVAL_P (orig_array_ptr ), var , strlen ( var ) )) {
318
+ zend_symtable_str_exists (Z_ARRVAL_P (orig_array_ptr ), var , var_len )) {
317
319
return 0 ;
318
320
}
319
321
322
+ /*
323
+ * Fast path: if the default filter is UNSAFE_RAW, we can build a single zval, register it twice, and be done
324
+ */
325
+ if (is_raw )
326
+ {
327
+ if (array_ptr || orig_array_ptr )
328
+ {
329
+ if (val_len )
330
+ {
331
+ ZVAL_STRINGL (& raw_var , * val , val_len );
332
+ } else
333
+ {
334
+ ZVAL_EMPTY_STRING (& raw_var );
335
+ }
336
+ if (array_ptr )
337
+ {
338
+ php_register_variable_ex (var , & raw_var , array_ptr );
339
+ }
340
+ if (orig_array_ptr )
341
+ {
342
+ php_register_variable_ex (var , & raw_var , orig_array_ptr );
343
+ }
344
+
345
+ if (retval )
346
+ {
347
+ if (new_val_len )
348
+ {
349
+ * new_val_len = Z_STRLEN_P (& raw_var );
350
+ }
351
+ efree (* val );
352
+ if (Z_STRLEN_P (& raw_var ))
353
+ {
354
+ * val = estrndup (Z_STRVAL_P (& raw_var ), Z_STRLEN_P (& raw_var ));
355
+ } else
356
+ {
357
+ * val = strdup ("" );
358
+ }
359
+ }
360
+
361
+ zval_ptr_dtor (& raw_var );
362
+ }
363
+ return retval ;
364
+ }
365
+
320
366
if (array_ptr ) {
321
367
/* Store the RAW variable internally */
322
368
ZVAL_STRINGL (& raw_var , * val , val_len );
0 commit comments