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