1 /*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1998-2018 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@php.net> |
16 | Zeev Suraski <zeev@php.net> |
17 +----------------------------------------------------------------------+
18 */
19
20 #include "zend.h"
21 #include "zend_constants.h"
22 #include "zend_exceptions.h"
23 #include "zend_execute.h"
24 #include "zend_variables.h"
25 #include "zend_operators.h"
26 #include "zend_globals.h"
27 #include "zend_API.h"
28
29 /* Protection from recursive self-referencing class constants */
30 #define IS_CONSTANT_VISITED_MARK 0x80
31
32 #define IS_CONSTANT_VISITED(zv) (Z_ACCESS_FLAGS_P(zv) & IS_CONSTANT_VISITED_MARK)
33 #define MARK_CONSTANT_VISITED(zv) Z_ACCESS_FLAGS_P(zv) |= IS_CONSTANT_VISITED_MARK
34 #define RESET_CONSTANT_VISITED(zv) Z_ACCESS_FLAGS_P(zv) &= ~IS_CONSTANT_VISITED_MARK
35
free_zend_constant(zval * zv)36 void free_zend_constant(zval *zv)
37 {
38 zend_constant *c = Z_PTR_P(zv);
39
40 if (!(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)) {
41 zval_ptr_dtor_nogc(&c->value);
42 if (c->name) {
43 zend_string_release_ex(c->name, 0);
44 }
45 efree(c);
46 } else {
47 zval_internal_ptr_dtor(&c->value);
48 if (c->name) {
49 zend_string_release_ex(c->name, 1);
50 }
51 free(c);
52 }
53 }
54
55
56 #ifdef ZTS
copy_zend_constant(zval * zv)57 static void copy_zend_constant(zval *zv)
58 {
59 zend_constant *c = Z_PTR_P(zv);
60
61 ZEND_ASSERT(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT);
62 Z_PTR_P(zv) = pemalloc(sizeof(zend_constant), 1);
63 memcpy(Z_PTR_P(zv), c, sizeof(zend_constant));
64
65 c = Z_PTR_P(zv);
66 c->name = zend_string_copy(c->name);
67 if (Z_TYPE(c->value) == IS_STRING) {
68 Z_STR(c->value) = zend_string_dup(Z_STR(c->value), 1);
69 }
70 }
71
72
zend_copy_constants(HashTable * target,HashTable * source)73 void zend_copy_constants(HashTable *target, HashTable *source)
74 {
75 zend_hash_copy(target, source, copy_zend_constant);
76 }
77 #endif
78
79
clean_module_constant(zval * el,void * arg)80 static int clean_module_constant(zval *el, void *arg)
81 {
82 zend_constant *c = (zend_constant *)Z_PTR_P(el);
83 int module_number = *(int *)arg;
84
85 if (ZEND_CONSTANT_MODULE_NUMBER(c) == module_number) {
86 return 1;
87 } else {
88 return 0;
89 }
90 }
91
92
clean_module_constants(int module_number)93 void clean_module_constants(int module_number)
94 {
95 zend_hash_apply_with_argument(EG(zend_constants), clean_module_constant, (void *) &module_number);
96 }
97
98
zend_startup_constants(void)99 int zend_startup_constants(void)
100 {
101 EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
102
103 zend_hash_init(EG(zend_constants), 128, NULL, ZEND_CONSTANT_DTOR, 1);
104 return SUCCESS;
105 }
106
107
108
zend_register_standard_constants(void)109 void zend_register_standard_constants(void)
110 {
111 REGISTER_MAIN_LONG_CONSTANT("E_ERROR", E_ERROR, CONST_PERSISTENT | CONST_CS);
112 REGISTER_MAIN_LONG_CONSTANT("E_RECOVERABLE_ERROR", E_RECOVERABLE_ERROR, CONST_PERSISTENT | CONST_CS);
113 REGISTER_MAIN_LONG_CONSTANT("E_WARNING", E_WARNING, CONST_PERSISTENT | CONST_CS);
114 REGISTER_MAIN_LONG_CONSTANT("E_PARSE", E_PARSE, CONST_PERSISTENT | CONST_CS);
115 REGISTER_MAIN_LONG_CONSTANT("E_NOTICE", E_NOTICE, CONST_PERSISTENT | CONST_CS);
116 REGISTER_MAIN_LONG_CONSTANT("E_STRICT", E_STRICT, CONST_PERSISTENT | CONST_CS);
117 REGISTER_MAIN_LONG_CONSTANT("E_DEPRECATED", E_DEPRECATED, CONST_PERSISTENT | CONST_CS);
118 REGISTER_MAIN_LONG_CONSTANT("E_CORE_ERROR", E_CORE_ERROR, CONST_PERSISTENT | CONST_CS);
119 REGISTER_MAIN_LONG_CONSTANT("E_CORE_WARNING", E_CORE_WARNING, CONST_PERSISTENT | CONST_CS);
120 REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_ERROR", E_COMPILE_ERROR, CONST_PERSISTENT | CONST_CS);
121 REGISTER_MAIN_LONG_CONSTANT("E_COMPILE_WARNING", E_COMPILE_WARNING, CONST_PERSISTENT | CONST_CS);
122 REGISTER_MAIN_LONG_CONSTANT("E_USER_ERROR", E_USER_ERROR, CONST_PERSISTENT | CONST_CS);
123 REGISTER_MAIN_LONG_CONSTANT("E_USER_WARNING", E_USER_WARNING, CONST_PERSISTENT | CONST_CS);
124 REGISTER_MAIN_LONG_CONSTANT("E_USER_NOTICE", E_USER_NOTICE, CONST_PERSISTENT | CONST_CS);
125 REGISTER_MAIN_LONG_CONSTANT("E_USER_DEPRECATED", E_USER_DEPRECATED, CONST_PERSISTENT | CONST_CS);
126
127 REGISTER_MAIN_LONG_CONSTANT("E_ALL", E_ALL, CONST_PERSISTENT | CONST_CS);
128
129 REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_PROVIDE_OBJECT", DEBUG_BACKTRACE_PROVIDE_OBJECT, CONST_PERSISTENT | CONST_CS);
130 REGISTER_MAIN_LONG_CONSTANT("DEBUG_BACKTRACE_IGNORE_ARGS", DEBUG_BACKTRACE_IGNORE_ARGS, CONST_PERSISTENT | CONST_CS);
131 /* true/false constants */
132 {
133 REGISTER_MAIN_BOOL_CONSTANT("TRUE", 1, CONST_PERSISTENT | CONST_CT_SUBST);
134 REGISTER_MAIN_BOOL_CONSTANT("FALSE", 0, CONST_PERSISTENT | CONST_CT_SUBST);
135 REGISTER_MAIN_BOOL_CONSTANT("ZEND_THREAD_SAFE", ZTS_V, CONST_PERSISTENT | CONST_CS);
136 REGISTER_MAIN_BOOL_CONSTANT("ZEND_DEBUG_BUILD", ZEND_DEBUG, CONST_PERSISTENT | CONST_CS);
137 }
138 REGISTER_MAIN_NULL_CONSTANT("NULL", CONST_PERSISTENT | CONST_CT_SUBST);
139 }
140
141
zend_shutdown_constants(void)142 int zend_shutdown_constants(void)
143 {
144 zend_hash_destroy(EG(zend_constants));
145 free(EG(zend_constants));
146 return SUCCESS;
147 }
148
zend_register_null_constant(const char * name,size_t name_len,int flags,int module_number)149 ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int flags, int module_number)
150 {
151 zend_constant c;
152
153 ZVAL_NULL(&c.value);
154 ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
155 c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
156 zend_register_constant(&c);
157 }
158
zend_register_bool_constant(const char * name,size_t name_len,zend_bool bval,int flags,int module_number)159 ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, zend_bool bval, int flags, int module_number)
160 {
161 zend_constant c;
162
163 ZVAL_BOOL(&c.value, bval);
164 ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
165 c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
166 zend_register_constant(&c);
167 }
168
zend_register_long_constant(const char * name,size_t name_len,zend_long lval,int flags,int module_number)169 ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number)
170 {
171 zend_constant c;
172
173 ZVAL_LONG(&c.value, lval);
174 ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
175 c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
176 zend_register_constant(&c);
177 }
178
179
zend_register_double_constant(const char * name,size_t name_len,double dval,int flags,int module_number)180 ZEND_API void zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number)
181 {
182 zend_constant c;
183
184 ZVAL_DOUBLE(&c.value, dval);
185 ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
186 c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
187 zend_register_constant(&c);
188 }
189
190
zend_register_stringl_constant(const char * name,size_t name_len,char * strval,size_t strlen,int flags,int module_number)191 ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, char *strval, size_t strlen, int flags, int module_number)
192 {
193 zend_constant c;
194
195 ZVAL_STR(&c.value, zend_string_init_interned(strval, strlen, flags & CONST_PERSISTENT));
196 ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number);
197 c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT);
198 zend_register_constant(&c);
199 }
200
201
zend_register_string_constant(const char * name,size_t name_len,char * strval,int flags,int module_number)202 ZEND_API void zend_register_string_constant(const char *name, size_t name_len, char *strval, int flags, int module_number)
203 {
204 zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number);
205 }
206
zend_get_special_constant(const char * name,size_t name_len)207 static zend_constant *zend_get_special_constant(const char *name, size_t name_len)
208 {
209 zend_constant *c;
210 static const char haltoff[] = "__COMPILER_HALT_OFFSET__";
211
212 if (!EG(current_execute_data)) {
213 return NULL;
214 } else if (name_len == sizeof("__COMPILER_HALT_OFFSET__")-1 &&
215 !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) {
216 const char *cfilename;
217 zend_string *haltname;
218 size_t clen;
219
220 cfilename = zend_get_executed_filename();
221 clen = strlen(cfilename);
222 /* check for __COMPILER_HALT_OFFSET__ */
223 haltname = zend_mangle_property_name(haltoff,
224 sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0);
225 c = zend_hash_find_ptr(EG(zend_constants), haltname);
226 zend_string_efree(haltname);
227 return c;
228 } else {
229 return NULL;
230 }
231 }
232
zend_verify_const_access(zend_class_constant * c,zend_class_entry * scope)233 ZEND_API int zend_verify_const_access(zend_class_constant *c, zend_class_entry *scope) /* {{{ */
234 {
235 if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PUBLIC) {
236 return 1;
237 } else if (Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PRIVATE) {
238 return (c->ce == scope);
239 } else {
240 ZEND_ASSERT(Z_ACCESS_FLAGS(c->value) & ZEND_ACC_PROTECTED);
241 return zend_check_protected(c->ce, scope);
242 }
243 }
244 /* }}} */
245
zend_get_constant_str_impl(const char * name,size_t name_len)246 static inline zend_constant *zend_get_constant_str_impl(const char *name, size_t name_len)
247 {
248 zend_constant *c;
249 ALLOCA_FLAG(use_heap)
250
251 if ((c = zend_hash_str_find_ptr(EG(zend_constants), name, name_len)) == NULL) {
252 char *lcname = do_alloca(name_len + 1, use_heap);
253 zend_str_tolower_copy(lcname, name, name_len);
254 if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, name_len)) != NULL) {
255 if (ZEND_CONSTANT_FLAGS(c) & CONST_CS) {
256 c = NULL;
257 }
258 } else {
259 c = zend_get_special_constant(name, name_len);
260 }
261 free_alloca(lcname, use_heap);
262 }
263
264 return c;
265 }
266
zend_get_constant_str(const char * name,size_t name_len)267 ZEND_API zval *zend_get_constant_str(const char *name, size_t name_len)
268 {
269 zend_constant *c = zend_get_constant_str_impl(name, name_len);
270 return c ? &c->value : NULL;
271 }
272
zend_get_constant_impl(zend_string * name)273 static inline zend_constant *zend_get_constant_impl(zend_string *name)
274 {
275 zval *zv;
276 zend_constant *c;
277 ALLOCA_FLAG(use_heap)
278
279 zv = zend_hash_find(EG(zend_constants), name);
280 if (zv == NULL) {
281 char *lcname = do_alloca(ZSTR_LEN(name) + 1, use_heap);
282 zend_str_tolower_copy(lcname, ZSTR_VAL(name), ZSTR_LEN(name));
283 zv = zend_hash_str_find(EG(zend_constants), lcname, ZSTR_LEN(name));
284 if (zv != NULL) {
285 c = Z_PTR_P(zv);
286 if (ZEND_CONSTANT_FLAGS(c) & CONST_CS) {
287 c = NULL;
288 }
289 } else {
290 c = zend_get_special_constant(ZSTR_VAL(name), ZSTR_LEN(name));
291 }
292 free_alloca(lcname, use_heap);
293 return c;
294 } else {
295 return (zend_constant *) Z_PTR_P(zv);
296 }
297 }
298
zend_get_constant(zend_string * name)299 ZEND_API zval *zend_get_constant(zend_string *name)
300 {
301 zend_constant *c = zend_get_constant_impl(name);
302 return c ? &c->value : NULL;
303 }
304
is_access_deprecated(const zend_constant * c,const char * access_name)305 static zend_bool is_access_deprecated(const zend_constant *c, const char *access_name) {
306 const char *ns_sep = zend_memrchr(ZSTR_VAL(c->name), '\\', ZSTR_LEN(c->name));
307 if (ns_sep) {
308 /* Namespaces are always case-insensitive. Only compare shortname. */
309 size_t shortname_offset = ns_sep - ZSTR_VAL(c->name) + 1;
310 size_t shortname_len = ZSTR_LEN(c->name) - shortname_offset;
311 return memcmp(
312 access_name + shortname_offset,
313 ZSTR_VAL(c->name) + shortname_offset,
314 shortname_len
315 ) != 0;
316 } else {
317 /* No namespace, compare whole name */
318 return memcmp(access_name, ZSTR_VAL(c->name), ZSTR_LEN(c->name)) != 0;
319 }
320 }
321
zend_get_constant_ex(zend_string * cname,zend_class_entry * scope,uint32_t flags)322 ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags)
323 {
324 zend_constant *c;
325 const char *colon;
326 zend_class_entry *ce = NULL;
327 const char *name = ZSTR_VAL(cname);
328 size_t name_len = ZSTR_LEN(cname);
329
330 /* Skip leading \\ */
331 if (name[0] == '\\') {
332 name += 1;
333 name_len -= 1;
334 cname = NULL;
335 }
336
337 if ((colon = zend_memrchr(name, ':', name_len)) &&
338 colon > name && (*(colon - 1) == ':')) {
339 int class_name_len = colon - name - 1;
340 size_t const_name_len = name_len - class_name_len - 2;
341 zend_string *constant_name = zend_string_init(colon + 1, const_name_len, 0);
342 zend_string *class_name = zend_string_init(name, class_name_len, 0);
343 zend_class_constant *c = NULL;
344 zval *ret_constant = NULL;
345
346 if (zend_string_equals_literal_ci(class_name, "self")) {
347 if (UNEXPECTED(!scope)) {
348 zend_throw_error(NULL, "Cannot access self:: when no class scope is active");
349 goto failure;
350 }
351 ce = scope;
352 } else if (zend_string_equals_literal_ci(class_name, "parent")) {
353 if (UNEXPECTED(!scope)) {
354 zend_throw_error(NULL, "Cannot access parent:: when no class scope is active");
355 goto failure;
356 } else if (UNEXPECTED(!scope->parent)) {
357 zend_throw_error(NULL, "Cannot access parent:: when current class scope has no parent");
358 goto failure;
359 } else {
360 ce = scope->parent;
361 }
362 } else if (zend_string_equals_literal_ci(class_name, "static")) {
363 ce = zend_get_called_scope(EG(current_execute_data));
364 if (UNEXPECTED(!ce)) {
365 zend_throw_error(NULL, "Cannot access static:: when no class scope is active");
366 goto failure;
367 }
368 } else {
369 ce = zend_fetch_class(class_name, flags);
370 }
371 if (ce) {
372 c = zend_hash_find_ptr(&ce->constants_table, constant_name);
373 if (c == NULL) {
374 if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
375 zend_throw_error(NULL, "Undefined class constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
376 goto failure;
377 }
378 ret_constant = NULL;
379 } else {
380 if (!zend_verify_const_access(c, scope)) {
381 if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
382 zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
383 }
384 goto failure;
385 }
386 ret_constant = &c->value;
387 }
388 }
389
390 if (ret_constant && Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) {
391 int ret;
392
393 if (IS_CONSTANT_VISITED(ret_constant)) {
394 zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
395 ret_constant = NULL;
396 goto failure;
397 }
398
399 MARK_CONSTANT_VISITED(ret_constant);
400 ret = zval_update_constant_ex(ret_constant, c->ce);
401 RESET_CONSTANT_VISITED(ret_constant);
402
403 if (UNEXPECTED(ret != SUCCESS)) {
404 ret_constant = NULL;
405 goto failure;
406 }
407 }
408 failure:
409 zend_string_release_ex(class_name, 0);
410 zend_string_efree(constant_name);
411 return ret_constant;
412 }
413
414 /* non-class constant */
415 if ((colon = zend_memrchr(name, '\\', name_len)) != NULL) {
416 /* compound constant name */
417 int prefix_len = colon - name;
418 size_t const_name_len = name_len - prefix_len - 1;
419 const char *constant_name = colon + 1;
420 char *lcname;
421 size_t lcname_len;
422 ALLOCA_FLAG(use_heap)
423
424 lcname_len = prefix_len + 1 + const_name_len;
425 lcname = do_alloca(lcname_len + 1, use_heap);
426 zend_str_tolower_copy(lcname, name, prefix_len);
427 /* Check for namespace constant */
428
429 lcname[prefix_len] = '\\';
430 memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1);
431
432 if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) == NULL) {
433 /* try lowercase */
434 zend_str_tolower(lcname + prefix_len + 1, const_name_len);
435 if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) != NULL) {
436 if ((ZEND_CONSTANT_FLAGS(c) & CONST_CS) != 0) {
437 c = NULL;
438 }
439 }
440 }
441 free_alloca(lcname, use_heap);
442
443 if (!c) {
444 if (!(flags & IS_CONSTANT_UNQUALIFIED)) {
445 return NULL;
446 }
447
448 /* name requires runtime resolution, need to check non-namespaced name */
449 c = zend_get_constant_str_impl(constant_name, const_name_len);
450 name = constant_name;
451 }
452 } else {
453 if (cname) {
454 c = zend_get_constant_impl(cname);
455 } else {
456 c = zend_get_constant_str_impl(name, name_len);
457 }
458 }
459
460 if (!c) {
461 return NULL;
462 }
463
464 if (!(flags & ZEND_GET_CONSTANT_NO_DEPRECATION_CHECK)) {
465 if (!(ZEND_CONSTANT_FLAGS(c) & (CONST_CS|CONST_CT_SUBST)) && is_access_deprecated(c, name)) {
466 zend_error(E_DEPRECATED,
467 "Case-insensitive constants are deprecated. "
468 "The correct casing for this constant is \"%s\"",
469 ZSTR_VAL(c->name));
470 }
471 }
472
473 return &c->value;
474 }
475
zend_hash_add_constant(HashTable * ht,zend_string * key,zend_constant * c)476 static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c)
477 {
478 void *ret;
479 zend_constant *copy = pemalloc(sizeof(zend_constant), ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT);
480
481 memcpy(copy, c, sizeof(zend_constant));
482 ret = zend_hash_add_ptr(ht, key, copy);
483 if (!ret) {
484 pefree(copy, ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT);
485 }
486 return ret;
487 }
488
zend_register_constant(zend_constant * c)489 ZEND_API int zend_register_constant(zend_constant *c)
490 {
491 zend_string *lowercase_name = NULL;
492 zend_string *name;
493 int ret = SUCCESS;
494
495 #if 0
496 printf("Registering constant for module %d\n", c->module_number);
497 #endif
498
499 if (!(ZEND_CONSTANT_FLAGS(c) & CONST_CS)) {
500 lowercase_name = zend_string_tolower_ex(c->name, ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT);
501 lowercase_name = zend_new_interned_string(lowercase_name);
502 name = lowercase_name;
503 } else {
504 char *slash = strrchr(ZSTR_VAL(c->name), '\\');
505 if (slash) {
506 lowercase_name = zend_string_init(ZSTR_VAL(c->name), ZSTR_LEN(c->name), ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT);
507 zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(c->name));
508 lowercase_name = zend_new_interned_string(lowercase_name);
509 name = lowercase_name;
510 } else {
511 name = c->name;
512 }
513 }
514
515 /* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */
516 if (zend_string_equals_literal(name, "__COMPILER_HALT_OFFSET__")
517 || zend_hash_add_constant(EG(zend_constants), name, c) == NULL) {
518
519 /* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */
520 if (ZSTR_VAL(c->name)[0] == '\0' && ZSTR_LEN(c->name) > sizeof("\0__COMPILER_HALT_OFFSET__")-1
521 && memcmp(ZSTR_VAL(name), "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {
522 }
523 zend_error(E_NOTICE,"Constant %s already defined", ZSTR_VAL(name));
524 zend_string_release(c->name);
525 if (!(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)) {
526 zval_ptr_dtor_nogc(&c->value);
527 }
528 ret = FAILURE;
529 }
530 if (lowercase_name) {
531 zend_string_release(lowercase_name);
532 }
533 return ret;
534 }
535
536
537 /*
538 * Local variables:
539 * tab-width: 4
540 * c-basic-offset: 4
541 * indent-tabs-mode: t
542 * End:
543 * vim600: sw=4 ts=4 fdm=marker
544 * vim<600: sw=4 ts=4
545 */
546