pollita Thu Apr 6 19:39:11 2006 UTC Modified files: /php-src/main/streams streams.c Log: Do runtime conversions (with an E_NOTICE) on writing unicode data to a binary stream. Take the WTF out of the equation http://cvs.php.net/viewcvs.cgi/php-src/main/streams/streams.c?r1=1.118&r2=1.119&diff_format=u Index: php-src/main/streams/streams.c diff -u php-src/main/streams/streams.c:1.118 php-src/main/streams/streams.c:1.119 --- php-src/main/streams/streams.c:1.118 Fri Mar 31 22:51:37 2006 +++ php-src/main/streams/streams.c Thu Apr 6 19:39:11 2006 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.118 2006/03/31 22:51:37 pollita Exp $ */ +/* $Id: streams.c,v 1.119 2006/04/06 19:39:11 pollita Exp $ */ #define _GNU_SOURCE #include "php.h" @@ -1201,6 +1201,8 @@ { size_t didwrite = 0, towrite, justwrote, shouldwrite; char *freeme = NULL; + void *buf_orig = buf.v; + int buflen_orig = buflen, conv_err = 0; /* if we have a seekable stream we need to ensure that data is written at the * current stream->position. This means invalidating the read buffer and then @@ -1211,9 +1213,26 @@ stream->ops->seek(stream, stream->position, SEEK_SET, &stream->position TSRMLS_CC); } - /* Sloppy handling, make it a binary buffer */ if (buf_type == IS_UNICODE) { - buflen = UBYTES(buflen); + int len, num_conv, ulen = u_countChar32(buf.u, buflen); + char *str; + UErrorCode status = U_ZERO_ERROR; + + /* Use runtime_encoding to map to binary */ + num_conv = zend_convert_from_unicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &str, &len, buf.u, buflen, &status); + if (U_FAILURE(status)) { + zend_raise_conversion_error_ex("Unable to convert data to be writen", ZEND_U_CONVERTER(UG(runtime_encoding_conv)), + ZEND_FROM_UNICODE, num_conv, (UG(from_error_mode) & ZEND_CONV_ERROR_EXCEPTION) TSRMLS_CC); + } else { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%d character unicode buffer downcoded for binary stream runtime_encoding", ulen); + } + + if (num_conv < buflen) { + conv_err = 1; + } + + freeme = buf.s = str; + buflen = len; } shouldwrite = buflen; @@ -1243,8 +1262,23 @@ } if (buf_type == IS_UNICODE) { - /* Was slopily converted */ - didwrite /= UBYTES(1); + /* Map bytes written back to UChars written */ + + if (shouldwrite == didwrite && !conv_err) { + /* wrote it all */ + didwrite = buflen_orig; + } else { + /* Figure out how didwrite corresponds to the input buffer */ + char *tmp = emalloc(didwrite + 1), *t = tmp; + UChar *s = buf_orig; + UErrorCode status = U_ZERO_ERROR; + + ucnv_resetFromUnicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv))); + ucnv_fromUnicode(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &t, t + didwrite, &s, s + buflen_orig, NULL, TRUE, &status); + + didwrite = s - ((UChar*)buf_orig); + efree(tmp); + } } if (freeme) {
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php