diff options
author | Dmitry Stogov <dmitry@zend.com> | 2015-06-17 12:05:58 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2015-06-17 12:05:58 +0300 |
commit | a0b3fd78031f7d5218f73e3c9d44460c600fa2e8 (patch) | |
tree | 3722a7fe7eb62f9868f61dfae16058e028379dbd | |
parent | ff9e290438afc4c9e3d69bc88e37fd56267fe898 (diff) | |
download | php-git-a0b3fd78031f7d5218f73e3c9d44460c600fa2e8.tar.gz |
Improved variable name validation
-rw-r--r-- | ext/standard/array.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c index 527f6a3df1..a8e56c07cd 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1357,22 +1357,37 @@ PHP_FUNCTION(array_search) } /* }}} */ -static int php_valid_var_name(char *var_name, size_t var_name_len) /* {{{ */ +static zend_always_inline int php_valid_var_name(char *var_name, size_t var_name_len) /* {{{ */ { +#if 1 + /* first 256 bits for first character, and second 256 bits for the next */ + static const uint32_t charset[16] = { + /* 31 0 63 32 95 64 127 96 */ + 0x00000000, 0x00000000, 0x87fffffe, 0x07fffffe, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + /* 31 0 63 32 95 64 127 96 */ + 0x00000000, 0x03ff0000, 0x87fffffe, 0x07fffffe, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff + }; +#endif size_t i; - int ch; + uint32_t ch; - if (!var_name_len) { + if (UNEXPECTED(!var_name_len)) { return 0; } /* These are allowed as first char: [a-zA-Z_\x7f-\xff] */ - ch = (int)((unsigned char *)var_name)[0]; + ch = (uint32_t)((unsigned char *)var_name)[0]; +#if 1 + if (UNEXPECTED(!(charset[ch >> 5] & (1 << (ch & 0x1f))))) { +#else if (var_name[0] != '_' && (ch < 65 /* A */ || /* Z */ ch > 90) && (ch < 97 /* a */ || /* z */ ch > 122) && (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255) ) { +#endif return 0; } @@ -1380,13 +1395,17 @@ static int php_valid_var_name(char *var_name, size_t var_name_len) /* {{{ */ if (var_name_len > 1) { i = 1; do { - ch = (int)((unsigned char *)var_name)[i]; + ch = (uint32_t)((unsigned char *)var_name)[i]; +#if 1 + if (UNEXPECTED(!(charset[8 + (ch >> 5)] & (1 << (ch & 0x1f))))) { +#else if (var_name[i] != '_' && (ch < 48 /* 0 */ || /* 9 */ ch > 57) && (ch < 65 /* A */ || /* Z */ ch > 90) && (ch < 97 /* a */ || /* z */ ch > 122) && (ch < 127 /* 0x7f */ || /* 0xff */ ch > 255) ) { +#endif return 0; } } while (++i < var_name_len); |