30
30
#endif
31
31
32
32
#include "php_globals.h"
33
+ #include "zend_smart_str.h"
33
34
34
35
35
36
/* Implementation of the language Header() function */
@@ -81,12 +82,10 @@ PHPAPI int php_header(void)
81
82
82
83
PHPAPI int php_setcookie (zend_string * name , zend_string * value , time_t expires , zend_string * path , zend_string * domain , int secure , int httponly , zend_string * samesite , int url_encode )
83
84
{
84
- char * cookie ;
85
- size_t len = sizeof ("Set-Cookie: " );
86
85
zend_string * dt ;
87
86
sapi_header_line ctr = {0 };
88
87
int result ;
89
- zend_string * encoded_value = NULL ;
88
+ smart_str buf = { 0 } ;
90
89
91
90
if (!ZSTR_LEN (name )) {
92
91
zend_error ( E_WARNING , "Cookie names must not be empty" );
@@ -112,97 +111,82 @@ PHPAPI int php_setcookie(zend_string *name, zend_string *value, time_t expires,
112
111
return FAILURE ;
113
112
}
114
113
115
- len += ZSTR_LEN (name );
116
- if (value ) {
117
- if (url_encode ) {
118
- encoded_value = php_url_encode (ZSTR_VAL (value ), ZSTR_LEN (value ));
119
- len += ZSTR_LEN (encoded_value );
120
- } else {
121
- encoded_value = zend_string_copy (value );
122
- len += ZSTR_LEN (encoded_value );
123
- }
124
- }
125
-
126
- if (path ) {
127
- len += ZSTR_LEN (path );
128
- }
129
- if (domain ) {
130
- len += ZSTR_LEN (domain );
131
- }
132
- if (samesite ) {
133
- len += ZSTR_LEN (samesite );
134
- }
135
-
136
- cookie = emalloc (len + 100 );
137
-
138
114
if (value == NULL || ZSTR_LEN (value ) == 0 ) {
139
115
/*
140
116
* MSIE doesn't delete a cookie when you set it to a null value
141
117
* so in order to force cookies to be deleted, even on MSIE, we
142
118
* pick an expiry date in the past
143
119
*/
144
120
dt = php_format_date ("D, d-M-Y H:i:s T" , sizeof ("D, d-M-Y H:i:s T" )- 1 , 1 , 0 );
145
- snprintf (cookie , len + 100 , "Set-Cookie: %s=deleted; expires=%s; Max-Age=0" , ZSTR_VAL (name ), ZSTR_VAL (dt ));
121
+ smart_str_appends (& buf , "Set-Cookie: " );
122
+ smart_str_append (& buf , name );
123
+ smart_str_appends (& buf , "=deleted; expires=" );
124
+ smart_str_append (& buf , dt );
125
+ smart_str_appends (& buf , "; Max-Age=0" );
146
126
zend_string_free (dt );
147
127
} else {
148
- snprintf (cookie , len + 100 , "Set-Cookie: %s=%s" , ZSTR_VAL (name ), value ? ZSTR_VAL (encoded_value ) : "" );
128
+ smart_str_appends (& buf , "Set-Cookie: " );
129
+ smart_str_append (& buf , name );
130
+ smart_str_appendc (& buf , '=' );
131
+ if (url_encode ) {
132
+ zend_string * encoded_value = php_url_encode (ZSTR_VAL (value ), ZSTR_LEN (value ));
133
+ smart_str_append (& buf , encoded_value );
134
+ zend_string_release_ex (encoded_value , 0 );
135
+ } else {
136
+ smart_str_append (& buf , value );
137
+ }
149
138
if (expires > 0 ) {
150
139
const char * p ;
151
- char tsdelta [13 ];
152
140
double diff ;
153
141
154
- strlcat ( cookie , COOKIE_EXPIRES , len + 100 );
142
+ smart_str_appends ( & buf , COOKIE_EXPIRES );
155
143
dt = php_format_date ("D, d-M-Y H:i:s T" , sizeof ("D, d-M-Y H:i:s T" )- 1 , expires , 0 );
156
144
/* check to make sure that the year does not exceed 4 digits in length */
157
145
p = zend_memrchr (ZSTR_VAL (dt ), '-' , ZSTR_LEN (dt ));
158
146
if (!p || * (p + 5 ) != ' ' ) {
159
147
zend_string_free (dt );
160
- efree (cookie );
161
- zend_string_release_ex (encoded_value , 0 );
148
+ smart_str_free (& buf );
162
149
zend_error (E_WARNING , "Expiry date cannot have a year greater than 9999" );
163
150
return FAILURE ;
164
151
}
165
- strlcat (cookie , ZSTR_VAL (dt ), len + 100 );
152
+
153
+ smart_str_append (& buf , dt );
166
154
zend_string_free (dt );
167
155
168
156
diff = difftime (expires , time (NULL ));
169
157
if (diff < 0 ) {
170
158
diff = 0 ;
171
159
}
172
- snprintf (tsdelta , sizeof (tsdelta ), ZEND_LONG_FMT , (zend_long ) diff );
173
- strlcat (cookie , COOKIE_MAX_AGE , len + 100 );
174
- strlcat (cookie , tsdelta , len + 100 );
175
- }
176
- }
177
160
178
- if (encoded_value ) {
179
- zend_string_release_ex (encoded_value , 0 );
161
+ smart_str_appends (& buf , COOKIE_MAX_AGE );
162
+ smart_str_append_long (& buf , (zend_long ) diff );
163
+ }
180
164
}
181
165
182
166
if (path && ZSTR_LEN (path )) {
183
- strlcat ( cookie , COOKIE_PATH , len + 100 );
184
- strlcat ( cookie , ZSTR_VAL ( path ), len + 100 );
167
+ smart_str_appends ( & buf , COOKIE_PATH );
168
+ smart_str_append ( & buf , path );
185
169
}
186
170
if (domain && ZSTR_LEN (domain )) {
187
- strlcat ( cookie , COOKIE_DOMAIN , len + 100 );
188
- strlcat ( cookie , ZSTR_VAL ( domain ), len + 100 );
171
+ smart_str_appends ( & buf , COOKIE_DOMAIN );
172
+ smart_str_append ( & buf , domain );
189
173
}
190
174
if (secure ) {
191
- strlcat ( cookie , COOKIE_SECURE , len + 100 );
175
+ smart_str_appends ( & buf , COOKIE_SECURE );
192
176
}
193
177
if (httponly ) {
194
- strlcat ( cookie , COOKIE_HTTPONLY , len + 100 );
178
+ smart_str_appends ( & buf , COOKIE_HTTPONLY );
195
179
}
196
180
if (samesite && ZSTR_LEN (samesite )) {
197
- strlcat ( cookie , COOKIE_SAMESITE , len + 100 );
198
- strlcat ( cookie , ZSTR_VAL ( samesite ), len + 100 );
181
+ smart_str_appends ( & buf , COOKIE_SAMESITE );
182
+ smart_str_append ( & buf , samesite );
199
183
}
200
184
201
- ctr .line = cookie ;
202
- ctr .line_len = (uint32_t )strlen ( cookie );
185
+ ctr .line = ZSTR_VAL ( buf . s ) ;
186
+ ctr .line_len = (uint32_t ) ZSTR_LEN ( buf . s );
203
187
204
188
result = sapi_header_op (SAPI_HEADER_ADD , & ctr );
205
- efree ( cookie );
189
+ zend_string_release ( buf . s );
206
190
return result ;
207
191
}
208
192
0 commit comments