Annotation of embedaddon/php/Zend/zend_constants.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | Zend Engine                                                          |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
                      6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 2.00 of the Zend license,     |
                      8:    | that is bundled with this package in the file LICENSE, and is        | 
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.zend.com/license/2_00.txt.                                |
                     11:    | If you did not receive a copy of the Zend license and are unable to  |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@zend.com so we can mail you a copy immediately.              |
                     14:    +----------------------------------------------------------------------+
                     15:    | Authors: Andi Gutmans <andi@zend.com>                                |
                     16:    |          Zeev Suraski <zeev@zend.com>                                |
                     17:    +----------------------------------------------------------------------+
                     18: */
                     19: 
                     20: /* $Id: zend_constants.c 321634 2012-01-01 13:15:04Z felipe $ */
                     21: 
                     22: #include "zend.h"
                     23: #include "zend_constants.h"
                     24: #include "zend_execute.h"
                     25: #include "zend_variables.h"
                     26: #include "zend_operators.h"
                     27: #include "zend_globals.h"
                     28: 
                     29: 
                     30: void free_zend_constant(zend_constant *c)
                     31: {
                     32:        if (!(c->flags & CONST_PERSISTENT)) {
                     33:                zval_dtor(&c->value);
                     34:        }
                     35:        free(c->name);
                     36: }
                     37: 
                     38: 
                     39: void copy_zend_constant(zend_constant *c)
                     40: {
                     41:        c->name = zend_strndup(c->name, c->name_len - 1);
                     42:        if (!(c->flags & CONST_PERSISTENT)) {
                     43:                zval_copy_ctor(&c->value);
                     44:        }
                     45: }
                     46: 
                     47: 
                     48: void zend_copy_constants(HashTable *target, HashTable *source)
                     49: {
                     50:        zend_constant tmp_constant;
                     51: 
                     52:        zend_hash_copy(target, source, (copy_ctor_func_t) copy_zend_constant, &tmp_constant, sizeof(zend_constant));
                     53: }
                     54: 
                     55: 
                     56: static int clean_non_persistent_constant(const zend_constant *c TSRMLS_DC)
                     57: {
                     58:        return (c->flags & CONST_PERSISTENT) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE;
                     59: }
                     60: 
                     61: 
                     62: static int clean_non_persistent_constant_full(const zend_constant *c TSRMLS_DC)
                     63: {
                     64:        return (c->flags & CONST_PERSISTENT) ? 0 : 1;
                     65: }
                     66: 
                     67: 
                     68: static int clean_module_constant(const zend_constant *c, int *module_number TSRMLS_DC)
                     69: {
                     70:        if (c->module_number == *module_number) {
                     71:                return 1;
                     72:        } else {
                     73:                return 0;
                     74:        }
                     75: }
                     76: 
                     77: 
                     78: void clean_module_constants(int module_number TSRMLS_DC)
                     79: {
                     80:        zend_hash_apply_with_argument(EG(zend_constants), (apply_func_arg_t) clean_module_constant, (void *) &module_number TSRMLS_CC);
                     81: }
                     82: 
                     83: 
                     84: int zend_startup_constants(TSRMLS_D)
                     85: {
                     86:        EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
                     87: 
                     88:        if (zend_hash_init(EG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1)==FAILURE) {
                     89:                return FAILURE;
                     90:        }
                     91:        return SUCCESS;
                     92: }
                     93: 
                     94: 
                     95: 
                     96: void zend_register_standard_constants(TSRMLS_D)
                     97: {
                     98:        REGISTER_MAIN_LONG_CONSTANT("E_ERROR", E_ERROR, CONST_PERSISTENT | CONST_CS);
                     99:        REGISTER_MAIN_LONG_CONSTANT("E_RECOVERABLE_ERROR", E_RECOVERABLE_ERROR, CONST_PERSISTENT | CONST_CS);
                    100:        REGISTER_MAIN_LONG_CONSTANT("E_WARNING", E_WARNING, CONST_PERSISTENT | CONST_CS);
                    101:        REGISTER_MAIN_LONG_CONSTANT("E_PARSE", E_PARSE, CONST_PERSISTENT | CONST_CS);
                    102:        REGISTER_MAIN_LONG_CONSTANT("E_NOTICE", E_NOTICE, CONST_PERSISTENT | CONST_CS);
                    103:        REGISTER_MAIN_LONG_CONSTANT("E_STRICT", E_STRICT, CONST_PERSISTENT | CONST_CS);
                    104:        REGISTER_MAIN_LONG_CONSTANT("E_DEPRECATED", E_DEPRECATED, CONST_PERSISTENT | CONST_CS);
                    105:        REGISTER_MAIN_LONG_CONSTANT("E_CORE_ERROR", E_CORE_ERROR, CONST_PERSISTENT | CONST_CS);
                    106:        REGISTER_MAIN_LONG_CONSTANT("E_CORE_WARNING", E_CORE_WARNING, CONST_PERSISTENT | CONST_CS);
                    107:        REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_ERROR", E_COMPILE_ERROR, CONST_PERSISTENT | CONST_CS);
                    108:        REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_WARNING", E_COMPILE_WARNING, CONST_PERSISTENT | CONST_CS);
                    109:        REGISTER_MAIN_LONG_CONSTANT("E_USER_ERROR", E_USER_ERROR, CONST_PERSISTENT | CONST_CS);
                    110:        REGISTER_MAIN_LONG_CONSTANT("E_USER_WARNING", E_USER_WARNING, CONST_PERSISTENT | CONST_CS);
                    111:        REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
                    112:        REGISTER_MAIN_LONG_CONSTANT("E_USER_DEPRECATED", E_USER_DEPRECATED, CONST_PERSISTENT | CONST_CS);
                    113: 
                    114:        REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
                    115: 
                    116: #if SUHOSIN_PATCH
                    117:        REGISTER_MAIN_LONG_CONSTANT("S_MEMORY", S_MEMORY, CONST_PERSISTENT | CONST_CS);
                    118:        REGISTER_MAIN_LONG_CONSTANT("S_VARS", S_VARS, CONST_PERSISTENT | CONST_CS);
                    119:        REGISTER_MAIN_LONG_CONSTANT("S_FILES", S_FILES, CONST_PERSISTENT | CONST_CS);
                    120:        REGISTER_MAIN_LONG_CONSTANT("S_INCLUDE", S_INCLUDE, CONST_PERSISTENT | CONST_CS);
                    121:        REGISTER_MAIN_LONG_CONSTANT("S_SQL", S_SQL, CONST_PERSISTENT | CONST_CS);
                    122:        REGISTER_MAIN_LONG_CONSTANT("S_EXECUTOR", S_EXECUTOR, CONST_PERSISTENT | CONST_CS);
                    123:        REGISTER_MAIN_LONG_CONSTANT("S_MAIL", S_MAIL, CONST_PERSISTENT | CONST_CS);
                    124:        REGISTER_MAIN_LONG_CONSTANT("S_SESSION", S_SESSION, CONST_PERSISTENT | CONST_CS);
                    125:        REGISTER_MAIN_LONG_CONSTANT("S_MISC", S_MISC, CONST_PERSISTENT | CONST_CS);
                    126:        REGISTER_MAIN_LONG_CONSTANT("S_INTERNAL", S_INTERNAL, CONST_PERSISTENT | CONST_CS);
                    127:        REGISTER_MAIN_LONG_CONSTANT("S_ALL", S_ALL, CONST_PERSISTENT | CONST_CS);
                    128: 
                    129:        /* error levels */
                    130:        REGISTER_MAIN_LONG_CONSTANT("LOG_EMERG", LOG_EMERG, CONST_CS | CONST_PERSISTENT); /* system unusable */
                    131:        REGISTER_MAIN_LONG_CONSTANT("LOG_ALERT", LOG_ALERT, CONST_CS | CONST_PERSISTENT); /* immediate action required */
                    132:        REGISTER_MAIN_LONG_CONSTANT("LOG_CRIT", LOG_CRIT, CONST_CS | CONST_PERSISTENT); /* critical conditions */
                    133:        REGISTER_MAIN_LONG_CONSTANT("LOG_ERR", LOG_ERR, CONST_CS | CONST_PERSISTENT); 
                    134:        REGISTER_MAIN_LONG_CONSTANT("LOG_WARNING", LOG_WARNING, CONST_CS | CONST_PERSISTENT);
                    135:        REGISTER_MAIN_LONG_CONSTANT("LOG_NOTICE", LOG_NOTICE, CONST_CS | CONST_PERSISTENT);
                    136:        REGISTER_MAIN_LONG_CONSTANT("LOG_INFO", LOG_INFO, CONST_CS | CONST_PERSISTENT);
                    137:        REGISTER_MAIN_LONG_CONSTANT("LOG_DEBUG", LOG_DEBUG, CONST_CS | CONST_PERSISTENT);
                    138:        /* facility: type of program logging the message */
                    139:        REGISTER_MAIN_LONG_CONSTANT("LOG_KERN", LOG_KERN, CONST_CS | CONST_PERSISTENT);
                    140:        REGISTER_MAIN_LONG_CONSTANT("LOG_USER", LOG_USER, CONST_CS | CONST_PERSISTENT); /* generic user level */
                    141:        REGISTER_MAIN_LONG_CONSTANT("LOG_MAIL", LOG_MAIL, CONST_CS | CONST_PERSISTENT); /* log to email */
                    142:        REGISTER_MAIN_LONG_CONSTANT("LOG_DAEMON", LOG_DAEMON, CONST_CS | CONST_PERSISTENT); /* other system daemons */
                    143:        REGISTER_MAIN_LONG_CONSTANT("LOG_AUTH", LOG_AUTH, CONST_CS | CONST_PERSISTENT);
                    144:        REGISTER_MAIN_LONG_CONSTANT("LOG_SYSLOG", LOG_SYSLOG, CONST_CS | CONST_PERSISTENT);
                    145:        REGISTER_MAIN_LONG_CONSTANT("LOG_LPR", LOG_LPR, CONST_CS | CONST_PERSISTENT);
                    146: #ifdef LOG_NEWS
                    147:        /* No LOG_NEWS on HP-UX */
                    148:        REGISTER_MAIN_LONG_CONSTANT("LOG_NEWS", LOG_NEWS, CONST_CS | CONST_PERSISTENT); /* usenet new */
                    149: #endif
                    150: #ifdef LOG_UUCP
                    151:        /* No LOG_UUCP on HP-UX */
                    152:        REGISTER_MAIN_LONG_CONSTANT("LOG_UUCP", LOG_UUCP, CONST_CS | CONST_PERSISTENT);
                    153: #endif
                    154: #ifdef LOG_CRON
                    155:        /* apparently some systems don't have this one */
                    156:        REGISTER_MAIN_LONG_CONSTANT("LOG_CRON", LOG_CRON, CONST_CS | CONST_PERSISTENT);
                    157: #endif
                    158: #ifdef LOG_AUTHPRIV
                    159:        /* AIX doesn't have LOG_AUTHPRIV */
                    160:        REGISTER_MAIN_LONG_CONSTANT("LOG_AUTHPRIV", LOG_AUTHPRIV, CONST_CS | CONST_PERSISTENT);
                    161: #endif
                    162: #ifndef PHP_WIN32
                    163:        REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL0", LOG_LOCAL0, CONST_CS | CONST_PERSISTENT);
                    164:        REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL1", LOG_LOCAL1, CONST_CS | CONST_PERSISTENT);
                    165:        REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL2", LOG_LOCAL2, CONST_CS | CONST_PERSISTENT);
                    166:        REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL3", LOG_LOCAL3, CONST_CS | CONST_PERSISTENT);
                    167:        REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL4", LOG_LOCAL4, CONST_CS | CONST_PERSISTENT);
                    168:        REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL5", LOG_LOCAL5, CONST_CS | CONST_PERSISTENT);
                    169:        REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL6", LOG_LOCAL6, CONST_CS | CONST_PERSISTENT);
                    170:        REGISTER_MAIN_LONG_CONSTANT("LOG_LOCAL7", LOG_LOCAL7, CONST_CS | CONST_PERSISTENT);
                    171: #endif
                    172:        /* options */
                    173:        REGISTER_MAIN_LONG_CONSTANT("LOG_PID", LOG_PID, CONST_CS | CONST_PERSISTENT);
                    174:        REGISTER_MAIN_LONG_CONSTANT("LOG_CONS", LOG_CONS, CONST_CS | CONST_PERSISTENT);
                    175:        REGISTER_MAIN_LONG_CONSTANT("LOG_ODELAY", LOG_ODELAY, CONST_CS | CONST_PERSISTENT);
                    176:        REGISTER_MAIN_LONG_CONSTANT("LOG_NDELAY", LOG_NDELAY, CONST_CS | CONST_PERSISTENT);
                    177: #ifdef LOG_NOWAIT
                    178:        REGISTER_MAIN_LONG_CONSTANT("LOG_NOWAIT", LOG_NOWAIT, CONST_CS | CONST_PERSISTENT);
                    179: #endif
                    180: #ifdef LOG_PERROR
                    181:        /* AIX doesn't have LOG_PERROR */
                    182:        REGISTER_MAIN_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/
                    183: #endif
                    184: #endif
                    185: 
                    186:        REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS);
                    187:        REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);
                    188:        /* true/false constants */
                    189:        {
                    190:                zend_constant c;
                    191:        
                    192:                c.flags = CONST_PERSISTENT | CONST_CT_SUBST;
                    193:                c.module_number = 0;
                    194: 
                    195:                c.name = zend_strndup(ZEND_STRL("TRUE"));
                    196:                c.name_len = sizeof("TRUE");
                    197:                c.value.value.lval = 1;
                    198:                c.value.type = IS_BOOL;
                    199:                zend_register_constant(&c TSRMLS_CC);
                    200:                
                    201:                c.name = zend_strndup(ZEND_STRL("FALSE"));
                    202:                c.name_len = sizeof("FALSE");
                    203:                c.value.value.lval = 0;
                    204:                c.value.type = IS_BOOL;
                    205:                zend_register_constant(&c TSRMLS_CC);
                    206: 
                    207:                c.name = zend_strndup(ZEND_STRL("NULL"));
                    208:                c.name_len = sizeof("NULL");
                    209:                c.value.type = IS_NULL;
                    210:                zend_register_constant(&c TSRMLS_CC);
                    211: 
                    212:                c.flags = CONST_PERSISTENT;
                    213: 
                    214:                c.name = zend_strndup(ZEND_STRL("ZEND_THREAD_SAFE"));
                    215:                c.name_len = sizeof("ZEND_THREAD_SAFE");
                    216:                c.value.value.lval = ZTS_V;
                    217:                c.value.type = IS_BOOL;
                    218:                zend_register_constant(&c TSRMLS_CC);
                    219: 
                    220:                c.name = zend_strndup(ZEND_STRL("ZEND_DEBUG_BUILD"));
                    221:                c.name_len = sizeof("ZEND_DEBUG_BUILD");
                    222:                c.value.value.lval = ZEND_DEBUG;
                    223:                c.value.type = IS_BOOL;
                    224:                zend_register_constant(&c TSRMLS_CC);
                    225:        }
                    226: }
                    227: 
                    228: 
                    229: int zend_shutdown_constants(TSRMLS_D)
                    230: {
                    231:        zend_hash_destroy(EG(zend_constants));
                    232:        free(EG(zend_constants));
                    233:        return SUCCESS;
                    234: }
                    235: 
                    236: 
                    237: void clean_non_persistent_constants(TSRMLS_D)
                    238: {
                    239:        if (EG(full_tables_cleanup)) {
                    240:                zend_hash_apply(EG(zend_constants), (apply_func_t) clean_non_persistent_constant_full TSRMLS_CC);
                    241:        } else {
                    242:                zend_hash_reverse_apply(EG(zend_constants), (apply_func_t) clean_non_persistent_constant TSRMLS_CC);
                    243:        }
                    244: }
                    245: 
                    246: 
                    247: ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC)
                    248: {
                    249:        zend_constant c;
                    250:        
                    251:        c.value.type = IS_LONG;
                    252:        c.value.value.lval = lval;
                    253:        c.flags = flags;
                    254:        c.name = zend_strndup(name, name_len-1);
                    255:        c.name_len = name_len;
                    256:        c.module_number = module_number;
                    257:        zend_register_constant(&c TSRMLS_CC);
                    258: }
                    259: 
                    260: 
                    261: ZEND_API void zend_register_double_constant(const char *name, uint name_len, double dval, int flags, int module_number TSRMLS_DC)
                    262: {
                    263:        zend_constant c;
                    264:        
                    265:        c.value.type = IS_DOUBLE;
                    266:        c.value.value.dval = dval;
                    267:        c.flags = flags;
                    268:        c.name = zend_strndup(name, name_len-1);
                    269:        c.name_len = name_len;
                    270:        c.module_number = module_number;
                    271:        zend_register_constant(&c TSRMLS_CC);
                    272: }
                    273: 
                    274: 
                    275: ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, char *strval, uint strlen, int flags, int module_number TSRMLS_DC)
                    276: {
                    277:        zend_constant c;
                    278:        
                    279:        c.value.type = IS_STRING;
                    280:        c.value.value.str.val = strval;
                    281:        c.value.value.str.len = strlen;
                    282:        c.flags = flags;
                    283:        c.name = zend_strndup(name, name_len-1);
                    284:        c.name_len = name_len;
                    285:        c.module_number = module_number;
                    286:        zend_register_constant(&c TSRMLS_CC);
                    287: }
                    288: 
                    289: 
                    290: ZEND_API void zend_register_string_constant(const char *name, uint name_len, char *strval, int flags, int module_number TSRMLS_DC)
                    291: {
                    292:        zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number TSRMLS_CC);
                    293: }
                    294: 
                    295: 
                    296: ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSRMLS_DC)
                    297: {
                    298:        zend_constant *c;
                    299:        int retval = 1;
                    300:        char *lookup_name;
                    301: 
                    302:        if (zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c) == FAILURE) {
                    303:                lookup_name = zend_str_tolower_dup(name, name_len);
                    304: 
                    305:                if (zend_hash_find(EG(zend_constants), lookup_name, name_len+1, (void **) &c)==SUCCESS) {
                    306:                        if (c->flags & CONST_CS) {
                    307:                                retval=0;
                    308:                        }
                    309:                } else {
                    310:                        static char haltoff[] = "__COMPILER_HALT_OFFSET__";
                    311: 
                    312:                        if (!EG(in_execution)) {
                    313:                                retval = 0;
                    314:                        } else if (name_len == sizeof("__COMPILER_HALT_OFFSET__")-1 &&
                    315:                                  !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) {
                    316:                                char *cfilename, *haltname;
                    317:                                int len, clen;
                    318: 
                    319:                                cfilename = zend_get_executed_filename(TSRMLS_C);
                    320:                                clen = strlen(cfilename);
                    321:                                /* check for __COMPILER_HALT_OFFSET__ */
                    322:                                zend_mangle_property_name(&haltname, &len, haltoff,
                    323:                                        sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0);
                    324:                                if (zend_hash_find(EG(zend_constants), haltname, len+1, (void **) &c) == SUCCESS) {
                    325:                                        retval = 1;
                    326:                                } else {
                    327:                                        retval=0;
                    328:                                }
                    329:                                pefree(haltname, 0);
                    330:                        } else {
                    331:                                retval=0;
                    332:                        }
                    333:                }
                    334:                efree(lookup_name);
                    335:        }
                    336: 
                    337:        if (retval) {
                    338:                *result = c->value;
                    339:                zval_copy_ctor(result);
                    340:                Z_SET_REFCOUNT_P(result, 1);
                    341:                Z_UNSET_ISREF_P(result);
                    342:        }
                    343: 
                    344:        return retval;
                    345: }
                    346: 
                    347: ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, zend_class_entry *scope, ulong flags TSRMLS_DC)
                    348: {
                    349:        zend_constant *c;
                    350:        int retval = 1;
                    351:        char *colon;
                    352:        zend_class_entry *ce = NULL;
                    353:        char *class_name;
                    354:        zval **ret_constant;
                    355: 
                    356:        /* Skip leading \\ */
                    357:        if (name[0] == '\\') {
                    358:                name += 1;
                    359:                name_len -= 1;
                    360:        }
                    361: 
                    362: 
                    363:        if ((colon = zend_memrchr(name, ':', name_len)) &&
                    364:            colon > name && (*(colon - 1) == ':')) {
                    365:                int class_name_len = colon - name - 1;
                    366:                int const_name_len = name_len - class_name_len - 2;
                    367:                char *constant_name = colon + 1;
                    368:                char *lcname;
                    369: 
                    370:                class_name = estrndup(name, class_name_len);
                    371:                lcname = zend_str_tolower_dup(class_name, class_name_len);
                    372:                if (!scope) {
                    373:                        if (EG(in_execution)) {
                    374:                                scope = EG(scope);
                    375:                        } else {
                    376:                                scope = CG(active_class_entry);
                    377:                        }
                    378:                }
                    379: 
                    380:                if (class_name_len == sizeof("self")-1 &&
                    381:                    !memcmp(lcname, "self", sizeof("self")-1)) {
                    382:                        if (scope) {
                    383:                                ce = scope;
                    384:                        } else {
                    385:                                zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
                    386:                                retval = 0;
                    387:                        }
                    388:                        efree(lcname);
                    389:                } else if (class_name_len == sizeof("parent")-1 &&
                    390:                           !memcmp(lcname, "parent", sizeof("parent")-1)) {
                    391:                        if (!scope) {
                    392:                                zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
                    393:                        } else if (!scope->parent) {
                    394:                                zend_error(E_ERROR, "Cannot access parent:: when current class scope has no parent");
                    395:                        } else {
                    396:                                ce = scope->parent;
                    397:                        }
                    398:                        efree(lcname);
                    399:                } else if (class_name_len == sizeof("static")-1 &&
                    400:                           !memcmp(lcname, "static", sizeof("static")-1)) {
                    401:                        if (EG(called_scope)) {
                    402:                                ce = EG(called_scope);
                    403:                        } else {
                    404:                                zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
                    405:                        }
                    406:                        efree(lcname);
                    407:                } else {
                    408:                        efree(lcname);
                    409:                        ce = zend_fetch_class(class_name, class_name_len, flags TSRMLS_CC);
                    410:                }
                    411:                if (retval && ce) {
                    412:                        if (zend_hash_find(&ce->constants_table, constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) {
                    413:                                retval = 0;
                    414:                                if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
                    415:                                        zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name, constant_name);
                    416:                                }
                    417:                        }
                    418:                } else if (!ce) {
                    419:                        retval = 0;
                    420:                }
                    421:                efree(class_name);
                    422:                goto finish;
                    423:        }
                    424: 
                    425:        /* non-class constant */
                    426:        if ((colon = zend_memrchr(name, '\\', name_len)) != NULL) {
                    427:                /* compound constant name */
                    428:                int prefix_len = colon - name;
                    429:                int const_name_len = name_len - prefix_len - 1;
                    430:                char *constant_name = colon + 1;
                    431:                char *lcname;
                    432:                int found_const = 0;
                    433: 
                    434:                lcname = zend_str_tolower_dup(name, prefix_len);
                    435:                /* Check for namespace constant */
                    436: 
                    437:                /* Concatenate lowercase namespace name and constant name */
                    438:                lcname = erealloc(lcname, prefix_len + 1 + const_name_len + 1);
                    439:                lcname[prefix_len] = '\\';
                    440:                memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1);
                    441: 
                    442:                if (zend_hash_find(EG(zend_constants), lcname, prefix_len + 1 + const_name_len + 1, (void **) &c) == SUCCESS) {
                    443:                        found_const = 1;
                    444:                } else {
                    445:                        /* try lowercase */
                    446:                        zend_str_tolower(lcname + prefix_len + 1, const_name_len);
                    447:                        if (zend_hash_find(EG(zend_constants), lcname, prefix_len + 1 + const_name_len + 1, (void **) &c) == SUCCESS) {
                    448:                                if ((c->flags & CONST_CS) == 0) {
                    449:                                        found_const = 1;
                    450:                                }
                    451:                        }
                    452:                }
                    453:                efree(lcname);
                    454:                if(found_const) {
                    455:                        *result = c->value;
                    456:                        zval_update_constant_ex(&result, (void*)1, NULL TSRMLS_CC);
                    457:                        zval_copy_ctor(result);
                    458:                        Z_SET_REFCOUNT_P(result, 1);
                    459:                        Z_UNSET_ISREF_P(result);
                    460:                        return 1;
                    461:                }
                    462:                /* name requires runtime resolution, need to check non-namespaced name */
                    463:                if ((flags & IS_CONSTANT_UNQUALIFIED) != 0) {
                    464:                        name = constant_name;
                    465:                        name_len = const_name_len;
                    466:                        return zend_get_constant(name, name_len, result TSRMLS_CC);
                    467:                }
                    468:                retval = 0;
                    469: finish:
                    470:                if (retval) {
                    471:                        zval_update_constant_ex(ret_constant, (void*)1, ce TSRMLS_CC);
                    472:                        *result = **ret_constant;
                    473:                        zval_copy_ctor(result);
                    474:                        INIT_PZVAL(result);
                    475:                }
                    476: 
                    477:                return retval;
                    478:        }
                    479: 
                    480:        return zend_get_constant(name, name_len, result TSRMLS_CC);
                    481: }
                    482: 
                    483: ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
                    484: {
                    485:        char *lowercase_name = NULL;
                    486:        char *name;
                    487:        int ret = SUCCESS;
                    488: 
                    489: #if 0
                    490:        printf("Registering constant for module %d\n", c->module_number);
                    491: #endif
                    492: 
                    493:        if (!(c->flags & CONST_CS)) {
                    494:                /* keep in mind that c->name_len already contains the '\0' */
                    495:                lowercase_name = estrndup(c->name, c->name_len-1);
                    496:                zend_str_tolower(lowercase_name, c->name_len-1);
                    497:                name = lowercase_name;
                    498:        } else {
                    499:                char *slash = strrchr(c->name, '\\');
                    500:                if(slash) {
                    501:                        lowercase_name = estrndup(c->name, c->name_len-1);
                    502:                        zend_str_tolower(lowercase_name, slash-c->name);
                    503:                        name = lowercase_name;
                    504:                } else {
                    505:                        name = c->name;
                    506:                }
                    507:        }
                    508: 
                    509:        /* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */
                    510:        if ((c->name_len == sizeof("__COMPILER_HALT_OFFSET__")
                    511:                && !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1))
                    512:                || zend_hash_add(EG(zend_constants), name, c->name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
                    513:                
                    514:                /* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */
                    515:                if (c->name[0] == '\0' && c->name_len > sizeof("\0__COMPILER_HALT_OFFSET__")
                    516:                        && memcmp(name, "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {
                    517:                        name++;
                    518:                }
                    519:                zend_error(E_NOTICE,"Constant %s already defined", name);
                    520:                free(c->name);
                    521:                if (!(c->flags & CONST_PERSISTENT)) {
                    522:                        zval_dtor(&c->value);
                    523:                }
                    524:                ret = FAILURE;
                    525:        }
                    526:        if (lowercase_name) {
                    527:                efree(lowercase_name);
                    528:        }
                    529:        return ret;
                    530: }
                    531: 
                    532: 
                    533: /*
                    534:  * Local variables:
                    535:  * tab-width: 4
                    536:  * c-basic-offset: 4
                    537:  * indent-tabs-mode: t
                    538:  * End:
                    539:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>