Skip to content

Commit 88c550a

Browse files
committed
Added vstrpprintf strpprintf to avoid duplicate string
(the function name maybe improvement)
1 parent e2890e3 commit 88c550a

File tree

9 files changed

+82
-47
lines changed

9 files changed

+82
-47
lines changed

Zend/zend.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ ZEND_API void (*zend_unblock_interruptions)(void);
5555
ZEND_API void (*zend_ticks_function)(int ticks TSRMLS_DC);
5656
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
5757
int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
58+
zend_string *(*zend_vstrpprintf)(size_t max_len, const char *format, va_list ap);
5859
ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
5960
ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
6061

@@ -676,6 +677,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
676677
zend_ticks_function = utility_functions->ticks_function;
677678
zend_on_timeout = utility_functions->on_timeout;
678679
zend_vspprintf = utility_functions->vspprintf_function;
680+
zend_vstrpprintf = utility_functions->vstrpprintf_function;
679681
zend_getenv = utility_functions->getenv_function;
680682
zend_resolve_path = utility_functions->resolve_path_function;
681683

Zend/zend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ typedef struct _zend_utility_functions {
522522
void (*on_timeout)(int seconds TSRMLS_DC);
523523
int (*stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
524524
int (*vspprintf_function)(char **pbuf, size_t max_len, const char *format, va_list ap);
525+
zend_string *(*vstrpprintf_function)(size_t max_len, const char *format, va_list ap);
525526
char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC);
526527
char *(*resolve_path_function)(const char *filename, int filename_len TSRMLS_DC);
527528
} zend_utility_functions;
@@ -632,6 +633,7 @@ extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, cons
632633
extern ZEND_API void (*zend_on_timeout)(int seconds TSRMLS_DC);
633634
extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
634635
extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list ap);
636+
extern zend_string *(*zend_vstrpprintf)(size_t max_len, const char *format, va_list ap);
635637
extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
636638
extern ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
637639

Zend/zend_closures.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -313,23 +313,20 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
313313
array_init(&val);
314314

315315
for (i = 0; i < closure->func.common.num_args; i++) {
316-
char *name, *info;
317-
int name_len, info_len;
316+
zend_string *name;
317+
zval info;
318318
if (arg_info->name) {
319-
name_len = zend_spprintf(&name, 0, "%s$%s",
320-
arg_info->pass_by_reference ? "&" : "",
321-
arg_info->name);
319+
name = zend_strpprintf(0, "%s$%s",
320+
arg_info->pass_by_reference ? "&" : "",
321+
arg_info->name);
322322
} else {
323-
name_len = zend_spprintf(&name, 0, "%s$param%d",
324-
arg_info->pass_by_reference ? "&" : "",
325-
i + 1);
323+
name = zend_strpprintf(0, "%s$param%d",
324+
arg_info->pass_by_reference ? "&" : "",
325+
i + 1);
326326
}
327-
info_len = zend_spprintf(&info, 0, "%s",
328-
i >= required ? "<optional>" : "<required>");
329-
// TODO: avoid reallocation ???
330-
add_assoc_stringl_ex(&val, name, name_len, info, info_len);
331-
efree(info);
332-
efree(name);
327+
ZVAL_STR(&info, zend_strpprintf(0, "%s", i >= required ? "<optional>" : "<required>"));
328+
zend_hash_update(Z_ARRVAL(val), name, &info);
329+
STR_RELEASE(name);
333330
arg_info++;
334331
}
335332
zend_hash_str_update(closure->debug_info, "parameter", sizeof("parameter")-1, &val);

Zend/zend_exceptions.c

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ ZEND_METHOD(exception, getPrevious)
618618

619619
previous = zend_read_property(default_exception_ce, getThis(), "previous", sizeof("previous")-1, 1 TSRMLS_CC);
620620
RETURN_ZVAL(previous, 1, 0);
621-
}
621+
} /* }}} */
622622

623623
int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ */
624624
{
@@ -632,19 +632,30 @@ int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ *
632632
}
633633
/* }}} */
634634

635+
zend_string *zend_strpprintf(int max_len, const char *format, ...) /* {{{ */
636+
{
637+
va_list arg;
638+
zend_string *str;
639+
640+
va_start(arg, format);
641+
str = zend_vstrpprintf(max_len, format, arg);
642+
va_end(arg);
643+
return str;
644+
}
645+
/* }}} */
646+
635647
/* {{{ proto string Exception::__toString()
636648
Obtain the string representation of the Exception object */
637649
ZEND_METHOD(exception, __toString)
638650
{
639651
zval message, file, line, trace, *exception;
640-
char *str, *prev_str;
641-
int len = 0;
652+
zend_string *str, *prev_str;
642653
zend_fcall_info fci;
643654
zval fname;
644655

645656
DEFAULT_0_PARAMS;
646657

647-
str = estrndup("", 0);
658+
str = STR_EMPTY_ALLOC();
648659

649660
exception = getThis();
650661
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1);
@@ -677,17 +688,17 @@ ZEND_METHOD(exception, __toString)
677688
}
678689

679690
if (Z_STRLEN(message) > 0) {
680-
len = zend_spprintf(&str, 0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
681-
Z_OBJCE_P(exception)->name->val, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
682-
(Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
683-
len ? "\n\nNext " : "", prev_str);
691+
str = zend_strpprintf(0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
692+
Z_OBJCE_P(exception)->name->val, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
693+
(Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
694+
prev_str->len ? "\n\nNext " : "", prev_str->val);
684695
} else {
685-
len = zend_spprintf(&str, 0, "exception '%s' in %s:%ld\nStack trace:\n%s%s%s",
686-
Z_OBJCE_P(exception)->name->val, Z_STRVAL(file), Z_LVAL(line),
687-
(Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
688-
len ? "\n\nNext " : "", prev_str);
696+
str = zend_strpprintf(0, "exception '%s' in %s:%ld\nStack trace:\n%s%s%s",
697+
Z_OBJCE_P(exception)->name->val, Z_STRVAL(file), Z_LVAL(line),
698+
(Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
699+
prev_str->len ? "\n\nNext " : "", prev_str->val);
689700
}
690-
efree(prev_str);
701+
STR_RELEASE(prev_str);
691702
zval_dtor(&message);
692703
zval_dtor(&file);
693704
zval_dtor(&line);
@@ -701,11 +712,9 @@ ZEND_METHOD(exception, __toString)
701712

702713
/* We store the result in the private property string so we can access
703714
* the result in uncaught exception handlers without memleaks. */
704-
zend_update_property_string(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);
715+
zend_update_property_str(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);
705716

706-
// TODO: avoid reallocation ???
707-
RETVAL_STRINGL(str, len);
708-
efree(str);
717+
RETURN_STR(str);
709718
}
710719
/* }}} */
711720

Zend/zend_exceptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ ZEND_API void zend_exception_error(zend_object *exception, int severity TSRMLS_D
5454

5555
/* do not export, in php it's available thru spprintf directly */
5656
int zend_spprintf(char **message, int max_len, const char *format, ...);
57+
zend_string *zend_strpprintf(int max_len, const char *format, ...);
5758

5859
END_EXTERN_C()
5960

Zend/zend_operators.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -621,15 +621,13 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
621621
break;
622622
}
623623
case IS_DOUBLE: {
624-
char *str;
625-
int len;
624+
zend_string *str;
626625
double dval = Z_DVAL_P(op);
627626
TSRMLS_FETCH();
628627

629-
len = zend_spprintf(&str, 0, "%.*G", (int) EG(precision), dval);
628+
str = zend_strpprintf(0, "%.*G", (int) EG(precision), dval);
630629
/* %G already handles removing trailing zeros from the fractional part, yay */
631-
ZVAL_NEW_STR(op, STR_INIT(str, len, 0));
632-
efree(str);
630+
ZVAL_NEW_STR(op, str);
633631
break;
634632
}
635633
case IS_ARRAY:
@@ -910,11 +908,7 @@ ZEND_API zend_string *_zval_get_string_func(zval *op TSRMLS_DC) /* {{{ */
910908
return STR_INIT(buf, len, 0);
911909
}
912910
case IS_DOUBLE: {
913-
char *str;
914-
int len = zend_spprintf(&str, 0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
915-
zend_string *retval = STR_INIT(str, len, 0);
916-
efree(str);
917-
return retval;
911+
return zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
918912
}
919913
case IS_ARRAY:
920914
zend_error(E_NOTICE, "Array to string conversion");
@@ -2529,12 +2523,10 @@ ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) /
25292523
ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
25302524
{
25312525
TSRMLS_FETCH();
2532-
char *str;
2533-
int len;
2526+
zend_string *str;
25342527

2535-
len = zend_spprintf(&str, 0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
2536-
ZVAL_NEW_STR(op, STR_INIT(str, len, 0));
2537-
efree(str);
2528+
str = zend_strpprintf(0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
2529+
ZVAL_NEW_STR(op, str);
25382530
}
25392531
/* }}} */
25402532

main/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,6 +2095,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
20952095
zuf.on_timeout = php_on_timeout;
20962096
zuf.stream_open_function = php_stream_open_for_zend;
20972097
zuf.vspprintf_function = vspprintf;
2098+
zuf.vstrpprintf_function = vstrpprintf;
20982099
zuf.getenv_function = sapi_getenv;
20992100
zuf.resolve_path_function = php_resolve_path_for_zend;
21002101
zend_startup(&zuf, NULL TSRMLS_CC);

main/spprintf.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap
799799

800800
xbuf_format_converter(&xbuf, format, ap);
801801

802-
if (max_len && xbuf.s->len > max_len) {
802+
if (max_len && xbuf.s && xbuf.s->len > max_len) {
803803
xbuf.s->len = max_len;
804804
}
805805
smart_str_0(&xbuf);
@@ -829,6 +829,33 @@ PHPAPI int spprintf(char **pbuf, size_t max_len, const char *format, ...) /* {{{
829829
}
830830
/* }}} */
831831

832+
PHPAPI zend_string *vstrpprintf(size_t max_len, const char *format, va_list ap) /* {{{ */
833+
{
834+
smart_str xbuf = {0};
835+
836+
xbuf_format_converter(&xbuf, format, ap);
837+
838+
if (max_len && xbuf.s && xbuf.s->len > max_len) {
839+
xbuf.s->len = max_len;
840+
}
841+
smart_str_0(&xbuf);
842+
843+
return xbuf.s;
844+
}
845+
/* }}} */
846+
847+
PHPAPI zend_string *strpprintf(size_t max_len, const char *format, ...) /* {{{ */
848+
{
849+
va_list ap;
850+
zend_string *str;
851+
852+
va_start(ap, format);
853+
str = vstrpprintf(max_len, format, ap);
854+
va_end(ap);
855+
return str;
856+
}
857+
/* }}} */
858+
832859
/*
833860
* Local variables:
834861
* tab-width: 4

main/spprintf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ BEGIN_EXTERN_C()
4040
PHPAPI int spprintf( char **pbuf, size_t max_len, const char *format, ...) PHP_ATTRIBUTE_FORMAT(printf, 3, 4);
4141

4242
PHPAPI int vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) PHP_ATTRIBUTE_FORMAT(printf, 3, 0);
43+
44+
PHPAPI zend_string *vstrpprintf(size_t max_len, const char *format, va_list ap);
45+
46+
PHPAPI zend_string *strpprintf(size_t max_len, const char *format, ...);
4347
END_EXTERN_C()
4448

4549
#endif /* SNPRINTF_H */

0 commit comments

Comments
 (0)