Hi Sara, Your first solution will not work. String passed to ZVAL_RETURN_RT_STRING() may be not allocated by emalloc().
The second solution will work. ZVAL_RETURN_RT_STRINGL(str, len, duplicate) -> ZVAL_RETURN_RT_STRINGL(str, len, duplicate, auto_free) 3) It is possible to reuse "duplicate" argument 0 - don't duplicate 1 - duplicate 2 - duplicate and free Thanks. Dmitry. > -----Original Message----- > From: Sara Golemon [mailto:[EMAIL PROTECTED] > Sent: Monday, April 03, 2006 4:07 AM > To: internals@lists.php.net > Subject: [PHP-DEV] RETURN_RT_STRING() and family leakage > > > I was going through failing tests today and noticed some which failed > because of memory leaks using code like the following: > > RETURN_RT_STRING(s, 0); > } > > For non-unicode mode this is functionally identical to: > > RETURN_STRING(s, 0); > } > > However for unicode mode, this binary value is translated to > unicode using > (effectively) this: > > { > UChar *u; > int u_len; > UErrorCode status = U_ZERO_ERROR; > > zend_convert_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), > &u, &u_len, s, strlen(s), &status); > RETURN_UNICODE(u, 0); > } > } > > The trouble with this, is that the original s value winds up > getting leaked. > I noticed a few other spots in the source where this is > handled as such: > > RETVAL_RT_STRING(s, 0); > if (UG(unicode)) { > efree(s); > } > return; > } > > Which is, of course, perfectly valid, but it feels a bit > cludgy to me as > it's a little inconsistent with the normal > RETURN_STRING()/RETURN_UNICODE() > semantics when it comes to "giving away" the variable. It's > also a problem > for the RETURN_RT_STRING(s, 0); usage in general as there's > no point after > the macro to free the original var. > > I see two solutions: > > (1) Modify the RETURN_RT_STRING(L)() macros to the following: > > #define RETURN_RT_STRING(t, duplicate) \ > { RETVAL_RT_STRING(t, duplicate); if (duplicate && > UG(unicode)) efree(t); > return; } > > (2) Modify ZVAL_U_STRINGL() to: > > #define ZVAL_U_STRINGL(conv, z, s, l, duplicate, auto_free) \ > if (UG(unicode)) { \ > UErrorCode status = U_ZERO_ERROR; \ > UChar *u_str; \ > int u_len; \ > zend_convert_to_unicode(conv, &u_str, &u_len, s, l, > &status); \ > if (auto_free && !duplicate) { \ > efree(s); \ > } \ > ZVAL_UNICODEL(z, u_str, u_len, 0); \ > } else { \ > char *__s=(s); int __l=l; \ > Z_STRLEN_P(z) = __l; \ > Z_STRVAL_P(z) = (duplicate?estrndup(__s, __l):__s); \ > Z_TYPE_P(z) = IS_STRING; \ > } > > Along with changes to the (ZVAL|RETVAL)_RT_STRING() macros: > to support the > additional auto_free option (with RETURN_* assuming auto_free=1). > > The first option solves the one real problem with the current > implementation > by making the uncatchable RETURN_RT_STRING() macros free the > original char* > as needed, whereas the latter takes that work away from the > calling scope at > the cost of adding to the proto and requiring more work to go > back and clean > up existing uses. > > Thoughts? > > -Sara > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php