26#ifdef HAVE_ARPA_INET_H
27# include <arpa/inet.h>
31# define INADDR_NONE ((unsigned long int) -1)
36#define FETCH_DOUBLE_OPTION(var_name, option_name) \
40 if ((option_val = zend_hash_str_find(Z_ARRVAL_P(option_array), option_name, sizeof(option_name) - 1)) != NULL) { \
41 var_name = zval_get_double(option_val); \
48#define FETCH_LONG_OPTION(var_name, option_name) \
52 if ((option_val = zend_hash_str_find(Z_ARRVAL_P(option_array), option_name, sizeof(option_name) - 1)) != NULL) { \
53 var_name = zval_get_long(option_val); \
60#define FETCH_STRING_OPTION(var_name, option_name) \
65 if ((option_val = zend_hash_str_find_deref(Z_ARRVAL_P(option_array), option_name, sizeof(option_name) - 1)) != NULL) { \
66 if (Z_TYPE_P(option_val) == IS_STRING) { \
67 var_name = Z_STRVAL_P(option_val); \
68 var_name##_len = Z_STRLEN_P(option_val); \
76#define FETCH_STR_OPTION(var_name, option_name) \
80 if ((option_val = zend_hash_str_find_deref(Z_ARRVAL_P(option_array), option_name, sizeof(option_name) - 1)) != NULL) { \
81 if (Z_TYPE_P(option_val) == IS_STRING) { \
82 var_name = Z_STR_P(option_val); \
92static int _php_filter_validate_ipv6(
const char *str,
size_t str_len,
int ip[8]);
94static int php_filter_parse_int(
const char *str,
size_t str_len,
zend_long *
ret) {
96 int sign = 0, digit = 0;
97 const char *
end = str + str_len;
109 if (*str ==
'0' && str + 1 ==
end) {
115 if (str < end && *str >=
'1' && *str <=
'9') {
116 ctx_value = ((
sign)?-1:1) * ((*(str++)) -
'0');
128 if (*str >=
'0' && *str <=
'9') {
129 digit = (*(str++) -
'0');
131 ctx_value = (ctx_value * 10) + digit;
133 ctx_value = (ctx_value * 10) - digit;
147static int php_filter_parse_octal(
const char *str,
size_t str_len,
zend_long *
ret) {
149 const char *
end = str + str_len;
152 if (*str >=
'0' && *str <=
'7') {
170static int php_filter_parse_hex(
const char *str,
size_t str_len,
zend_long *
ret) {
172 const char *
end = str + str_len;
176 if (*str >=
'0' && *str <=
'9') {
177 n = ((*(str++)) -
'0');
178 }
else if (*str >=
'a' && *str <=
'f') {
179 n = ((*(str++)) - (
'a' - 10));
180 }
else if (*str >=
'A' && *str <=
'F') {
181 n = ((*(str++)) - (
'A' - 10));
200 zend_long min_range, max_range, option_flags;
201 int min_range_set, max_range_set;
202 int allow_octal = 0, allow_hex = 0;
211 option_flags =
flags;
235 if (allow_hex && (*
p ==
'x' || *
p ==
'X')) {
240 if (php_filter_parse_hex(
p,
len, &ctx_value) < 0) {
243 }
else if (allow_octal) {
245 if (*
p ==
'o' || *
p ==
'O') {
251 if (php_filter_parse_octal(
p,
len, &ctx_value) < 0) {
254 }
else if (
len != 0) {
258 if (php_filter_parse_int(
p,
len, &ctx_value) < 0) {
263 if (
error > 0 || (min_range_set && (ctx_value < min_range)) || (max_range_set && (ctx_value > max_range))) {
291 }
else if (*str ==
'0') {
359 double min_range, max_range;
360 int min_range_set, max_range_set;
373 if (decimal_len != 1) {
384 if (thousand_len < 1) {
398 if (str <
end && (*str ==
'+' || *str ==
'-')) {
404 while (str < end && *str >=
'0' && *str <=
'9') {
408 if (str ==
end || *str == dec_sep || *str ==
'e' || *str ==
'E') {
409 if (!first &&
n != 3) {
412 if (*str == dec_sep) {
415 while (str < end && *str >=
'0' && *str <=
'9') {
419 if (*str ==
'e' || *str ==
'E') {
421 if (str <
end && (*str ==
'+' || *str ==
'-')) {
424 while (str < end && *str >=
'0' && *str <=
'9') {
445 switch (is_numeric_string(num,
p - num, &lval, &
dval, 0)) {
447 if ((min_range_set && (lval < min_range)) || (max_range_set && (lval > max_range))) {
457 if ((min_range_set && (
dval < min_range)) || (max_range_set && (
dval > max_range))) {
479 uint32_t capture_count;
507static int _php_filter_validate_domain(
char * domain,
size_t len,
zend_long flags)
520 if (l > 0 && *t ==
'.') {
531 if(*
s ==
'.' || (hostname && !isalnum((
int)*(
unsigned char *)
s))) {
538 if (*(
s + 1) ==
'.' || (hostname && (!isalnum((
int)*(
unsigned char *)(
s - 1)) || !isalnum((
int)*(
unsigned char *)(
s + 1))))) {
545 if (i > 63 || (hostname && (*
s !=
'-' || *(
s + 1) ==
'\0') && !isalnum((
int)*(
unsigned char *)
s))) {
569 const char *valid =
"-._~!$&'()*+,;=:";
572 if (isalpha(*
p) || isdigit(*
p) ||
strchr(valid, *
p)) {
574 }
else if (*
p ==
'%' &&
p -
ZSTR_VAL(str) <=
ZSTR_LEN(str) - 3 && isdigit(*(
p+1)) && isxdigit(*(
p+2))) {
583static bool php_filter_is_valid_ipv6_hostname(
const char *
s,
size_t l)
585 const char *e =
s + l;
586 const char *t = e - 1;
588 return *
s ==
'[' && *t ==
']' && _php_filter_validate_ipv6(
s + 1, l - 2,
NULL);
623 !php_filter_is_valid_ipv6_hostname(
s, l) &&
644 if ((url->
user !=
NULL && !is_userinfo_valid(url->
user))
684 uint32_t capture_count;
687 const char regexp0[] =
"/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E\\pL\\pN]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F\\pL\\pN]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E\\pL\\pN]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F\\pL\\pN]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iDu";
688 const char regexp1[] =
"/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD";
694 regexp_len =
sizeof(regexp0) - 1;
697 regexp_len =
sizeof(regexp1) - 1;
705 sregexp = zend_string_init(regexp, regexp_len, 0);
726static int _php_filter_validate_ipv4(
char *str,
size_t str_len,
int *ip)
728 const char *
end = str + str_len;
734 if (*str <
'0' || *str >
'9') {
737 leading_zero = (*str ==
'0');
739 num = ((*(str++)) -
'0');
740 while (str <
end && (*str >=
'0' && *str <=
'9')) {
741 num = num * 10 + ((*(str++)) -
'0');
742 if (num > 255 || ++m > 3) {
748 if (leading_zero && (num != 0 || m > 1))
753 }
else if (str >=
end || *(str++) !=
'.') {
761static int _php_filter_validate_ipv6(
const char *str,
size_t str_len,
int ip[8])
763 int compressed_pos = -1;
772 if (!memchr(str,
':', str_len)) {
777 ipv4 = memchr(str,
'.', str_len);
779 while (ipv4 > str && *(ipv4-1) !=
':') {
783 if (!_php_filter_validate_ipv4(ipv4, (str_len - (ipv4 - str)), ip4elm)) {
787 str_len = ipv4 - str;
792 if (ipv4[-2] !=
':') {
809 if (compressed_pos >= 0) {
812 if (ip && blocks < 8) {
815 compressed_pos = blocks++;
822 }
else if ((str - 1) ==
s) {
829 if (*str >=
'0' && *str <=
'9') {
830 num = 16 * num + (*str -
'0');
831 }
else if (*str >=
'a' && *str <=
'f') {
832 num = 16 * num + (*str -
'a') + 10;
833 }
else if (*str >=
'A' && *str <=
'F') {
834 num = 16 * num + (*str -
'A') + 10;
841 if (ip && blocks < 8) {
853 for (i = 0; i < 5; i++) {
857 ip[i++] = 256 * ip4elm[0] + ip4elm[1];
858 ip[i++] = 256 * ip4elm[2] + ip4elm[3];
859 }
else if (ip && compressed_pos >= 0 && blocks <= 8) {
861 for (i = 7; i > compressed_pos +
offset; i--) {
864 for (i = compressed_pos +
offset; i >= compressed_pos; i--) {
869 return (compressed_pos >= 0 && blocks <= 8) || blocks == 8;
875static bool ipv4_get_status_flags(
const int ip[8],
bool *global,
bool *reserved,
bool *
private)
884 }
else if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0) {
887 }
else if (ip[0] == 10) {
890 }
else if (ip[0] == 100 && ip[1] >= 64 && ip[1] <= 127) {
892 }
else if (ip[0] == 127) {
895 }
else if (ip[0] == 169 && ip[1] == 254) {
898 }
else if (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31) {
901 }
else if (ip[0] == 192 && ip[1] == 0 && ip[2] == 0) {
903 }
else if (ip[0] == 192 && ip[1] == 0 && ip[2] == 0 && ip[3] >= 0 && ip[3] <= 7) {
905 }
else if (ip[0] == 192 && ip[1] == 0 && ip[2] == 2) {
907 }
else if (ip[0] == 192 && ip[1] == 88 && ip[2] == 99) {
910 }
else if (ip[0] == 192 && ip[1] == 168) {
913 }
else if (ip[0] == 198 && ip[1] >= 18 && ip[1] <= 19) {
915 }
else if (ip[0] == 198 && ip[1] == 51 && ip[2] == 100) {
917 }
else if (ip[0] == 203 && ip[1] == 0 && ip[2] == 113) {
919 }
else if (ip[0] >= 240 && ip[1] <= 255) {
922 }
else if (ip[0] == 255 && ip[1] == 255 && ip[2] == 255 && ip[3] == 255) {
933static bool ipv6_get_status_flags(
const int ip[8],
bool *global,
bool *reserved,
bool *
private)
939 if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0 && ip[4] == 0 && ip[5] == 0 && ip[6] == 0 && ip[7] == 0) {
942 }
else if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0 && ip[4] == 0 && ip[5] == 0 && ip[6] == 0 && ip[7] == 1) {
945 }
else if (ip[0] == 0x0064 && ip[1] == 0xff9b) {
948 }
else if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0 && ip[4] == 0 && ip[5] == 0xffff) {
951 }
else if (ip[0] == 0x0100 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0) {
953 }
else if (ip[0] == 0x2001 && ip[1] == 0x0000) {
955 }
else if (ip[0] == 0x2001 && ip[1] <= 0x01ff) {
957 }
else if (ip[0] == 0x2001 && ip[1] == 0x0002 && ip[2] == 0) {
959 }
else if (ip[0] == 0x2001 && ip[1] == 0x0db8) {
961 }
else if (ip[0] == 0x2001 && ip[1] >= 0x0010 && ip[1] <= 0x001f) {
963 }
else if (ip[0] == 0x2002) {
965 }
else if (ip[0] >= 0xfc00 && ip[0] <= 0xfdff) {
968 }
else if (ip[0] >= 0xfe80 && ip[0] <= 0xfebf) {
986 bool flag_global, flag_reserved, flag_private;
1009 if (!ipv4_get_status_flags(ip, &flag_global, &flag_reserved, &flag_private)) {
1018 if (!ipv6_get_status_flags(ip, &flag_global, &flag_reserved, &flag_private)) {
1041 int tokens, length, i,
offset, exp_separator_set;
1042 size_t exp_separator_len;
1044 char *exp_separator;
1050 if (exp_separator_set && exp_separator_len != 1) {
1055 if (14 == input_len) {
1062 }
else if (17 == input_len && input[2] ==
'-') {
1067 }
else if (17 == input_len && input[2] ==
':') {
1076 if (exp_separator_set && separator != exp_separator[0]) {
1084 for (i = 0; i < tokens; i++) {
1085 offset = i * (length + 1);
1087 if (i < tokens - 1 && input[
offset + length] != separator) {
1091 if (php_filter_parse_hex(input +
offset, length, &
ret) < 0) {
strpbrk(string $string, string $characters)
strchr(string $haystack, string $needle, bool $before_needle=false)
#define RETURN_VALIDATION_FAILED
#define FILTER_FLAG_NO_RES_RANGE
#define FILTER_FLAG_NO_PRIV_RANGE
#define FILTER_FLAG_ALLOW_THOUSAND
#define FILTER_FLAG_ALLOW_HEX
#define PHP_FILTER_TRIM_DEFAULT_EX(p, len, return_if_empty)
#define FILTER_FLAG_PATH_REQUIRED
#define FILTER_FLAG_ALLOW_OCTAL
#define FILTER_FLAG_QUERY_REQUIRED
#define FILTER_FLAG_HOSTNAME
#define FILTER_FLAG_EMAIL_UNICODE
#define FILTER_FLAG_GLOBAL_RANGE
#define PHP_FILTER_TRIM_DEFAULT(p, len)
enum entity_charset charset
void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL)
#define FETCH_DOUBLE_OPTION(var_name, option_name)
void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL)
void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL)
void php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL)
void php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL)
#define FETCH_STRING_OPTION(var_name, option_name)
void php_filter_int(PHP_INPUT_FILTER_PARAM_DECL)
#define FETCH_STR_OPTION(var_name, option_name)
void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL)
#define FETCH_LONG_OPTION(var_name, option_name)
void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL)
void php_filter_validate_mac(PHP_INPUT_FILTER_PARAM_DECL)
unsigned const char * end
#define PHP_INPUT_FILTER_PARAM_DECL
void php_filter_url(PHP_INPUT_FILTER_PARAM_DECL)
PHPAPI pcre2_match_context * php_pcre_mctx(void)
PHPAPI pcre2_match_data * php_pcre_create_match_data(uint32_t capture_count, pcre2_code *re)
PHPAPI pcre2_code * pcre_get_compiled_regex(zend_string *regex, uint32_t *capture_count)
PHPAPI void php_pcre_free_match_data(pcre2_match_data *match_data)
PHPAPI php_url * php_url_parse_ex(char const *str, size_t length)
PHPAPI void php_url_free(php_url *theurl)
ZEND_API ZEND_COLD void zend_value_error(const char *format,...)
zend_string_release_ex(func->internal_function.function_name, 0)
#define strncasecmp(s1, s2, n)
ZEND_API const char * get_active_function_name(void)
#define MAX_LENGTH_OF_LONG
struct _zend_string zend_string
#define zend_string_equals_literal(str, literal)
#define zend_string_equals_literal_ci(str, c)
#define Z_STRVAL_P(zval_p)
#define Z_STRLEN_P(zval_p)
#define ZVAL_DOUBLE(z, d)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)