@@ -22,7 +22,7 @@ static void php_url_encode_scalar(zval *scalar, smart_str *form_str,
2222 int encoding_type , zend_ulong index_int ,
2323 const char * index_string , size_t index_string_len ,
2424 const char * num_prefix , size_t num_prefix_len ,
25- const char * key_prefix , size_t key_prefix_len ,
25+ const zend_string * key_prefix ,
2626 const char * key_suffix , size_t key_suffix_len ,
2727 const zend_string * arg_sep )
2828{
@@ -31,7 +31,7 @@ static void php_url_encode_scalar(zval *scalar, smart_str *form_str,
3131 }
3232 /* Simple key=value */
3333 if (key_prefix ) {
34- smart_str_appendl (form_str , key_prefix , key_prefix_len );
34+ smart_str_append (form_str , key_prefix );
3535 }
3636 if (index_string ) {
3737 zend_string * encoded_key ;
@@ -96,14 +96,13 @@ static void php_url_encode_scalar(zval *scalar, smart_str *form_str,
9696/* {{{ php_url_encode_hash */
9797PHPAPI void php_url_encode_hash_ex (HashTable * ht , smart_str * formstr ,
9898 const char * num_prefix , size_t num_prefix_len ,
99- const char * key_prefix , size_t key_prefix_len ,
99+ const zend_string * key_prefix ,
100100 const char * key_suffix , size_t key_suffix_len ,
101101 zval * type , const zend_string * arg_sep , int enc_type )
102102{
103103 zend_string * key = NULL ;
104- char * newprefix , * p ;
105104 const char * prop_name ;
106- size_t newprefix_len , prop_len ;
105+ size_t prop_len ;
107106 zend_ulong idx ;
108107 zval * zdata = NULL ;
109108 ZEND_ASSERT (ht );
@@ -155,70 +154,67 @@ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
155154
156155 ZVAL_DEREF (zdata );
157156 if (Z_TYPE_P (zdata ) == IS_ARRAY || Z_TYPE_P (zdata ) == IS_OBJECT ) {
157+ zend_string * new_prefix ;
158158 if (key ) {
159- zend_string * ekey ;
159+ zend_string * encoded_key ;
160160 if (enc_type == PHP_QUERY_RFC3986 ) {
161- ekey = php_raw_url_encode (prop_name , prop_len );
161+ encoded_key = php_raw_url_encode (prop_name , prop_len );
162162 } else {
163- ekey = php_url_encode (prop_name , prop_len );
163+ encoded_key = php_url_encode (prop_name , prop_len );
164164 }
165- newprefix_len = key_suffix_len + ZSTR_LEN (ekey ) + key_prefix_len + 3 /* %5B */ ;
166- newprefix = emalloc (newprefix_len + 1 );
167- p = newprefix ;
168165
169166 if (key_prefix ) {
170- memcpy (p , key_prefix , key_prefix_len );
171- p += key_prefix_len ;
172- }
173-
174- memcpy (p , ZSTR_VAL (ekey ), ZSTR_LEN (ekey ));
175- p += ZSTR_LEN (ekey );
176- zend_string_free (ekey );
167+ /* zend_string_concat4() */
168+ size_t len = ZSTR_LEN (key_prefix ) + ZSTR_LEN (encoded_key ) + key_suffix_len + strlen ("%5B" );
169+ new_prefix = zend_string_alloc (len , 0 );
177170
178- if (key_suffix ) {
179- memcpy (p , key_suffix , key_suffix_len );
180- p += key_suffix_len ;
171+ memcpy (ZSTR_VAL (new_prefix ), ZSTR_VAL (key_prefix ), ZSTR_LEN (key_prefix ));
172+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ), ZSTR_VAL (encoded_key ), ZSTR_LEN (encoded_key ));
173+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ) + ZSTR_LEN (encoded_key ), key_suffix , key_suffix_len );
174+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ) + ZSTR_LEN (encoded_key ) + key_suffix_len , "%5B" , strlen ("%5B" ));
175+ ZSTR_VAL (new_prefix )[len ] = '\0' ;
176+ } else {
177+ new_prefix = zend_string_concat2 (ZSTR_VAL (encoded_key ), ZSTR_LEN (encoded_key ), "%5B" , strlen ("%5B" ));
181178 }
182- * (p ++ ) = '%' ;
183- * (p ++ ) = '5' ;
184- * (p ++ ) = 'B' ;
185- * p = '\0' ;
186- } else {
187- char * ekey ;
188- size_t ekey_len ;
189- /* Is an integer key */
190- ekey_len = spprintf (& ekey , 0 , ZEND_LONG_FMT , idx );
191- newprefix_len = key_prefix_len + num_prefix_len + ekey_len + key_suffix_len + 3 /* %5B */ ;
192- newprefix = emalloc (newprefix_len + 1 );
193- p = newprefix ;
179+ zend_string_release_ex (encoded_key , false);
180+ } else { /* is integer index */
181+ char * index_int_as_str ;
182+ size_t index_int_as_str_len ;
194183
195- if (key_prefix ) {
196- memcpy (p , key_prefix , key_prefix_len );
197- p += key_prefix_len ;
198- }
184+ index_int_as_str_len = spprintf (& index_int_as_str , 0 , ZEND_LONG_FMT , idx );
199185
200- if (num_prefix ) {
201- memcpy ( p , num_prefix , num_prefix_len );
202- p += num_prefix_len ;
203- }
186+ if (key_prefix && num_prefix ) {
187+ /* zend_string_concat5() */
188+ size_t len = ZSTR_LEN ( key_prefix ) + num_prefix_len + index_int_as_str_len + key_suffix_len + strlen ( "%5B" ) ;
189+ new_prefix = zend_string_alloc ( len , 0 );
204190
205- memcpy (p , ekey , ekey_len );
206- p += ekey_len ;
207- efree (ekey );
191+ memcpy (ZSTR_VAL (new_prefix ), ZSTR_VAL (key_prefix ), ZSTR_LEN (key_prefix ));
192+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ), num_prefix , num_prefix_len );
193+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ) + num_prefix_len , index_int_as_str , index_int_as_str_len );
194+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ) + num_prefix_len + index_int_as_str_len , key_suffix , key_suffix_len );
195+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ) + num_prefix_len + index_int_as_str_len + key_suffix_len , "%5B" , strlen ("%5B" ));
196+ ZSTR_VAL (new_prefix )[len ] = '\0' ;
197+ } else if (key_prefix ) {
198+ /* zend_string_concat4() */
199+ size_t len = ZSTR_LEN (key_prefix ) + index_int_as_str_len + key_suffix_len + strlen ("%5B" );
200+ new_prefix = zend_string_alloc (len , 0 );
208201
209- if (key_suffix ) {
210- memcpy (p , key_suffix , key_suffix_len );
211- p += key_suffix_len ;
202+ memcpy (ZSTR_VAL (new_prefix ), ZSTR_VAL (key_prefix ), ZSTR_LEN (key_prefix ));
203+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ), index_int_as_str , index_int_as_str_len );
204+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ) + index_int_as_str_len , key_suffix , key_suffix_len );
205+ memcpy (ZSTR_VAL (new_prefix ) + ZSTR_LEN (key_prefix ) + index_int_as_str_len + key_suffix_len , "%5B" , strlen ("%5B" ));
206+ ZSTR_VAL (new_prefix )[len ] = '\0' ;
207+ } else if (num_prefix ) {
208+ new_prefix = zend_string_concat3 (num_prefix , num_prefix_len , index_int_as_str , index_int_as_str_len , "%5B" , strlen ("%5B" ));
209+ } else {
210+ new_prefix = zend_string_concat2 (index_int_as_str , index_int_as_str_len , "%5B" , strlen ("%5B" ));
212211 }
213- * (p ++ ) = '%' ;
214- * (p ++ ) = '5' ;
215- * (p ++ ) = 'B' ;
216- * p = '\0' ;
212+ efree (index_int_as_str );
217213 }
218214 GC_TRY_PROTECT_RECURSION (ht );
219- php_url_encode_hash_ex (HASH_OF (zdata ), formstr , NULL , 0 , newprefix , newprefix_len , "%5D" , 3 , (Z_TYPE_P (zdata ) == IS_OBJECT ? zdata : NULL ), arg_sep , enc_type );
215+ php_url_encode_hash_ex (HASH_OF (zdata ), formstr , NULL , 0 , new_prefix , "%5D" , 3 , (Z_TYPE_P (zdata ) == IS_OBJECT ? zdata : NULL ), arg_sep , enc_type );
220216 GC_TRY_UNPROTECT_RECURSION (ht );
221- efree ( newprefix );
217+ zend_string_release_ex ( new_prefix , false );
222218 } else if (Z_TYPE_P (zdata ) == IS_NULL || Z_TYPE_P (zdata ) == IS_RESOURCE ) {
223219 /* Skip these types */
224220 continue ;
@@ -227,7 +223,7 @@ PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
227223 enc_type , idx ,
228224 prop_name , prop_len ,
229225 num_prefix , num_prefix_len ,
230- key_prefix , key_prefix_len ,
226+ key_prefix ,
231227 key_suffix , key_suffix_len ,
232228 arg_sep );
233229 }
@@ -254,7 +250,7 @@ PHP_FUNCTION(http_build_query)
254250 Z_PARAM_LONG (enc_type )
255251 ZEND_PARSE_PARAMETERS_END ();
256252
257- php_url_encode_hash_ex (HASH_OF (formdata ), & formstr , prefix , prefix_len , NULL , 0 , NULL , 0 , (Z_TYPE_P (formdata ) == IS_OBJECT ? formdata : NULL), arg_sep , (int )enc_type );
253+ php_url_encode_hash_ex (HASH_OF (formdata ), & formstr , prefix , prefix_len , /* key_prefix */ NULL , NULL , 0 , (Z_TYPE_P (formdata ) == IS_OBJECT ? formdata : NULL), arg_sep , (int )enc_type );
258254
259255 RETURN_STR (smart_str_extract (& formstr ));
260256}
0 commit comments