mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Making ini parser typed
- Added ZEND_INI_SCANNER_TYPED mode for parse_ini_string() and parse_ini_file() - Added NULL_NULL token to separate it from BOOL_FALSE and BOOL_TRUE - Added zend_ini_copy_typed_value() function for zval initialisation - Updated RETURN_TOKEN() to observe scanner_mode
This commit is contained in:
parent
d7368c2531
commit
5270ee1aef
@ -283,7 +283,7 @@ struct _zend_ini_scanner_globals {
|
||||
char *filename;
|
||||
int lineno;
|
||||
|
||||
/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW */
|
||||
/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW, ZEND_INI_SCANNER_TYPED */
|
||||
int scanner_mode;
|
||||
};
|
||||
|
||||
|
@ -265,6 +265,7 @@ ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int s
|
||||
%token TC_QUOTED_STRING
|
||||
%token BOOL_TRUE
|
||||
%token BOOL_FALSE
|
||||
%token NULL_NULL
|
||||
%token END_OF_LINE
|
||||
%token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' '{' '}'
|
||||
%left '|' '&' '^'
|
||||
@ -291,7 +292,7 @@ statement:
|
||||
#endif
|
||||
ZEND_INI_PARSER_CB(&$1, &$3, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
|
||||
free(Z_STRVAL($1));
|
||||
free(Z_STRVAL($3));
|
||||
zval_internal_dtor(&$3);
|
||||
}
|
||||
| TC_OFFSET option_offset ']' '=' string_or_value {
|
||||
#if DEBUG_CFG_PARSER
|
||||
@ -300,7 +301,7 @@ statement:
|
||||
ZEND_INI_PARSER_CB(&$1, &$5, &$2, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
|
||||
free(Z_STRVAL($1));
|
||||
free(Z_STRVAL($2));
|
||||
free(Z_STRVAL($5));
|
||||
zval_internal_dtor(&$5);
|
||||
}
|
||||
| TC_LABEL { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); free(Z_STRVAL($1)); }
|
||||
| END_OF_LINE
|
||||
@ -315,6 +316,7 @@ string_or_value:
|
||||
expr { $$ = $1; }
|
||||
| BOOL_TRUE { $$ = $1; }
|
||||
| BOOL_FALSE { $$ = $1; }
|
||||
| NULL_NULL { $$ = $1; }
|
||||
| END_OF_LINE { zend_ini_init_string(&$$); }
|
||||
;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,7 @@
|
||||
/* Scanner modes */
|
||||
#define ZEND_INI_SCANNER_NORMAL 0 /* Normal mode. [DEFAULT] */
|
||||
#define ZEND_INI_SCANNER_RAW 1 /* Raw mode. Option values are not parsed */
|
||||
#define ZEND_INI_SCANNER_TYPED 2 /* Typed mode. */
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
int zend_ini_scanner_get_lineno(TSRMLS_D);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include "zend.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_globals.h"
|
||||
#include <zend_ini_parser.h>
|
||||
#include "zend_ini_scanner.h"
|
||||
@ -137,9 +138,55 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
|
||||
Z_TYPE_P(retval) = IS_STRING; \
|
||||
}
|
||||
|
||||
#define RETURN_TOKEN(type, str, len) { \
|
||||
zend_ini_copy_value(ini_lval, str, len); \
|
||||
return type; \
|
||||
#define RETURN_TOKEN(type, str, len) { \
|
||||
if (SCNG(scanner_mode) == ZEND_INI_SCANNER_TYPED) { \
|
||||
zend_ini_copy_typed_value(ini_lval, type, str, len); \
|
||||
} else { \
|
||||
zend_ini_copy_value(ini_lval, str, len); \
|
||||
} \
|
||||
return type; \
|
||||
}
|
||||
|
||||
static inline int convert_to_number(zval *retval, const char *str, const int str_len)
|
||||
{
|
||||
zend_uchar type;
|
||||
int overflow;
|
||||
long lval;
|
||||
double dval;
|
||||
|
||||
if ((type = is_numeric_string_ex(str, str_len, &lval, &dval, 0, &overflow)) != 0) {
|
||||
if (type == IS_LONG) {
|
||||
ZVAL_LONG(retval, lval);
|
||||
return SUCCESS;
|
||||
} else if (type == IS_DOUBLE && !overflow) {
|
||||
ZVAL_DOUBLE(retval, dval);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
static void zend_ini_copy_typed_value(zval *retval, const int type, const char *str, int len)
|
||||
{
|
||||
switch (type) {
|
||||
case BOOL_FALSE:
|
||||
case BOOL_TRUE:
|
||||
ZVAL_BOOL(retval, type == BOOL_TRUE);
|
||||
break;
|
||||
|
||||
case NULL_NULL:
|
||||
ZVAL_NULL(retval);
|
||||
break;
|
||||
|
||||
case TC_NUMBER:
|
||||
if (convert_to_number(retval, str, len) == SUCCESS) {
|
||||
break;
|
||||
}
|
||||
/* intentional fall-through */
|
||||
default:
|
||||
zend_ini_copy_value(retval, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void _yy_push_state(int new_state TSRMLS_DC)
|
||||
@ -172,7 +219,7 @@ static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
|
||||
static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) {
|
||||
if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW && scanner_mode != ZEND_INI_SCANNER_TYPED) {
|
||||
zend_error(E_WARNING, "Invalid scanner mode");
|
||||
return FAILURE;
|
||||
}
|
||||
@ -422,10 +469,14 @@ SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
|
||||
RETURN_TOKEN(BOOL_TRUE, "1", 1);
|
||||
}
|
||||
|
||||
<INITIAL,ST_VALUE>("false"|"off"|"no"|"none"|"null"){TABS_AND_SPACES}* { /* FALSE value (when used outside option value/offset this causes parse error!)*/
|
||||
<INITIAL,ST_VALUE>("false"|"off"|"no"|"none"){TABS_AND_SPACES}* { /* FALSE value (when used outside option value/offset this causes parse error!)*/
|
||||
RETURN_TOKEN(BOOL_FALSE, "", 0);
|
||||
}
|
||||
|
||||
<INITIAL,ST_VALUE>("null"){TABS_AND_SPACES}* {
|
||||
RETURN_TOKEN(NULL_NULL, "", 0);
|
||||
}
|
||||
|
||||
<INITIAL>{LABEL} { /* Get option name */
|
||||
/* Eat leading whitespace */
|
||||
EAT_LEADING_WHITESPACE();
|
||||
|
@ -3561,6 +3561,7 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
|
||||
|
||||
REGISTER_LONG_CONSTANT("INI_SCANNER_NORMAL", ZEND_INI_SCANNER_NORMAL, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("INI_SCANNER_RAW", ZEND_INI_SCANNER_RAW, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("INI_SCANNER_TYPED", ZEND_INI_SCANNER_TYPED, CONST_CS | CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_SCHEME", PHP_URL_SCHEME, CONST_CS | CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("PHP_URL_HOST", PHP_URL_HOST, CONST_CS | CONST_PERSISTENT);
|
||||
|
Loading…
Reference in New Issue
Block a user