xref: /PHP-7.3/Zend/zend_ini.c (revision 46d62e54)
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    | Author: Zeev Suraski <zeev@php.net>                                  |
16    +----------------------------------------------------------------------+
17 */
18 
19 #include "zend.h"
20 #include "zend_sort.h"
21 #include "zend_API.h"
22 #include "zend_ini.h"
23 #include "zend_alloc.h"
24 #include "zend_operators.h"
25 #include "zend_strtod.h"
26 
27 static HashTable *registered_zend_ini_directives;
28 
29 #define NO_VALUE_PLAINTEXT		"no value"
30 #define NO_VALUE_HTML			"<i>no value</i>"
31 
32 /*
33  * hash_apply functions
34  */
zend_remove_ini_entries(zval * el,void * arg)35 static int zend_remove_ini_entries(zval *el, void *arg) /* {{{ */
36 {
37 	zend_ini_entry *ini_entry = (zend_ini_entry *)Z_PTR_P(el);
38 	int module_number = *(int *)arg;
39 	if (ini_entry->module_number == module_number) {
40 		return 1;
41 	} else {
42 		return 0;
43 	}
44 }
45 /* }}} */
46 
zend_restore_ini_entry_cb(zend_ini_entry * ini_entry,int stage)47 static int zend_restore_ini_entry_cb(zend_ini_entry *ini_entry, int stage) /* {{{ */
48 {
49 	int result = FAILURE;
50 
51 	if (ini_entry->modified) {
52 		if (ini_entry->on_modify) {
53 			zend_try {
54 			/* even if on_modify bails out, we have to continue on with restoring,
55 				since there can be allocated variables that would be freed on MM shutdown
56 				and would lead to memory corruption later ini entry is modified again */
57 				result = ini_entry->on_modify(ini_entry, ini_entry->orig_value, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage);
58 			} zend_end_try();
59 		}
60 		if (stage == ZEND_INI_STAGE_RUNTIME && result == FAILURE) {
61 			/* runtime failure is OK */
62 			return 1;
63 		}
64 		if (ini_entry->value != ini_entry->orig_value) {
65 			zend_string_release(ini_entry->value);
66 		}
67 		ini_entry->value = ini_entry->orig_value;
68 		ini_entry->modifiable = ini_entry->orig_modifiable;
69 		ini_entry->modified = 0;
70 		ini_entry->orig_value = NULL;
71 		ini_entry->orig_modifiable = 0;
72 	}
73 	return 0;
74 }
75 /* }}} */
76 
zend_restore_ini_entry_wrapper(zval * el)77 static int zend_restore_ini_entry_wrapper(zval *el) /* {{{ */
78 {
79 	zend_ini_entry *ini_entry = (zend_ini_entry *)Z_PTR_P(el);
80 	zend_restore_ini_entry_cb(ini_entry, ZEND_INI_STAGE_DEACTIVATE);
81 	return 1;
82 }
83 /* }}} */
84 
free_ini_entry(zval * zv)85 static void free_ini_entry(zval *zv) /* {{{ */
86 {
87 	zend_ini_entry *entry = (zend_ini_entry*)Z_PTR_P(zv);
88 
89 	zend_string_release_ex(entry->name, 1);
90 	if (entry->value) {
91 		zend_string_release(entry->value);
92 	}
93 	if (entry->orig_value) {
94 		zend_string_release_ex(entry->orig_value, 1);
95 	}
96 	free(entry);
97 }
98 /* }}} */
99 
100 /*
101  * Startup / shutdown
102  */
zend_ini_startup(void)103 ZEND_API int zend_ini_startup(void) /* {{{ */
104 {
105 	registered_zend_ini_directives = (HashTable *) malloc(sizeof(HashTable));
106 
107 	EG(ini_directives) = registered_zend_ini_directives;
108 	EG(modified_ini_directives) = NULL;
109 	EG(error_reporting_ini_entry) = NULL;
110 	zend_hash_init_ex(registered_zend_ini_directives, 128, NULL, free_ini_entry, 1, 0);
111 	return SUCCESS;
112 }
113 /* }}} */
114 
zend_ini_shutdown(void)115 ZEND_API int zend_ini_shutdown(void) /* {{{ */
116 {
117 	zend_ini_dtor(EG(ini_directives));
118 	return SUCCESS;
119 }
120 /* }}} */
121 
zend_ini_dtor(HashTable * ini_directives)122 ZEND_API void zend_ini_dtor(HashTable *ini_directives) /* {{{ */
123 {
124 	zend_hash_destroy(ini_directives);
125 	free(ini_directives);
126 }
127 /* }}} */
128 
zend_ini_global_shutdown(void)129 ZEND_API int zend_ini_global_shutdown(void) /* {{{ */
130 {
131 	zend_hash_destroy(registered_zend_ini_directives);
132 	free(registered_zend_ini_directives);
133 	return SUCCESS;
134 }
135 /* }}} */
136 
zend_ini_deactivate(void)137 ZEND_API int zend_ini_deactivate(void) /* {{{ */
138 {
139 	if (EG(modified_ini_directives)) {
140 		zend_hash_apply(EG(modified_ini_directives), zend_restore_ini_entry_wrapper);
141 		zend_hash_destroy(EG(modified_ini_directives));
142 		FREE_HASHTABLE(EG(modified_ini_directives));
143 		EG(modified_ini_directives) = NULL;
144 	}
145 	return SUCCESS;
146 }
147 /* }}} */
148 
149 #ifdef ZTS
copy_ini_entry(zval * zv)150 static void copy_ini_entry(zval *zv) /* {{{ */
151 {
152 	zend_ini_entry *old_entry = (zend_ini_entry*)Z_PTR_P(zv);
153 	zend_ini_entry *new_entry = pemalloc(sizeof(zend_ini_entry), 1);
154 
155 	Z_PTR_P(zv) = new_entry;
156 	memcpy(new_entry, old_entry, sizeof(zend_ini_entry));
157 	if (old_entry->name) {
158 		new_entry->name = zend_string_dup(old_entry->name, 1);
159 	}
160 	if (old_entry->value) {
161 		new_entry->value = zend_string_dup(old_entry->value, 1);
162 	}
163 	if (old_entry->orig_value) {
164 		new_entry->orig_value = zend_string_dup(old_entry->orig_value, 1);
165 	}
166 }
167 /* }}} */
168 
zend_copy_ini_directives(void)169 ZEND_API int zend_copy_ini_directives(void) /* {{{ */
170 {
171 	EG(modified_ini_directives) = NULL;
172 	EG(error_reporting_ini_entry) = NULL;
173 	EG(ini_directives) = (HashTable *) malloc(sizeof(HashTable));
174 	zend_hash_init_ex(EG(ini_directives), registered_zend_ini_directives->nNumOfElements, NULL, free_ini_entry, 1, 0);
175 	zend_hash_copy(EG(ini_directives), registered_zend_ini_directives, copy_ini_entry);
176 	return SUCCESS;
177 }
178 /* }}} */
179 #endif
180 
ini_key_compare(const void * a,const void * b)181 static int ini_key_compare(const void *a, const void *b) /* {{{ */
182 {
183 	const Bucket *f;
184 	const Bucket *s;
185 
186 	f = (const Bucket *) a;
187 	s = (const Bucket *) b;
188 
189 	if (!f->key && !s->key) { /* both numeric */
190 		if (f->h > s->h) {
191 			return -1;
192 		} else if (f->h < s->h) {
193 			return 1;
194 		}
195 		return 0;
196 	} else if (!f->key) { /* f is numeric, s is not */
197 		return -1;
198 	} else if (!s->key) { /* s is numeric, f is not */
199 		return 1;
200 	} else { /* both strings */
201 		return zend_binary_strcasecmp(ZSTR_VAL(f->key), ZSTR_LEN(f->key), ZSTR_VAL(s->key), ZSTR_LEN(s->key));
202 	}
203 }
204 /* }}} */
205 
zend_ini_sort_entries(void)206 ZEND_API void zend_ini_sort_entries(void) /* {{{ */
207 {
208 	zend_hash_sort(EG(ini_directives), ini_key_compare, 0);
209 }
210 /* }}} */
211 
212 /*
213  * Registration / unregistration
214  */
zend_register_ini_entries(const zend_ini_entry_def * ini_entry,int module_number)215 ZEND_API int zend_register_ini_entries(const zend_ini_entry_def *ini_entry, int module_number) /* {{{ */
216 {
217 	zend_ini_entry *p;
218 	zval *default_value;
219 	HashTable *directives = registered_zend_ini_directives;
220 
221 #ifdef ZTS
222 	/* if we are called during the request, eg: from dl(),
223 	 * then we should not touch the global directives table,
224 	 * and should update the per-(request|thread) version instead.
225 	 * This solves two problems: one is that ini entries for dl()'d
226 	 * extensions will now work, and the second is that updating the
227 	 * global hash here from dl() is not mutex protected and can
228 	 * lead to death.
229 	 */
230 	if (directives != EG(ini_directives)) {
231 		directives = EG(ini_directives);
232 	}
233 #endif
234 
235 	while (ini_entry->name) {
236 		p = pemalloc(sizeof(zend_ini_entry), 1);
237 		p->name = zend_string_init_interned(ini_entry->name, ini_entry->name_length, 1);
238 		p->on_modify = ini_entry->on_modify;
239 		p->mh_arg1 = ini_entry->mh_arg1;
240 		p->mh_arg2 = ini_entry->mh_arg2;
241 		p->mh_arg3 = ini_entry->mh_arg3;
242 		p->value = NULL;
243 		p->orig_value = NULL;
244 		p->displayer = ini_entry->displayer;
245 		p->modifiable = ini_entry->modifiable;
246 
247 		p->orig_modifiable = 0;
248 		p->modified = 0;
249 		p->module_number = module_number;
250 
251 		if (zend_hash_add_ptr(directives, p->name, (void*)p) == NULL) {
252 			if (p->name) {
253 				zend_string_release_ex(p->name, 1);
254 			}
255 			zend_unregister_ini_entries(module_number);
256 			return FAILURE;
257 		}
258 		if (((default_value = zend_get_configuration_directive(p->name)) != NULL) &&
259             (!p->on_modify || p->on_modify(p, Z_STR_P(default_value), p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP) == SUCCESS)) {
260 
261 			p->value = zend_new_interned_string(zend_string_copy(Z_STR_P(default_value)));
262 		} else {
263 			p->value = ini_entry->value ?
264 				zend_string_init_interned(ini_entry->value, ini_entry->value_length, 1) : NULL;
265 
266 			if (p->on_modify) {
267 				p->on_modify(p, p->value, p->mh_arg1, p->mh_arg2, p->mh_arg3, ZEND_INI_STAGE_STARTUP);
268 			}
269 		}
270 		ini_entry++;
271 	}
272 	return SUCCESS;
273 }
274 /* }}} */
275 
zend_unregister_ini_entries(int module_number)276 ZEND_API void zend_unregister_ini_entries(int module_number) /* {{{ */
277 {
278 	zend_hash_apply_with_argument(registered_zend_ini_directives, zend_remove_ini_entries, (void *) &module_number);
279 }
280 /* }}} */
281 
282 #ifdef ZTS
zend_ini_refresh_cache(zval * el,void * arg)283 static int zend_ini_refresh_cache(zval *el, void *arg) /* {{{ */
284 {
285 	zend_ini_entry *p = (zend_ini_entry *)Z_PTR_P(el);
286 	int stage = (int)(zend_intptr_t)arg;
287 
288 	if (p->on_modify) {
289 		p->on_modify(p, p->value, p->mh_arg1, p->mh_arg2, p->mh_arg3, stage);
290 	}
291 	return 0;
292 }
293 /* }}} */
294 
zend_ini_refresh_caches(int stage)295 ZEND_API void zend_ini_refresh_caches(int stage) /* {{{ */
296 {
297 	zend_hash_apply_with_argument(EG(ini_directives), zend_ini_refresh_cache, (void *)(zend_intptr_t) stage);
298 }
299 /* }}} */
300 #endif
301 
zend_alter_ini_entry(zend_string * name,zend_string * new_value,int modify_type,int stage)302 ZEND_API int zend_alter_ini_entry(zend_string *name, zend_string *new_value, int modify_type, int stage) /* {{{ */
303 {
304 
305 	return zend_alter_ini_entry_ex(name, new_value, modify_type, stage, 0);
306 }
307 /* }}} */
308 
zend_alter_ini_entry_chars(zend_string * name,const char * value,size_t value_length,int modify_type,int stage)309 ZEND_API int zend_alter_ini_entry_chars(zend_string *name, const char *value, size_t value_length, int modify_type, int stage) /* {{{ */
310 {
311     int ret;
312     zend_string *new_value;
313 
314 	new_value = zend_string_init(value, value_length, !(stage & ZEND_INI_STAGE_IN_REQUEST));
315 	ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, 0);
316 	zend_string_release(new_value);
317 	return ret;
318 }
319 /* }}} */
320 
zend_alter_ini_entry_chars_ex(zend_string * name,const char * value,size_t value_length,int modify_type,int stage,int force_change)321 ZEND_API int zend_alter_ini_entry_chars_ex(zend_string *name, const char *value, size_t value_length, int modify_type, int stage, int force_change) /* {{{ */
322 {
323     int ret;
324     zend_string *new_value;
325 
326 	new_value = zend_string_init(value, value_length, !(stage & ZEND_INI_STAGE_IN_REQUEST));
327 	ret = zend_alter_ini_entry_ex(name, new_value, modify_type, stage, force_change);
328 	zend_string_release(new_value);
329 	return ret;
330 }
331 /* }}} */
332 
zend_alter_ini_entry_ex(zend_string * name,zend_string * new_value,int modify_type,int stage,int force_change)333 ZEND_API int zend_alter_ini_entry_ex(zend_string *name, zend_string *new_value, int modify_type, int stage, int force_change) /* {{{ */
334 {
335 	zend_ini_entry *ini_entry;
336 	zend_string *duplicate;
337 	uint8_t modifiable;
338 	zend_bool modified;
339 
340 	if ((ini_entry = zend_hash_find_ptr(EG(ini_directives), name)) == NULL) {
341 		return FAILURE;
342 	}
343 
344 	modifiable = ini_entry->modifiable;
345 	modified = ini_entry->modified;
346 
347 	if (stage == ZEND_INI_STAGE_ACTIVATE && modify_type == ZEND_INI_SYSTEM) {
348 		ini_entry->modifiable = ZEND_INI_SYSTEM;
349 	}
350 
351 	if (!force_change) {
352 		if (!(ini_entry->modifiable & modify_type)) {
353 			return FAILURE;
354 		}
355 	}
356 
357 	if (!EG(modified_ini_directives)) {
358 		ALLOC_HASHTABLE(EG(modified_ini_directives));
359 		zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
360 	}
361 	if (!modified) {
362 		ini_entry->orig_value = ini_entry->value;
363 		ini_entry->orig_modifiable = modifiable;
364 		ini_entry->modified = 1;
365 		zend_hash_add_ptr(EG(modified_ini_directives), ini_entry->name, ini_entry);
366 	}
367 
368 	duplicate = zend_string_copy(new_value);
369 
370 	if (!ini_entry->on_modify
371 		|| ini_entry->on_modify(ini_entry, duplicate, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage) == SUCCESS) {
372 		if (modified && ini_entry->orig_value != ini_entry->value) { /* we already changed the value, free the changed value */
373 			zend_string_release(ini_entry->value);
374 		}
375 		ini_entry->value = duplicate;
376 	} else {
377 		zend_string_release(duplicate);
378 		return FAILURE;
379 	}
380 
381 	return SUCCESS;
382 }
383 /* }}} */
384 
zend_restore_ini_entry(zend_string * name,int stage)385 ZEND_API int zend_restore_ini_entry(zend_string *name, int stage) /* {{{ */
386 {
387 	zend_ini_entry *ini_entry;
388 
389 	if ((ini_entry = zend_hash_find_ptr(EG(ini_directives), name)) == NULL ||
390 		(stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) {
391 		return FAILURE;
392 	}
393 
394 	if (EG(modified_ini_directives)) {
395 		if (zend_restore_ini_entry_cb(ini_entry, stage) == 0) {
396 			zend_hash_del(EG(modified_ini_directives), name);
397 		} else {
398 			return FAILURE;
399 		}
400 	}
401 
402 	return SUCCESS;
403 }
404 /* }}} */
405 
zend_ini_register_displayer(char * name,uint32_t name_length,void (* displayer)(zend_ini_entry * ini_entry,int type))406 ZEND_API int zend_ini_register_displayer(char *name, uint32_t name_length, void (*displayer)(zend_ini_entry *ini_entry, int type)) /* {{{ */
407 {
408 	zend_ini_entry *ini_entry;
409 
410 	ini_entry = zend_hash_str_find_ptr(registered_zend_ini_directives, name, name_length);
411 	if (ini_entry == NULL) {
412 		return FAILURE;
413 	}
414 
415 	ini_entry->displayer = displayer;
416 	return SUCCESS;
417 }
418 /* }}} */
419 
420 /*
421  * Data retrieval
422  */
423 
zend_ini_long(char * name,size_t name_length,int orig)424 ZEND_API zend_long zend_ini_long(char *name, size_t name_length, int orig) /* {{{ */
425 {
426 	zend_ini_entry *ini_entry;
427 
428 	ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
429 	if (ini_entry) {
430 		if (orig && ini_entry->modified) {
431 			return (ini_entry->orig_value ? ZEND_STRTOL(ZSTR_VAL(ini_entry->orig_value), NULL, 0) : 0);
432 		} else {
433 			return (ini_entry->value      ? ZEND_STRTOL(ZSTR_VAL(ini_entry->value), NULL, 0)      : 0);
434 		}
435 	}
436 
437 	return 0;
438 }
439 /* }}} */
440 
zend_ini_double(char * name,size_t name_length,int orig)441 ZEND_API double zend_ini_double(char *name, size_t name_length, int orig) /* {{{ */
442 {
443 	zend_ini_entry *ini_entry;
444 
445 	ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
446 	if (ini_entry) {
447 		if (orig && ini_entry->modified) {
448 			return (double) (ini_entry->orig_value ? zend_strtod(ZSTR_VAL(ini_entry->orig_value), NULL) : 0.0);
449 		} else {
450 			return (double) (ini_entry->value      ? zend_strtod(ZSTR_VAL(ini_entry->value), NULL)      : 0.0);
451 		}
452 	}
453 
454 	return 0.0;
455 }
456 /* }}} */
457 
zend_ini_string_ex(char * name,size_t name_length,int orig,zend_bool * exists)458 ZEND_API char *zend_ini_string_ex(char *name, size_t name_length, int orig, zend_bool *exists) /* {{{ */
459 {
460 	zend_ini_entry *ini_entry;
461 
462 	ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
463 	if (ini_entry) {
464 		if (exists) {
465 			*exists = 1;
466 		}
467 
468 		if (orig && ini_entry->modified) {
469 			return ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : NULL;
470 		} else {
471 			return ini_entry->value ? ZSTR_VAL(ini_entry->value) : NULL;
472 		}
473 	} else {
474 		if (exists) {
475 			*exists = 0;
476 		}
477 		return NULL;
478 	}
479 }
480 /* }}} */
481 
zend_ini_string(char * name,size_t name_length,int orig)482 ZEND_API char *zend_ini_string(char *name, size_t name_length, int orig) /* {{{ */
483 {
484 	zend_bool exists = 1;
485 	char *return_value;
486 
487 	return_value = zend_ini_string_ex(name, name_length, orig, &exists);
488 	if (!exists) {
489 		return NULL;
490 	} else if (!return_value) {
491 		return_value = "";
492 	}
493 	return return_value;
494 }
495 /* }}} */
496 
zend_ini_get_value(zend_string * name)497 ZEND_API zend_string *zend_ini_get_value(zend_string *name) /* {{{ */
498 {
499 	zend_ini_entry *ini_entry;
500 
501 	ini_entry = zend_hash_find_ptr(EG(ini_directives), name);
502 	if (ini_entry) {
503 		return ini_entry->value ? ini_entry->value : ZSTR_EMPTY_ALLOC();
504 	} else {
505 		return NULL;
506 	}
507 }
508 /* }}} */
509 
zend_ini_parse_bool(zend_string * str)510 ZEND_API zend_bool zend_ini_parse_bool(zend_string *str)
511 {
512 	if ((ZSTR_LEN(str) == 4 && strcasecmp(ZSTR_VAL(str), "true") == 0)
513 	  || (ZSTR_LEN(str) == 3 && strcasecmp(ZSTR_VAL(str), "yes") == 0)
514 	  || (ZSTR_LEN(str) == 2 && strcasecmp(ZSTR_VAL(str), "on") == 0)) {
515 		return 1;
516 	} else {
517 		return atoi(ZSTR_VAL(str)) != 0;
518 	}
519 }
520 
521 #if TONY_20070307
zend_ini_displayer_cb(zend_ini_entry * ini_entry,int type)522 static void zend_ini_displayer_cb(zend_ini_entry *ini_entry, int type) /* {{{ */
523 {
524 	if (ini_entry->displayer) {
525 		ini_entry->displayer(ini_entry, type);
526 	} else {
527 		char *display_string;
528 		uint32_t display_string_length;
529 
530 		if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
531 			if (ini_entry->orig_value) {
532 				display_string = ini_entry->orig_value;
533 				display_string_length = ini_entry->orig_value_length;
534 			} else {
535 				if (zend_uv.html_errors) {
536 					display_string = NO_VALUE_HTML;
537 					display_string_length = sizeof(NO_VALUE_HTML) - 1;
538 				} else {
539 					display_string = NO_VALUE_PLAINTEXT;
540 					display_string_length = sizeof(NO_VALUE_PLAINTEXT) - 1;
541 				}
542 			}
543 		} else if (ini_entry->value && ini_entry->value[0]) {
544 			display_string = ini_entry->value;
545 			display_string_length = ini_entry->value_length;
546 		} else {
547 			if (zend_uv.html_errors) {
548 				display_string = NO_VALUE_HTML;
549 				display_string_length = sizeof(NO_VALUE_HTML) - 1;
550 			} else {
551 				display_string = NO_VALUE_PLAINTEXT;
552 				display_string_length = sizeof(NO_VALUE_PLAINTEXT) - 1;
553 			}
554 		}
555 		ZEND_WRITE(display_string, display_string_length);
556 	}
557 }
558 /* }}} */
559 #endif
560 
ZEND_INI_DISP(zend_ini_boolean_displayer_cb)561 ZEND_INI_DISP(zend_ini_boolean_displayer_cb) /* {{{ */
562 {
563 	int value;
564 	zend_string *tmp_value;
565 
566 	if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
567 		tmp_value = (ini_entry->orig_value ? ini_entry->orig_value : NULL );
568 	} else if (ini_entry->value) {
569 		tmp_value = ini_entry->value;
570 	} else {
571 		tmp_value = NULL;
572 	}
573 
574 	if (tmp_value) {
575 		value = zend_ini_parse_bool(tmp_value);
576 	} else {
577 		value = 0;
578 	}
579 
580 	if (value) {
581 		ZEND_PUTS("On");
582 	} else {
583 		ZEND_PUTS("Off");
584 	}
585 }
586 /* }}} */
587 
ZEND_INI_DISP(zend_ini_color_displayer_cb)588 ZEND_INI_DISP(zend_ini_color_displayer_cb) /* {{{ */
589 {
590 	char *value;
591 
592 	if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
593 		value = ZSTR_VAL(ini_entry->orig_value);
594 	} else if (ini_entry->value) {
595 		value = ZSTR_VAL(ini_entry->value);
596 	} else {
597 		value = NULL;
598 	}
599 	if (value) {
600 		if (zend_uv.html_errors) {
601 			zend_printf("<font style=\"color: %s\">%s</font>", value, value);
602 		} else {
603 			ZEND_PUTS(value);
604 		}
605 	} else {
606 		if (zend_uv.html_errors) {
607 			ZEND_PUTS(NO_VALUE_HTML);
608 		} else {
609 			ZEND_PUTS(NO_VALUE_PLAINTEXT);
610 		}
611 	}
612 }
613 /* }}} */
614 
ZEND_INI_DISP(display_link_numbers)615 ZEND_INI_DISP(display_link_numbers) /* {{{ */
616 {
617 	char *value;
618 
619 	if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
620 		value = ZSTR_VAL(ini_entry->orig_value);
621 	} else if (ini_entry->value) {
622 		value = ZSTR_VAL(ini_entry->value);
623 	} else {
624 		value = NULL;
625 	}
626 
627 	if (value) {
628 		if (atoi(value) == -1) {
629 			ZEND_PUTS("Unlimited");
630 		} else {
631 			zend_printf("%s", value);
632 		}
633 	}
634 }
635 /* }}} */
636 
637 /* Standard message handlers */
ZEND_INI_MH(OnUpdateBool)638 ZEND_API ZEND_INI_MH(OnUpdateBool) /* {{{ */
639 {
640 	zend_bool *p;
641 #ifndef ZTS
642 	char *base = (char *) mh_arg2;
643 #else
644 	char *base;
645 
646 	base = (char *) ts_resource(*((int *) mh_arg2));
647 #endif
648 
649 	p = (zend_bool *) (base+(size_t) mh_arg1);
650 
651 	*p = zend_ini_parse_bool(new_value);
652 	return SUCCESS;
653 }
654 /* }}} */
655 
ZEND_INI_MH(OnUpdateLong)656 ZEND_API ZEND_INI_MH(OnUpdateLong) /* {{{ */
657 {
658 	zend_long *p;
659 #ifndef ZTS
660 	char *base = (char *) mh_arg2;
661 #else
662 	char *base;
663 
664 	base = (char *) ts_resource(*((int *) mh_arg2));
665 #endif
666 
667 	p = (zend_long *) (base+(size_t) mh_arg1);
668 
669 	*p = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
670 	return SUCCESS;
671 }
672 /* }}} */
673 
ZEND_INI_MH(OnUpdateLongGEZero)674 ZEND_API ZEND_INI_MH(OnUpdateLongGEZero) /* {{{ */
675 {
676 	zend_long *p, tmp;
677 #ifndef ZTS
678 	char *base = (char *) mh_arg2;
679 #else
680 	char *base;
681 
682 	base = (char *) ts_resource(*((int *) mh_arg2));
683 #endif
684 
685 	tmp = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
686 	if (tmp < 0) {
687 		return FAILURE;
688 	}
689 
690 	p = (zend_long *) (base+(size_t) mh_arg1);
691 	*p = tmp;
692 
693 	return SUCCESS;
694 }
695 /* }}} */
696 
ZEND_INI_MH(OnUpdateReal)697 ZEND_API ZEND_INI_MH(OnUpdateReal) /* {{{ */
698 {
699 	double *p;
700 #ifndef ZTS
701 	char *base = (char *) mh_arg2;
702 #else
703 	char *base;
704 
705 	base = (char *) ts_resource(*((int *) mh_arg2));
706 #endif
707 
708 	p = (double *) (base+(size_t) mh_arg1);
709 
710 	*p = zend_strtod(ZSTR_VAL(new_value), NULL);
711 	return SUCCESS;
712 }
713 /* }}} */
714 
ZEND_INI_MH(OnUpdateString)715 ZEND_API ZEND_INI_MH(OnUpdateString) /* {{{ */
716 {
717 	char **p;
718 #ifndef ZTS
719 	char *base = (char *) mh_arg2;
720 #else
721 	char *base;
722 
723 	base = (char *) ts_resource(*((int *) mh_arg2));
724 #endif
725 
726 	p = (char **) (base+(size_t) mh_arg1);
727 
728 	*p = new_value ? ZSTR_VAL(new_value) : NULL;
729 	return SUCCESS;
730 }
731 /* }}} */
732 
ZEND_INI_MH(OnUpdateStringUnempty)733 ZEND_API ZEND_INI_MH(OnUpdateStringUnempty) /* {{{ */
734 {
735 	char **p;
736 #ifndef ZTS
737 	char *base = (char *) mh_arg2;
738 #else
739 	char *base;
740 
741 	base = (char *) ts_resource(*((int *) mh_arg2));
742 #endif
743 
744 	if (new_value && !ZSTR_VAL(new_value)[0]) {
745 		return FAILURE;
746 	}
747 
748 	p = (char **) (base+(size_t) mh_arg1);
749 
750 	*p = new_value ? ZSTR_VAL(new_value) : NULL;
751 	return SUCCESS;
752 }
753 /* }}} */
754 
755 /*
756  * Local variables:
757  * tab-width: 4
758  * c-basic-offset: 4
759  * indent-tabs-mode: t
760  * End:
761  * vim600: sw=4 ts=4 fdm=marker
762  * vim<600: sw=4 ts=4
763  */
764