root/Zend/zend_ini_parser.y

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zend_ini_do_op
  2. zend_ini_init_string
  3. zend_ini_add_string
  4. zend_ini_get_constant
  5. zend_ini_get_var
  6. ini_error
  7. zend_parse_ini_file
  8. zend_parse_ini_string

   1 %{
   2 /*
   3    +----------------------------------------------------------------------+
   4    | Zend Engine                                                          |
   5    +----------------------------------------------------------------------+
   6    | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) |
   7    +----------------------------------------------------------------------+
   8    | This source file is subject to version 2.00 of the Zend license,     |
   9    | that is bundled with this package in the file LICENSE, and is        |
  10    | available through the world-wide-web at the following url:           |
  11    | http://www.zend.com/license/2_00.txt.                                |
  12    | If you did not receive a copy of the Zend license and are unable to  |
  13    | obtain it through the world-wide-web, please send a note to          |
  14    | license@zend.com so we can mail you a copy immediately.              |
  15    +----------------------------------------------------------------------+
  16    | Authors: Zeev Suraski <zeev@zend.com>                                |
  17    |          Jani Taskinen <jani@php.net>                                |
  18    +----------------------------------------------------------------------+
  19 */
  20 
  21 /* $Id$ */
  22 
  23 #define DEBUG_CFG_PARSER 0
  24 
  25 #include "zend.h"
  26 #include "zend_API.h"
  27 #include "zend_ini.h"
  28 #include "zend_constants.h"
  29 #include "zend_ini_scanner.h"
  30 #include "zend_extensions.h"
  31 
  32 #ifdef PHP_WIN32
  33 #include "win32/syslog.h"
  34 #endif
  35 
  36 #define YYERROR_VERBOSE
  37 #define YYSTYPE zval
  38 
  39 #ifdef ZTS
  40 #define YYPARSE_PARAM tsrm_ls
  41 #define YYLEX_PARAM tsrm_ls
  42 int ini_parse(void *arg);
  43 #else
  44 int ini_parse(void);
  45 #endif
  46 
  47 #define ZEND_INI_PARSER_CB      (CG(ini_parser_param))->ini_parser_cb
  48 #define ZEND_INI_PARSER_ARG     (CG(ini_parser_param))->arg
  49 
  50 /* {{{ zend_ini_do_op()
  51 */
  52 static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
  53 {
  54         int i_result;
  55         int i_op1, i_op2;
  56         char str_result[MAX_LENGTH_OF_LONG];
  57 
  58         i_op1 = atoi(Z_STRVAL_P(op1));
  59         free(Z_STRVAL_P(op1));
  60         if (op2) {
  61                 i_op2 = atoi(Z_STRVAL_P(op2));
  62                 free(Z_STRVAL_P(op2));
  63         } else {
  64                 i_op2 = 0;
  65         }
  66 
  67         switch (type) {
  68                 case '|':
  69                         i_result = i_op1 | i_op2;
  70                         break;
  71                 case '&':
  72                         i_result = i_op1 & i_op2;
  73                         break;
  74                 case '^':
  75                         i_result = i_op1 ^ i_op2;
  76                         break;
  77                 case '~':
  78                         i_result = ~i_op1;
  79                         break;
  80                 case '!':
  81                         i_result = !i_op1;
  82                         break;
  83                 default:
  84                         i_result = 0;
  85                         break;
  86         }
  87 
  88         Z_STRLEN_P(result) = zend_sprintf(str_result, "%d", i_result);
  89         Z_STRVAL_P(result) = (char *) malloc(Z_STRLEN_P(result)+1);
  90         memcpy(Z_STRVAL_P(result), str_result, Z_STRLEN_P(result));
  91         Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
  92         Z_TYPE_P(result) = IS_STRING;
  93 }
  94 /* }}} */
  95 
  96 /* {{{ zend_ini_init_string()
  97 */
  98 static void zend_ini_init_string(zval *result)
  99 {
 100         Z_STRVAL_P(result) = malloc(1);
 101         Z_STRVAL_P(result)[0] = 0;
 102         Z_STRLEN_P(result) = 0;
 103         Z_TYPE_P(result) = IS_STRING;
 104 }
 105 /* }}} */
 106 
 107 /* {{{ zend_ini_add_string()
 108 */
 109 static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
 110 {
 111         int length;
 112 
 113         if (Z_TYPE_P(op1) != IS_STRING) {
 114                 zval copy;
 115                 MAKE_COPY_ZVAL(&op1, &copy);
 116                 convert_to_string(&copy);
 117                 Z_STRVAL_P(op1) = zend_strndup(Z_STRVAL(copy), Z_STRLEN(copy));
 118                 Z_STRLEN_P(op1) = Z_STRLEN(copy);
 119                 zval_dtor(&copy);
 120         }
 121 
 122         length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
 123 
 124         Z_STRVAL_P(result) = (char *) realloc(Z_STRVAL_P(op1), length+1);
 125         memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
 126         Z_STRVAL_P(result)[length] = 0;
 127         Z_STRLEN_P(result) = length;
 128         Z_TYPE_P(result) = IS_STRING;
 129 }
 130 /* }}} */
 131 
 132 /* {{{ zend_ini_get_constant()
 133 */
 134 static void zend_ini_get_constant(zval *result, zval *name TSRMLS_DC)
 135 {
 136         zval z_constant;
 137 
 138         /* If name contains ':' it is not a constant. Bug #26893. */
 139         if (!memchr(Z_STRVAL_P(name), ':', Z_STRLEN_P(name))
 140                         && zend_get_constant(Z_STRVAL_P(name), Z_STRLEN_P(name), &z_constant TSRMLS_CC)) {
 141                 /* z_constant is emalloc()'d */
 142                 convert_to_string(&z_constant);
 143                 Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(z_constant), Z_STRLEN(z_constant));
 144                 Z_STRLEN_P(result) = Z_STRLEN(z_constant);
 145                 Z_TYPE_P(result) = Z_TYPE(z_constant);
 146                 zval_dtor(&z_constant);
 147                 free(Z_STRVAL_P(name));
 148         } else {
 149                 *result = *name;
 150         }
 151 }
 152 /* }}} */
 153 
 154 /* {{{ zend_ini_get_var()
 155 */
 156 static void zend_ini_get_var(zval *result, zval *name TSRMLS_DC)
 157 {
 158         zval curval;
 159         char *envvar;
 160 
 161         /* Fetch configuration option value */
 162         if (zend_get_configuration_directive(Z_STRVAL_P(name), Z_STRLEN_P(name)+1, &curval) == SUCCESS) {
 163                 Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(curval), Z_STRLEN(curval));
 164                 Z_STRLEN_P(result) = Z_STRLEN(curval);
 165         /* ..or if not found, try ENV */
 166         } else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name) TSRMLS_CC)) != NULL ||
 167                            (envvar = getenv(Z_STRVAL_P(name))) != NULL) {
 168                 Z_STRVAL_P(result) = strdup(envvar);
 169                 Z_STRLEN_P(result) = strlen(envvar);
 170         } else {
 171                 zend_ini_init_string(result);
 172         }
 173 }
 174 /* }}} */
 175 
 176 /* {{{ ini_error()
 177 */
 178 static void ini_error(char *msg)
 179 {
 180         char *error_buf;
 181         int error_buf_len;
 182         char *currently_parsed_filename;
 183         TSRMLS_FETCH();
 184 
 185         currently_parsed_filename = zend_ini_scanner_get_filename(TSRMLS_C);
 186         if (currently_parsed_filename) {
 187                 error_buf_len = 128 + strlen(msg) + strlen(currently_parsed_filename); /* should be more than enough */
 188                 error_buf = (char *) emalloc(error_buf_len);
 189 
 190                 sprintf(error_buf, "%s in %s on line %d\n", msg, currently_parsed_filename, zend_ini_scanner_get_lineno(TSRMLS_C));
 191         } else {
 192                 error_buf = estrdup("Invalid configuration directive\n");
 193         }
 194 
 195         if (CG(ini_parser_unbuffered_errors)) {
 196 #ifdef PHP_WIN32
 197                 syslog(LOG_ALERT, "PHP: %s (%s)", error_buf, GetCommandLine());
 198 #endif
 199                 fprintf(stderr, "PHP:  %s", error_buf);
 200         } else {
 201                 zend_error(E_WARNING, "%s", error_buf);
 202         }
 203         efree(error_buf);
 204 }
 205 /* }}} */
 206 
 207 /* {{{ zend_parse_ini_file()
 208 */
 209 ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg TSRMLS_DC)
 210 {
 211         int retval;
 212         zend_ini_parser_param ini_parser_param;
 213 
 214         ini_parser_param.ini_parser_cb = ini_parser_cb;
 215         ini_parser_param.arg = arg;
 216         CG(ini_parser_param) = &ini_parser_param;
 217 
 218         if (zend_ini_open_file_for_scanning(fh, scanner_mode TSRMLS_CC) == FAILURE) {
 219                 return FAILURE;
 220         }
 221 
 222         CG(ini_parser_unbuffered_errors) = unbuffered_errors;
 223         retval = ini_parse(TSRMLS_C);
 224         zend_file_handle_dtor(fh TSRMLS_CC);
 225 
 226         shutdown_ini_scanner(TSRMLS_C);
 227 
 228         if (retval == 0) {
 229                 return SUCCESS;
 230         } else {
 231                 return FAILURE;
 232         }
 233 }
 234 /* }}} */
 235 
 236 /* {{{ zend_parse_ini_string()
 237 */
 238 ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg TSRMLS_DC)
 239 {
 240         int retval;
 241         zend_ini_parser_param ini_parser_param;
 242 
 243         ini_parser_param.ini_parser_cb = ini_parser_cb;
 244         ini_parser_param.arg = arg;
 245         CG(ini_parser_param) = &ini_parser_param;
 246 
 247         if (zend_ini_prepare_string_for_scanning(str, scanner_mode TSRMLS_CC) == FAILURE) {
 248                 return FAILURE;
 249         }
 250 
 251         CG(ini_parser_unbuffered_errors) = unbuffered_errors;
 252         retval = ini_parse(TSRMLS_C);
 253 
 254         shutdown_ini_scanner(TSRMLS_C);
 255 
 256         if (retval == 0) {
 257                 return SUCCESS;
 258         } else {
 259                 return FAILURE;
 260         }
 261 }
 262 /* }}} */
 263 
 264 %}
 265 
 266 %expect 0
 267 %pure_parser
 268 
 269 %token TC_SECTION
 270 %token TC_RAW
 271 %token TC_CONSTANT
 272 %token TC_NUMBER
 273 %token TC_STRING
 274 %token TC_WHITESPACE
 275 %token TC_LABEL
 276 %token TC_OFFSET
 277 %token TC_DOLLAR_CURLY
 278 %token TC_VARNAME
 279 %token TC_QUOTED_STRING
 280 %token BOOL_TRUE
 281 %token BOOL_FALSE
 282 %token NULL_NULL
 283 %token END_OF_LINE
 284 %token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' '{' '}'
 285 %left '|' '&' '^'
 286 %right '~' '!'
 287 
 288 %%
 289 
 290 statement_list:
 291                 statement_list statement
 292         |       /* empty */
 293 ;
 294 
 295 statement:
 296                 TC_SECTION section_string_or_value ']' {
 297 #if DEBUG_CFG_PARSER
 298                         printf("SECTION: [%s]\n", Z_STRVAL($2));
 299 #endif
 300                         ZEND_INI_PARSER_CB(&$2, NULL, NULL, ZEND_INI_PARSER_SECTION, ZEND_INI_PARSER_ARG TSRMLS_CC);
 301                         free(Z_STRVAL($2));
 302                 }
 303         |       TC_LABEL '=' string_or_value {
 304 #if DEBUG_CFG_PARSER
 305                         printf("NORMAL: '%s' = '%s'\n", Z_STRVAL($1), Z_STRVAL($3));
 306 #endif
 307                         ZEND_INI_PARSER_CB(&$1, &$3, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
 308                         free(Z_STRVAL($1));
 309                         zval_internal_dtor(&$3);
 310                 }
 311         |       TC_OFFSET option_offset ']' '=' string_or_value {
 312 #if DEBUG_CFG_PARSER
 313                         printf("OFFSET: '%s'[%s] = '%s'\n", Z_STRVAL($1), Z_STRVAL($2), Z_STRVAL($5));
 314 #endif
 315                         ZEND_INI_PARSER_CB(&$1, &$5, &$2, ZEND_INI_PARSER_POP_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC);
 316                         free(Z_STRVAL($1));
 317                         if (Z_TYPE($2) == IS_STRING) {
 318                                 free(Z_STRVAL($2));
 319                         } else {
 320                                 zval_dtor(&$2);
 321                         }
 322                         zval_internal_dtor(&$5);
 323                 }
 324         |       TC_LABEL        { ZEND_INI_PARSER_CB(&$1, NULL, NULL, ZEND_INI_PARSER_ENTRY, ZEND_INI_PARSER_ARG TSRMLS_CC); free(Z_STRVAL($1)); }
 325         |       END_OF_LINE
 326 ;
 327 
 328 section_string_or_value:
 329                 var_string_list_section                 { $$ = $1; }
 330         |       /* empty */                                             { zend_ini_init_string(&$$); }
 331 ;
 332 
 333 string_or_value:
 334                 expr                                                    { $$ = $1; }
 335         |       BOOL_TRUE                                               { $$ = $1; }
 336         |       BOOL_FALSE                                              { $$ = $1; }
 337         |       NULL_NULL                                               { $$ = $1; }
 338         |       END_OF_LINE                                             { zend_ini_init_string(&$$); }
 339 ;
 340 
 341 option_offset:
 342                 var_string_list                                 { $$ = $1; }
 343         |       /* empty */                                             { zend_ini_init_string(&$$); }
 344 ;
 345 
 346 encapsed_list:
 347                 encapsed_list cfg_var_ref               { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
 348         |       encapsed_list TC_QUOTED_STRING  { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
 349         |       /* empty */                                             { zend_ini_init_string(&$$); }
 350 ;
 351 
 352 var_string_list_section:
 353                 cfg_var_ref                                             { $$ = $1; }
 354         |       constant_literal                                { $$ = $1; }
 355         |       '"' encapsed_list '"'                   { $$ = $2; }
 356         |       var_string_list_section cfg_var_ref     { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
 357         |       var_string_list_section constant_literal        { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
 358         |       var_string_list_section '"' encapsed_list '"'  { zend_ini_add_string(&$$, &$1, &$3); free(Z_STRVAL($3)); }
 359 ;
 360 
 361 var_string_list:
 362                 cfg_var_ref                                             { $$ = $1; }
 363         |       constant_string                                 { $$ = $1; }
 364         |       '"' encapsed_list '"'                   { $$ = $2; }
 365         |       var_string_list cfg_var_ref     { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
 366         |       var_string_list constant_string { zend_ini_add_string(&$$, &$1, &$2); free(Z_STRVAL($2)); }
 367         |       var_string_list '"' encapsed_list '"'  { zend_ini_add_string(&$$, &$1, &$3); free(Z_STRVAL($3)); }
 368 ;
 369 
 370 expr:
 371                 var_string_list                                 { $$ = $1; }
 372         |       expr '|' expr                                   { zend_ini_do_op('|', &$$, &$1, &$3); }
 373         |       expr '&' expr                                   { zend_ini_do_op('&', &$$, &$1, &$3); }
 374         |       expr '^' expr                                   { zend_ini_do_op('^', &$$, &$1, &$3); }
 375         |       '~' expr                                                { zend_ini_do_op('~', &$$, &$2, NULL); }
 376         |       '!'     expr                                            { zend_ini_do_op('!', &$$, &$2, NULL); }
 377         |       '(' expr ')'                                    { $$ = $2; }
 378 ;
 379 
 380 cfg_var_ref:
 381                 TC_DOLLAR_CURLY TC_VARNAME '}'  { zend_ini_get_var(&$$, &$2 TSRMLS_CC); free(Z_STRVAL($2)); }
 382 ;
 383 
 384 constant_literal:
 385                 TC_CONSTANT                                             { $$ = $1; }
 386         |       TC_RAW                                                  { $$ = $1; /*printf("TC_RAW: '%s'\n", Z_STRVAL($1));*/ }
 387         |       TC_NUMBER                                               { $$ = $1; /*printf("TC_NUMBER: '%s'\n", Z_STRVAL($1));*/ }
 388         |       TC_STRING                                               { $$ = $1; /*printf("TC_STRING: '%s'\n", Z_STRVAL($1));*/ }
 389         |       TC_WHITESPACE                                   { $$ = $1; /*printf("TC_WHITESPACE: '%s'\n", Z_STRVAL($1));*/ }
 390 ;
 391 
 392 constant_string:
 393                 TC_CONSTANT                                             { zend_ini_get_constant(&$$, &$1 TSRMLS_CC); }
 394         |       TC_RAW                                                  { $$ = $1; /*printf("TC_RAW: '%s'\n", Z_STRVAL($1));*/ }
 395         |       TC_NUMBER                                               { $$ = $1; /*printf("TC_NUMBER: '%s'\n", Z_STRVAL($1));*/ }
 396         |       TC_STRING                                               { $$ = $1; /*printf("TC_STRING: '%s'\n", Z_STRVAL($1));*/ }
 397         |       TC_WHITESPACE                                   { $$ = $1; /*printf("TC_WHITESPACE: '%s'\n", Z_STRVAL($1));*/ }
 398 ;
 399 
 400 /*
 401  * Local variables:
 402  * tab-width: 4
 403  * c-basic-offset: 4
 404  * indent-tabs-mode: t
 405  * End:
 406  */

/* [<][>][^][v][top][bottom][index][help] */