56
56
57
57
extern zend_long php_getuid (void );
58
58
59
- static php_mail_header_value_error_type php_mail_build_headers_check_field_value (zval * val )
59
+ static php_mail_header_value_error_type php_mail_build_headers_check_field_value (const zend_string * value )
60
60
{
61
61
size_t len = 0 ;
62
- zend_string * value = Z_STR_P (val );
63
62
64
63
/* https://tools.ietf.org/html/rfc2822#section-2.2.1 */
65
64
/* https://tools.ietf.org/html/rfc2822#section-2.2.3 */
@@ -100,74 +99,55 @@ static php_mail_header_value_error_type php_mail_build_headers_check_field_value
100
99
return NO_HEADER_ERROR ;
101
100
}
102
101
103
-
104
- static bool php_mail_build_headers_check_field_name (zend_string * key )
102
+ static bool php_mail_build_headers_check_field_name (const zend_string * key )
105
103
{
106
104
size_t len = 0 ;
107
105
108
106
/* https://tools.ietf.org/html/rfc2822#section-2.2 */
109
- while (len < key -> len ) {
110
- if (* (key -> val + len ) < 33 || * (key -> val + len ) > 126 || * (key -> val + len ) == ':' ) {
111
- return FAILURE ;
107
+ while (len < ZSTR_LEN ( key ) ) {
108
+ if (* (ZSTR_VAL ( key ) + len ) < 33 || * (ZSTR_VAL ( key ) + len ) > 126 || * (ZSTR_VAL ( key ) + len ) == ':' ) {
109
+ return false ;
112
110
}
113
111
len ++ ;
114
112
}
115
- return SUCCESS ;
113
+ return true ;
116
114
}
117
115
118
-
119
- static void php_mail_build_headers_elems (smart_str * s , zend_string * key , zval * val );
120
-
121
- static void php_mail_build_headers_elem (smart_str * s , zend_string * key , zval * val )
116
+ static void php_mail_build_headers_elem (smart_str * s , const zend_string * key , const zend_string * val )
122
117
{
123
- switch (Z_TYPE_P (val )) {
124
- case IS_STRING :
125
- if (php_mail_build_headers_check_field_name (key ) != SUCCESS ) {
126
- zend_value_error ("Header name \"%s\" contains invalid characters" , ZSTR_VAL (key ));
127
- return ;
128
- }
129
-
130
- php_mail_header_value_error_type error_type = php_mail_build_headers_check_field_value (val );
131
- switch (error_type ) {
132
- case NO_HEADER_ERROR :
133
- break ;
134
- case CONTAINS_LF_ONLY :
135
- zend_value_error ("Header \"%s\" contains LF character that is not allowed in the header" , ZSTR_VAL (key ));
136
- return ;
137
- case CONTAINS_CR_ONLY :
138
- zend_value_error ("Header \"%s\" contains CR character that is not allowed in the header" , ZSTR_VAL (key ));
139
- return ;
140
- case CONTAINS_CRLF :
141
- zend_value_error ("Header \"%s\" contains CRLF characters that are used as a line separator and are not allowed in the header" , ZSTR_VAL (key ));
142
- return ;
143
- case CONTAINS_NULL :
144
- zend_value_error ("Header \"%s\" contains NULL character that is not allowed in the header" , ZSTR_VAL (key ));
145
- return ;
146
- default :
147
- // fallback
148
- zend_value_error ("Header \"%s\" has invalid format, or contains invalid characters" , ZSTR_VAL (key ));
149
- return ;
150
- }
151
- smart_str_append (s , key );
152
- smart_str_appendl (s , ": " , 2 );
153
- smart_str_appends (s , Z_STRVAL_P (val ));
154
- smart_str_appendl (s , "\r\n" , 2 );
155
- break ;
156
- case IS_ARRAY :
157
- php_mail_build_headers_elems (s , key , val );
118
+ php_mail_header_value_error_type error_type = php_mail_build_headers_check_field_value (val );
119
+ switch (error_type ) {
120
+ case NO_HEADER_ERROR :
158
121
break ;
122
+ case CONTAINS_LF_ONLY :
123
+ zend_value_error ("Header \"%s\" contains LF character that is not allowed in the header" , ZSTR_VAL (key ));
124
+ return ;
125
+ case CONTAINS_CR_ONLY :
126
+ zend_value_error ("Header \"%s\" contains CR character that is not allowed in the header" , ZSTR_VAL (key ));
127
+ return ;
128
+ case CONTAINS_CRLF :
129
+ zend_value_error ("Header \"%s\" contains CRLF characters that are used as a line separator and are not allowed in the header" , ZSTR_VAL (key ));
130
+ return ;
131
+ case CONTAINS_NULL :
132
+ zend_value_error ("Header \"%s\" contains NULL character that is not allowed in the header" , ZSTR_VAL (key ));
133
+ return ;
159
134
default :
160
- zend_type_error ("Header \"%s\" must be of type array|string, %s given" , ZSTR_VAL (key ), zend_zval_value_name (val ));
135
+ // fallback
136
+ zend_value_error ("Header \"%s\" has invalid format, or contains invalid characters" , ZSTR_VAL (key ));
137
+ return ;
161
138
}
139
+ smart_str_append (s , key );
140
+ smart_str_appendl (s , ": " , 2 );
141
+ smart_str_append (s , val );
142
+ smart_str_appendl (s , "\r\n" , 2 );
162
143
}
163
144
164
-
165
- static void php_mail_build_headers_elems (smart_str * s , zend_string * key , zval * val )
145
+ static void php_mail_build_headers_array (smart_str * s , const zend_string * key , const HashTable * val )
166
146
{
167
147
zend_string * tmp_key ;
168
148
zval * tmp_val ;
169
149
170
- ZEND_HASH_FOREACH_STR_KEY_VAL (Z_ARRVAL_P ( val ) , tmp_key , tmp_val ) {
150
+ ZEND_HASH_FOREACH_STR_KEY_VAL (val , tmp_key , tmp_val ) {
171
151
if (tmp_key ) {
172
152
zend_type_error ("Header \"%s\" must only contain numeric keys, \"%s\" found" , ZSTR_VAL (key ), ZSTR_VAL (tmp_key ));
173
153
break ;
@@ -177,25 +157,11 @@ static void php_mail_build_headers_elems(smart_str *s, zend_string *key, zval *v
177
157
zend_type_error ("Header \"%s\" must only contain values of type string, %s found" , ZSTR_VAL (key ), zend_zval_value_name (tmp_val ));
178
158
break ;
179
159
}
180
- php_mail_build_headers_elem (s , key , tmp_val );
160
+ // TODO Should this actually pass tmp_key?
161
+ php_mail_build_headers_elem (s , key , Z_STR_P (tmp_val ));
181
162
} ZEND_HASH_FOREACH_END ();
182
163
}
183
164
184
- #define PHP_MAIL_BUILD_HEADER_CHECK (target , s , key , val ) \
185
- do { \
186
- if (Z_TYPE_P(val) == IS_STRING) { \
187
- php_mail_build_headers_elem(&s, key, val); \
188
- } else if (Z_TYPE_P(val) == IS_ARRAY) { \
189
- if (zend_string_equals_literal_ci(key, target)) { \
190
- zend_type_error("Header \"%s\" must be of type string, array given", target); \
191
- break; \
192
- } \
193
- php_mail_build_headers_elems(&s, key, val); \
194
- } else { \
195
- zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_value_name(val)); \
196
- } \
197
- } while(0)
198
-
199
165
PHPAPI zend_string * php_mail_build_headers (HashTable * headers )
200
166
{
201
167
zend_ulong idx ;
@@ -206,39 +172,48 @@ PHPAPI zend_string *php_mail_build_headers(HashTable *headers)
206
172
ZEND_HASH_FOREACH_KEY_VAL (headers , idx , key , val ) {
207
173
if (!key ) {
208
174
zend_type_error ("Header name cannot be numeric, " ZEND_LONG_FMT " given" , idx );
209
- break ;
175
+ goto error ;
176
+ }
177
+ if (!php_mail_build_headers_check_field_name (key )) {
178
+ zend_value_error ("Header name \"%s\" contains invalid characters" , ZSTR_VAL (key ));
179
+ goto error ;
210
180
}
211
181
ZVAL_DEREF (val );
182
+ if (UNEXPECTED (Z_TYPE_P (val ) != IS_STRING && Z_TYPE_P (val ) != IS_ARRAY )) {
183
+ zend_type_error ("Header \"%s\" must be of type array|string, %s given" , ZSTR_VAL (key ), zend_zval_value_name (val ));
184
+ goto error ;
185
+ }
186
+
212
187
/* https://tools.ietf.org/html/rfc2822#section-3.6 */
213
- if (zend_string_equals_literal_ci (key , "orig-date" )) {
214
- PHP_MAIL_BUILD_HEADER_CHECK ("orig-date" , s , key , val );
215
- } else if (zend_string_equals_literal_ci (key , "from" )) {
216
- PHP_MAIL_BUILD_HEADER_CHECK ("from" , s , key , val );
217
- } else if (zend_string_equals_literal_ci (key , "sender" )) {
218
- PHP_MAIL_BUILD_HEADER_CHECK ("sender" , s , key , val );
219
- } else if (zend_string_equals_literal_ci (key , "reply-to" )) {
220
- PHP_MAIL_BUILD_HEADER_CHECK ("reply-to" , s , key , val );
221
- } else if (zend_string_equals_literal_ci (key , "to" )) {
222
- zend_value_error ("The additional headers cannot contain the \"To\" header" );
223
- } else if (zend_string_equals_literal_ci (key , "cc" )) {
224
- PHP_MAIL_BUILD_HEADER_CHECK ("cc" , s , key , val );
225
- } else if (zend_string_equals_literal_ci (key , "bcc" )) {
226
- PHP_MAIL_BUILD_HEADER_CHECK ("bcc" , s , key , val );
227
- } else if (zend_string_equals_literal_ci (key , "message-id" )) {
228
- PHP_MAIL_BUILD_HEADER_CHECK ("message-id" , s , key , val );
229
- } else if (zend_string_equals_literal_ci (key , "references" )) {
230
- PHP_MAIL_BUILD_HEADER_CHECK ("references" , s , key , val );
231
- } else if (zend_string_equals_literal_ci (key , "in-reply-to" )) {
232
- PHP_MAIL_BUILD_HEADER_CHECK ("in-reply-to" , s , key , val );
188
+ if (
189
+ zend_string_equals_literal_ci (key , "orig-date" )
190
+ || zend_string_equals_literal_ci (key , "from" )
191
+ || zend_string_equals_literal_ci (key , "sender" )
192
+ || zend_string_equals_literal_ci (key , "reply-to" )
193
+ || zend_string_equals_literal_ci (key , "cc" )
194
+ || zend_string_equals_literal_ci (key , "bcc" )
195
+ || zend_string_equals_literal_ci (key , "message-id" )
196
+ || zend_string_equals_literal_ci (key , "references" )
197
+ || zend_string_equals_literal_ci (key , "in-reply-to" )
198
+ ) {
199
+ if (UNEXPECTED (Z_TYPE_P (val ) == IS_ARRAY )) {
200
+ zend_type_error ("Header \"%s\" must be of type string, array given" , ZSTR_VAL (key ));
201
+ goto error ;
202
+ }
203
+ ZEND_ASSERT (Z_TYPE_P (val ) == IS_STRING );
204
+ php_mail_build_headers_elem (& s , key , Z_STR_P (val ));
233
205
} else if (zend_string_equals_literal_ci (key , "subject" )) {
234
206
zend_value_error ("The additional headers cannot contain the \"Subject\" header" );
207
+ goto error ;
208
+ } else if (zend_string_equals_literal_ci (key , "to" )) {
209
+ zend_value_error ("The additional headers cannot contain the \"To\" header" );
210
+ goto error ;
235
211
} else {
236
212
if (Z_TYPE_P (val ) == IS_STRING ) {
237
- php_mail_build_headers_elem (& s , key , val );
238
- } else if (Z_TYPE_P (val ) == IS_ARRAY ) {
239
- php_mail_build_headers_elems (& s , key , val );
213
+ php_mail_build_headers_elem (& s , key , Z_STR_P (val ));
240
214
} else {
241
- zend_type_error ("Header \"%s\" must be of type array|string, %s given" , ZSTR_VAL (key ), zend_zval_value_name (val ));
215
+ ZEND_ASSERT (Z_TYPE_P (val ) == IS_ARRAY );
216
+ php_mail_build_headers_array (& s , key , Z_ARRVAL_P (val ));
242
217
}
243
218
}
244
219
@@ -253,6 +228,10 @@ PHPAPI zend_string *php_mail_build_headers(HashTable *headers)
253
228
smart_str_0 (& s );
254
229
255
230
return s .s ;
231
+
232
+ error :
233
+ smart_str_free (& s );
234
+ return NULL ;
256
235
}
257
236
258
237
0 commit comments