31static bool is_not_slash(
char c)
36static bool is_not_semicolon(
char c)
41static bool is_not_semicolon_or_equals(
char c)
43 return c !=
';' && c !=
'=';
46static bool is_not_quote_or_backslash(
char c)
48 return c !=
'"' && c !=
'\\';
52static bool is_http_tab_or_space(
char c)
54 return c == 0x09 || c == 0x20;
58static bool is_http_whitespace(
char c)
60 return c == 0x0A || c == 0x0D || is_http_tab_or_space(c);
64static bool is_http_quoted_string_token(
unsigned char c)
66 return c == 0x09 || (c >= 0x20 && c != 0x7F);
71static zend_always_inline size_t collect_a_sequence_of_code_points(
const char *position,
const char *
end,
bool (*condition)(
char))
73 const char *
start = position;
74 while (position <
end && condition(*position)) {
77 return position -
start;
81static zend_string *collect_an_http_quoted_string_with_extract_value(
const char *position,
const char *
end,
const char **position_out)
98 size_t length = collect_a_sequence_of_code_points(position,
end, is_not_quote_or_backslash);
104 if (position >=
end) {
109 char quote_or_backslash = *position;
115 if (quote_or_backslash ==
'\\') {
117 if (position >=
end) {
138 *position_out = position;
146static bool is_ascii_alpha_numeric(
char c)
148 return (c >=
'0' && c <=
'9') || (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z');
152static bool is_http_token(
char c)
155 || (c >= 0x23 && c <= 0x27)
156 || c == 0x2A || c == 0x2B || c == 0x2D || c == 0x2E
157 || c == 0x5E || c == 0x5F
159 || c == 0x7C || c == 0x7E
160 || is_ascii_alpha_numeric(c);
163static bool is_empty_string_or_does_not_solely_contain_http_token_code_points(
const char *
start,
size_t len)
169 if (!is_http_token(*
start)) {
178static bool solely_contains_http_quoted_string_tokens(
const char *
start,
size_t len)
181 if (!is_http_quoted_string_token(*
start)) {
192PHP_LIBXML_API
zend_string *php_libxml_sniff_charset_from_string(
const char *
start,
const char *
end)
198 while (
start <
end && is_http_whitespace(*(
end - 1))) {
205 size_t type_length = collect_a_sequence_of_code_points(
start,
end, is_not_slash);
208 if (is_empty_string_or_does_not_solely_contain_http_token_code_points(
start, type_length)) {
211 start += type_length;
222 size_t subtype_length = collect_a_sequence_of_code_points(
start,
end, is_not_semicolon);
227 if (is_empty_string_or_does_not_solely_contain_http_token_code_points(
start, subtype_length)) {
230 start += subtype_length;
240 size_t whitespace_length = collect_a_sequence_of_code_points(
start,
end, is_http_whitespace);
241 start += whitespace_length;
244 size_t parameter_name_length = collect_a_sequence_of_code_points(
start,
end, is_not_semicolon_or_equals);
245 const char *parameter_name =
start;
246 start += parameter_name_length;
267 parameter_value = collect_an_http_quoted_string_with_extract_value(
start,
end, &
start);
270 start += collect_a_sequence_of_code_points(
start,
end, is_not_semicolon);
274 size_t parameter_value_length = collect_a_sequence_of_code_points(
start,
end, is_not_semicolon);
275 parameter_value = zend_string_init(
start, parameter_value_length,
false);
276 start += parameter_name_length;
279 while (
ZSTR_LEN(parameter_value) > 0 && is_http_whitespace(
ZSTR_VAL(parameter_value)[
ZSTR_LEN(parameter_value) - 1])) {
285 if (
ZSTR_LEN(parameter_value) == 0) {
293 if (parameter_name_length ==
strlen(
"charset")
295 && solely_contains_http_quoted_string_tokens(
ZSTR_VAL(parameter_value),
ZSTR_LEN(parameter_value))) {
296 return parameter_value;
319 if (colon ==
NULL || space < colon) {
header(string $header, bool $replace=true, int $response_code=0)
unsigned const char * end
struct _php_stream php_stream
zend_string_release_ex(func->internal_function.function_name, 0)
#define strncasecmp(s1, s2, n)
#define ZEND_HASH_REVERSE_FOREACH_VAL_IND(ht, _val)
#define ZEND_HASH_FOREACH_END()
struct _zend_string zend_string
#define zend_always_inline
#define zend_string_starts_with_literal_ci(str, prefix)
#define Z_STRVAL_P(zval_p)
#define Z_STRLEN_P(zval_p)