Skip to content

Commit fcf5ee2

Browse files
author
Anthony Ferrara
committed
Revert back functionality of ZPP
1 parent a226892 commit fcf5ee2

File tree

1 file changed

+178
-20
lines changed

1 file changed

+178
-20
lines changed

Zend/zend_API.c

Lines changed: 178 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,49 @@ ZEND_API int zend_get_object_classname(const zval *object, const char **class_na
258258
}
259259
/* }}} */
260260

261+
static int parse_arg_object_to_string(zval **arg, char **p, int *pl, int type TSRMLS_DC) /* {{{ */
262+
{
263+
if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
264+
zval *obj;
265+
MAKE_STD_ZVAL(obj);
266+
if (Z_OBJ_HANDLER_P(*arg, cast_object)(*arg, obj, type TSRMLS_CC) == SUCCESS) {
267+
zval_ptr_dtor(arg);
268+
*arg = obj;
269+
*pl = Z_STRLEN_PP(arg);
270+
*p = Z_STRVAL_PP(arg);
271+
return SUCCESS;
272+
}
273+
efree(obj);
274+
}
275+
/* Standard PHP objects */
276+
if (Z_OBJ_HT_PP(arg) == &std_object_handlers || !Z_OBJ_HANDLER_PP(arg, cast_object)) {
277+
SEPARATE_ZVAL_IF_NOT_REF(arg);
278+
if (zend_std_cast_object_tostring(*arg, *arg, type TSRMLS_CC) == SUCCESS) {
279+
*pl = Z_STRLEN_PP(arg);
280+
*p = Z_STRVAL_PP(arg);
281+
return SUCCESS;
282+
}
283+
}
284+
if (!Z_OBJ_HANDLER_PP(arg, cast_object) && Z_OBJ_HANDLER_PP(arg, get)) {
285+
int use_copy;
286+
zval *z = Z_OBJ_HANDLER_PP(arg, get)(*arg TSRMLS_CC);
287+
Z_ADDREF_P(z);
288+
if(Z_TYPE_P(z) != IS_OBJECT) {
289+
zval_dtor(*arg);
290+
Z_TYPE_P(*arg) = IS_NULL;
291+
zend_make_printable_zval(z, *arg, &use_copy);
292+
if (!use_copy) {
293+
ZVAL_ZVAL(*arg, z, 1, 1);
294+
}
295+
*pl = Z_STRLEN_PP(arg);
296+
*p = Z_STRVAL_PP(arg);
297+
return SUCCESS;
298+
}
299+
zval_ptr_dtor(&z);
300+
}
301+
return FAILURE;
302+
}
303+
/* }}} */
261304

262305
static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, const char **spec, char **error, int *severity TSRMLS_DC) /* {{{ */
263306
{
@@ -284,45 +327,160 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
284327
case 'L':
285328
{
286329
long *p = va_arg(*va, long *);
287-
if (FAILURE == convert_to_long_safe_ex(arg)) {
288-
return "long";
330+
switch (Z_TYPE_PP(arg)) {
331+
case IS_STRING:
332+
{
333+
double d;
334+
int type;
335+
336+
if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), p, &d, -1)) == 0) {
337+
return "long";
338+
} else if (type == IS_DOUBLE) {
339+
if (c == 'L') {
340+
if (d > LONG_MAX) {
341+
*p = LONG_MAX;
342+
break;
343+
} else if (d < LONG_MIN) {
344+
*p = LONG_MIN;
345+
break;
346+
}
347+
}
348+
349+
*p = zend_dval_to_lval(d);
350+
}
351+
}
352+
break;
353+
354+
case IS_DOUBLE:
355+
if (c == 'L') {
356+
if (Z_DVAL_PP(arg) > LONG_MAX) {
357+
*p = LONG_MAX;
358+
break;
359+
} else if (Z_DVAL_PP(arg) < LONG_MIN) {
360+
*p = LONG_MIN;
361+
break;
362+
}
363+
}
364+
case IS_NULL:
365+
case IS_LONG:
366+
case IS_BOOL:
367+
convert_to_long_ex(arg);
368+
*p = Z_LVAL_PP(arg);
369+
break;
370+
371+
case IS_ARRAY:
372+
case IS_OBJECT:
373+
case IS_RESOURCE:
374+
default:
375+
return "long";
289376
}
290-
*p = Z_LVAL_PP(arg);
291-
break;
292377
}
378+
break;
379+
293380
case 'd':
294381
{
295382
double *p = va_arg(*va, double *);
296-
if (FAILURE == convert_to_double_safe_ex(arg)) {
297-
return "double";
383+
switch (Z_TYPE_PP(arg)) {
384+
case IS_STRING:
385+
{
386+
long l;
387+
int type;
388+
389+
if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &l, p, -1)) == 0) {
390+
return "double";
391+
} else if (type == IS_LONG) {
392+
*p = (double) l;
393+
}
394+
}
395+
break;
396+
397+
case IS_NULL:
398+
case IS_LONG:
399+
case IS_DOUBLE:
400+
case IS_BOOL:
401+
convert_to_double_ex(arg);
402+
*p = Z_DVAL_PP(arg);
403+
break;
404+
405+
case IS_ARRAY:
406+
case IS_OBJECT:
407+
case IS_RESOURCE:
408+
default:
409+
return "double";
298410
}
299-
*p = Z_DVAL_PP(arg);
300-
break;
301411
}
412+
break;
413+
302414
case 'p':
303415
case 's':
304416
{
305417
char **p = va_arg(*va, char **);
306418
int *pl = va_arg(*va, int *);
307-
if (FAILURE == convert_to_string_safe_ex(arg)) {
308-
return c == 's' ? "string" : "a valid path";
309-
}
310-
if (c == 'p' && CHECK_ZVAL_NULL_PATH(*arg)) {
311-
return "a valid path";
419+
switch (Z_TYPE_PP(arg)) {
420+
case IS_NULL:
421+
if (return_null) {
422+
*p = NULL;
423+
*pl = 0;
424+
break;
425+
}
426+
/* break omitted intentionally */
427+
428+
case IS_STRING:
429+
case IS_LONG:
430+
case IS_DOUBLE:
431+
case IS_BOOL:
432+
convert_to_string_ex(arg);
433+
if (UNEXPECTED(Z_ISREF_PP(arg) != 0)) {
434+
/* it's dangerous to return pointers to string
435+
buffer of referenced variable, because it can
436+
be clobbered throug magic callbacks */
437+
SEPARATE_ZVAL(arg);
438+
}
439+
*p = Z_STRVAL_PP(arg);
440+
*pl = Z_STRLEN_PP(arg);
441+
if (c == 'p' && CHECK_ZVAL_NULL_PATH(*arg)) {
442+
return "a valid path";
443+
}
444+
break;
445+
446+
case IS_OBJECT:
447+
if (parse_arg_object_to_string(arg, p, pl, IS_STRING TSRMLS_CC) == SUCCESS) {
448+
if (c == 'p' && CHECK_ZVAL_NULL_PATH(*arg)) {
449+
return "a valid path";
450+
}
451+
break;
452+
}
453+
454+
case IS_ARRAY:
455+
case IS_RESOURCE:
456+
default:
457+
return c == 's' ? "string" : "a valid path";
312458
}
313-
*p = Z_STRVAL_PP(arg);
314-
*pl = Z_STRLEN_PP(arg);
315-
break;
316459
}
460+
break;
461+
317462
case 'b':
318463
{
319464
zend_bool *p = va_arg(*va, zend_bool *);
320-
if (FAILURE == convert_to_boolean_safe_ex(arg)) {
321-
return "boolean";
465+
switch (Z_TYPE_PP(arg)) {
466+
case IS_NULL:
467+
case IS_STRING:
468+
case IS_LONG:
469+
case IS_DOUBLE:
470+
case IS_BOOL:
471+
convert_to_boolean_ex(arg);
472+
*p = Z_BVAL_PP(arg);
473+
break;
474+
475+
case IS_ARRAY:
476+
case IS_OBJECT:
477+
case IS_RESOURCE:
478+
default:
479+
return "boolean";
322480
}
323-
*p = Z_BVAL_PP(arg);
324-
break;
325481
}
482+
break;
483+
326484
case 'r':
327485
{
328486
zval **p = va_arg(*va, zval **);

0 commit comments

Comments
 (0)