From 2d625b5f81205d7f0217243b0bfe9a77683951e8 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 29 Apr 2014 13:40:44 +0200 Subject: [PATCH 1/2] Fixed bug #66431 Special Character via COM Interface (CP_UTF8) --- NEWS | 3 ++ ext/com_dotnet/com_olechar.c | 6 +++ ext/com_dotnet/com_variant.c | 6 ++- ext/com_dotnet/tests/bug66431_0.phpt | 42 +++++++++++++++++++ ext/com_dotnet/tests/bug66431_1.phpt | 60 ++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 ext/com_dotnet/tests/bug66431_0.phpt create mode 100644 ext/com_dotnet/tests/bug66431_1.phpt diff --git a/NEWS b/NEWS index 2212b03a319..387d070c028 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2014, PHP 5.4.29 +- COM: + . Fixed bug #66431 (Special Character via COM Interface (CP_UTF8)). (Anatol) + - Core: . Fixed bug #65701 (copy() doesn't work when destination filename is created by tempnam()). (Boro Sitnikovski) diff --git a/ext/com_dotnet/com_olechar.c b/ext/com_dotnet/com_olechar.c index a3e81978bd9..bf42b4fffb4 100644 --- a/ext/com_dotnet/com_olechar.c +++ b/ext/com_dotnet/com_olechar.c @@ -46,7 +46,13 @@ PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(char *string, uint strin if (string_len > 0) { olestring = (OLECHAR*)safe_emalloc(string_len, sizeof(OLECHAR), 0); + /* XXX if that's a real multibyte string, olestring is obviously allocated excessively. + This should be fixed by reallocating the olestring, but as emalloc is used, that doesn't + matter much. */ ok = MultiByteToWideChar(codepage, flags, string, string_len, olestring, string_len); + if (ok > 0 && ok < string_len) { + olestring[ok] = '\0'; + } } else { ok = FALSE; olestring = (OLECHAR*)emalloc(sizeof(OLECHAR)); diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c index af80f00528b..b808d0eb6ce 100644 --- a/ext/com_dotnet/com_variant.c +++ b/ext/com_dotnet/com_variant.c @@ -154,7 +154,11 @@ PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codep case IS_STRING: V_VT(v) = VT_BSTR; olestring = php_com_string_to_olestring(Z_STRVAL_P(z), Z_STRLEN_P(z), codepage TSRMLS_CC); - V_BSTR(v) = SysAllocStringByteLen((char*)olestring, Z_STRLEN_P(z) * sizeof(OLECHAR)); + if (CP_UTF8 == codepage) { + V_BSTR(v) = SysAllocStringByteLen((char*)olestring, wcslen(olestring) * sizeof(OLECHAR)); + } else { + V_BSTR(v) = SysAllocStringByteLen((char*)olestring, Z_STRLEN_P(z) * sizeof(OLECHAR)); + } efree(olestring); break; diff --git a/ext/com_dotnet/tests/bug66431_0.phpt b/ext/com_dotnet/tests/bug66431_0.phpt new file mode 100644 index 00000000000..daac328538e --- /dev/null +++ b/ext/com_dotnet/tests/bug66431_0.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug #66431 Special Character via COM Interface (CP_UTF8), Scripting.FileSystemObject +--SKIPIF-- + +--FILE-- +OpenTextFile($fpath, 2, true); +$fh->Write($text); +$fh->Close(); + +$check_text = file_get_contents($fpath); + +$result = ($check_text == $text); + +var_dump($result); + +if (!$result) { + echo "Expected: '$check_text'\n"; + echo "Have: '$text'\n"; +} + +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/com_dotnet/tests/bug66431_1.phpt b/ext/com_dotnet/tests/bug66431_1.phpt new file mode 100644 index 00000000000..d97011c2bb2 --- /dev/null +++ b/ext/com_dotnet/tests/bug66431_1.phpt @@ -0,0 +1,60 @@ +--TEST-- +Bug #66431 Special Character via COM Interface (CP_UTF8), Application.Word +--SKIPIF-- +getMessage(); +} + +?> +--FILE-- +Documents->Add(); +$Wrd->Selection->TypeText($text); +$Wrd->ActiveDocument->SaveAs($fpath); +$Wrd->ActiveDocument->Close(false); +$Wrd->Application->Quit(); +unset($Wrd); + +$Wrd = new COM("word.application", NULL, CP_UTF8); +$Wrd->Documents->Open($fpath, NULL, false); +$check_text = $Wrd->ActiveDocument->Range($Wrd->ActiveDocument->Sentences(1)->Start, $Wrd->ActiveDocument->Sentences(1)->End)->Text; +$Wrd->ActiveDocument->Close(false); +$Wrd->Application->Quit(); +unset($Wrd); + +/* trim the returned text as we'll get windows eol from a word doc. */ +$result = (trim($check_text) == $text); + +var_dump($result); + +if (!$result) { + echo "Expected: '$check_text'\n"; + echo "Have: '$text'\n"; +} + +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +===DONE=== From b22f33afe225b5c5530927acc32ba7588adbf960 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 29 Apr 2014 13:44:54 +0200 Subject: [PATCH 2/2] updated NEWS --- NEWS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS b/NEWS index 77f9bde32c3..6def0cf17a9 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,9 @@ PHP NEWS - CLI server: . Fixed bug #67079 (Missing MIME types for XML/XSL files). (Anatol) +- COM: + . Fixed bug #66431 (Special Character via COM Interface (CP_UTF8)). (Anatol) + - Core: . Fixed bug #65701 (copy() doesn't work when destination filename is created by tempnam()). (Boro Sitnikovski)