@@ -549,6 +549,32 @@ PHP_METHOD(XSLTProcessor, transformToXml)
549
549
}
550
550
/* }}} end XSLTProcessor::transformToXml */
551
551
552
+ static zend_string * xsl_create_parameter_key (uint32_t arg_num , const zend_string * namespace , zend_string * name )
553
+ {
554
+ if (ZSTR_LEN (namespace ) == 0 ) {
555
+ return zend_string_copy (name );
556
+ }
557
+
558
+ /* Clark notation already sets the namespace and we cannot have a double namespace declaration. */
559
+ if (ZSTR_VAL (name )[0 ] == '{' ) {
560
+ zend_argument_value_error (arg_num , "must not use clark notation when argument #1 ($namespace) is not empty" );
561
+ return NULL ;
562
+ }
563
+
564
+ /* Cannot be a QName as that would cause a namespace lookup in the document. */
565
+ if (ZSTR_VAL (name )[0 ] != ':' && strchr (ZSTR_VAL (name ), ':' )) {
566
+ zend_argument_value_error (arg_num , "must not be a QName when argument #1 ($namespace) is not empty" );
567
+ return NULL ;
568
+ }
569
+
570
+ zend_string * clark_str = zend_string_safe_alloc (1 , ZSTR_LEN (name ), 2 + ZSTR_LEN (namespace ), false);
571
+ ZSTR_VAL (clark_str )[0 ] = '{' ;
572
+ memcpy (ZSTR_VAL (clark_str ) + 1 , ZSTR_VAL (namespace ), ZSTR_LEN (namespace ));
573
+ ZSTR_VAL (clark_str )[ZSTR_LEN (namespace ) + 1 ] = '}' ;
574
+ memcpy (ZSTR_VAL (clark_str ) + 2 + ZSTR_LEN (namespace ), ZSTR_VAL (name ), ZSTR_LEN (name ) + 1 /* include '\0' */ );
575
+ return clark_str ;
576
+ }
577
+
552
578
/* {{{ */
553
579
PHP_METHOD (XSLTProcessor , setParameter )
554
580
{
@@ -557,12 +583,10 @@ PHP_METHOD(XSLTProcessor, setParameter)
557
583
zval * entry , new_string ;
558
584
HashTable * array_value ;
559
585
xsl_object * intern ;
560
- char * namespace ;
561
- size_t namespace_len ;
562
- zend_string * string_key , * name , * value = NULL ;
586
+ zend_string * namespace , * string_key , * name , * value = NULL ;
563
587
564
588
ZEND_PARSE_PARAMETERS_START (2 , 3 )
565
- Z_PARAM_STRING (namespace , namespace_len )
589
+ Z_PARAM_PATH_STR (namespace )
566
590
Z_PARAM_ARRAY_HT_OR_STR (array_value , name )
567
591
Z_PARAM_OPTIONAL
568
592
Z_PARAM_PATH_STR_OR_NULL (value )
@@ -590,19 +614,27 @@ PHP_METHOD(XSLTProcessor, setParameter)
590
614
RETURN_THROWS ();
591
615
}
592
616
617
+ zend_string * ht_key = xsl_create_parameter_key (2 , namespace , string_key );
618
+ if (!ht_key ) {
619
+ RETURN_THROWS ();
620
+ }
621
+
593
622
str = zval_try_get_string (entry );
594
623
if (UNEXPECTED (!str )) {
624
+ zend_string_release_ex (ht_key , false);
595
625
RETURN_THROWS ();
596
626
}
597
627
598
628
if (UNEXPECTED (CHECK_NULL_PATH (ZSTR_VAL (str ), ZSTR_LEN (str )))) {
599
629
zend_string_release (str );
630
+ zend_string_release_ex (ht_key , false);
600
631
zend_argument_value_error (3 , "must not contain values with any null bytes" );
601
632
RETURN_THROWS ();
602
633
}
603
634
604
635
ZVAL_STR (& tmp , str );
605
- zend_hash_update (intern -> parameter , string_key , & tmp );
636
+ zend_hash_update (intern -> parameter , ht_key , & tmp );
637
+ zend_string_release_ex (ht_key , false);
606
638
} ZEND_HASH_FOREACH_END ();
607
639
RETURN_TRUE ;
608
640
} else {
@@ -616,9 +648,15 @@ PHP_METHOD(XSLTProcessor, setParameter)
616
648
RETURN_THROWS ();
617
649
}
618
650
651
+ zend_string * key = xsl_create_parameter_key (2 , namespace , name );
652
+ if (!key ) {
653
+ RETURN_THROWS ();
654
+ }
655
+
619
656
ZVAL_STR_COPY (& new_string , value );
620
657
621
- zend_hash_update (intern -> parameter , name , & new_string );
658
+ zend_hash_update (intern -> parameter , key , & new_string );
659
+ zend_string_release_ex (key , false);
622
660
RETURN_TRUE ;
623
661
}
624
662
}
@@ -628,17 +666,21 @@ PHP_METHOD(XSLTProcessor, setParameter)
628
666
PHP_METHOD (XSLTProcessor , getParameter )
629
667
{
630
668
zval * id = ZEND_THIS ;
631
- char * namespace ;
632
- size_t namespace_len = 0 ;
633
669
zval * value ;
634
- zend_string * name ;
670
+ zend_string * namespace , * name ;
635
671
xsl_object * intern ;
636
672
637
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "sS" , & namespace , & namespace_len , & name ) == FAILURE ) {
673
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "PP" , & namespace , & name ) == FAILURE ) {
674
+ RETURN_THROWS ();
675
+ }
676
+ zend_string * key = xsl_create_parameter_key (2 , namespace , name );
677
+ if (!key ) {
638
678
RETURN_THROWS ();
639
679
}
640
680
intern = Z_XSL_P (id );
641
- if ((value = zend_hash_find (intern -> parameter , name )) != NULL ) {
681
+ value = zend_hash_find (intern -> parameter , key );
682
+ zend_string_release_ex (key , false);
683
+ if (value != NULL ) {
642
684
RETURN_STR_COPY (Z_STR_P (value ));
643
685
} else {
644
686
RETURN_FALSE ;
@@ -650,20 +692,23 @@ PHP_METHOD(XSLTProcessor, getParameter)
650
692
PHP_METHOD (XSLTProcessor , removeParameter )
651
693
{
652
694
zval * id = ZEND_THIS ;
653
- size_t namespace_len = 0 ;
654
- char * namespace ;
655
- zend_string * name ;
695
+ zend_string * namespace , * name ;
656
696
xsl_object * intern ;
657
697
658
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "sS" , & namespace , & namespace_len , & name ) == FAILURE ) {
698
+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "PP" , & namespace , & name ) == FAILURE ) {
699
+ RETURN_THROWS ();
700
+ }
701
+ zend_string * key = xsl_create_parameter_key (2 , namespace , name );
702
+ if (!key ) {
659
703
RETURN_THROWS ();
660
704
}
661
705
intern = Z_XSL_P (id );
662
- if (zend_hash_del (intern -> parameter , name ) == SUCCESS ) {
663
- RETURN_TRUE ;
706
+ if (zend_hash_del (intern -> parameter , key ) == SUCCESS ) {
707
+ RETVAL_TRUE ;
664
708
} else {
665
- RETURN_FALSE ;
709
+ RETVAL_FALSE ;
666
710
}
711
+ zend_string_release_ex (key , false);
667
712
}
668
713
/* }}} end XSLTProcessor::removeParameter */
669
714
0 commit comments