. Fixed bug #79030 (Upgrade apache2handler's php_apache_sapi_get_request_time
to return usec). (Herbert256)
+- COM:
+ . Fixed bug #63208 (BSTR to PHP string conversion not binary safe). (cmb)
+
- Curl:
. Fixed bug #79741 (curl_setopt CURLOPT_POSTFIELDS asserts on object with
declared properties). (Nikita)
return string;
}
+
+BSTR php_com_string_to_bstr(zend_string *string, int codepage)
+{
+ BSTR bstr = NULL;
+ DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
+ size_t mb_len = ZSTR_LEN(string);
+ int wc_len;
+
+ if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, NULL, 0)) <= 0) {
+ goto fail;
+ }
+ if ((bstr = SysAllocStringLen(NULL, (UINT)(wc_len - 1))) == NULL) {
+ goto fail;
+ }
+ if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, bstr, wc_len)) <= 0) {
+ goto fail;
+ }
+ return bstr;
+
+fail:
+ char *msg = php_win32_error_to_msg(GetLastError());
+ php_error_docref(NULL, E_WARNING,
+ "Could not convert string to unicode: `%s'", msg);
+ LocalFree(msg);
+ SysFreeString(bstr);
+ return SysAllocString(L"");
+}
+
+zend_string *php_com_bstr_to_string(BSTR bstr, int codepage)
+{
+ zend_string *string = NULL;
+ UINT wc_len = SysStringLen(bstr);
+ int mb_len;
+
+ mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, NULL, 0, NULL, NULL);
+ if (mb_len > 0) {
+ string = zend_string_alloc(mb_len - 1, 0);
+ mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, ZSTR_VAL(string), mb_len, NULL, NULL);
+ }
+
+ if (mb_len <= 0) {
+ char *msg = php_win32_error_to_msg(GetLastError());
+
+ php_error_docref(NULL, E_WARNING,
+ "Could not convert string from unicode: `%s'", msg);
+ LocalFree(msg);
+
+ if (string != NULL) {
+ zend_string_release(string);
+ }
+ string = ZSTR_EMPTY_ALLOC();
+ }
+
+ return string;
+}
PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codepage)
{
- OLECHAR *olestring;
php_com_dotnet_object *obj;
zend_uchar ztype = IS_NULL;
case IS_STRING:
V_VT(v) = VT_BSTR;
- olestring = php_com_string_to_olestring(Z_STRVAL_P(z), Z_STRLEN_P(z), codepage);
- if (CP_UTF8 == codepage) {
- V_BSTR(v) = SysAllocStringByteLen((char*)olestring, (UINT)(wcslen(olestring) * sizeof(OLECHAR)));
- } else {
- V_BSTR(v) = SysAllocStringByteLen((char*)olestring, (UINT)(Z_STRLEN_P(z) * sizeof(OLECHAR)));
- }
- efree(olestring);
+ V_BSTR(v) = php_com_string_to_bstr(Z_STR_P(z), codepage);
break;
case IS_RESOURCE:
case VT_BSTR:
olestring = V_BSTR(v);
if (olestring) {
- size_t len;
- char *str = php_com_olestring_to_string(olestring,
- &len, codepage);
- ZVAL_STRINGL(z, str, len);
- // TODO: avoid reallocation???
- efree(str);
+ zend_string *str = php_com_bstr_to_string(olestring, codepage);
+ ZVAL_STR(z, str);
olestring = NULL;
}
break;
size_t *string_len, int codepage);
PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(char *string,
size_t string_len, int codepage);
+BSTR php_com_string_to_bstr(zend_string *string, int codepage);
+zend_string *php_com_bstr_to_string(BSTR bstr, int codepage);
/* com_com.c */
--- /dev/null
+--TEST--
+Bug #63208 (BSTR to PHP string conversion not binary safe)
+--SKIPIF--
+<?php
+if (!extension_loaded('com_dotnet')) die('skip com_dotnet extension not available');
+?>
+--FILE--
+<?php
+$string = "\u{0905}b\0cd";
+$variant = new VARIANT($string, VT_ARRAY | VT_UI1, CP_UTF8); // Array of bytes
+$converted = (string) $variant;
+var_dump(bin2hex($string));
+var_dump(bin2hex($converted));
+?>
+--EXPECT--
+string(14) "e0a48562006364"
+string(14) "e0a48562006364"