summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2014-04-29 13:40:44 +0200
committerAnatol Belski <ab@php.net>2014-04-29 13:40:44 +0200
commit2d625b5f81205d7f0217243b0bfe9a77683951e8 (patch)
tree54f142ba56098a1ae70bca121fe5c7120f21a9ec
parentbb422cb60e69794b3ea9d7d47fcc8a976a385608 (diff)
downloadphp-git-2d625b5f81205d7f0217243b0bfe9a77683951e8.tar.gz
Fixed bug #66431 Special Character via COM Interface (CP_UTF8)
-rw-r--r--NEWS3
-rw-r--r--ext/com_dotnet/com_olechar.c6
-rw-r--r--ext/com_dotnet/com_variant.c6
-rw-r--r--ext/com_dotnet/tests/bug66431_0.phpt42
-rw-r--r--ext/com_dotnet/tests/bug66431_1.phpt60
5 files changed, 116 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 2212b03a31..387d070c02 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 a3e81978bd..bf42b4fffb 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 af80f00528..b808d0eb6c 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 0000000000..daac328538
--- /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--
+<?php
+if (!extension_loaded("com_dotnet")){ echo "skip COM/.Net support not present"; }
+?>
+--FILE--
+<?php
+
+$text= "Xin chào cộng đồng PHP";
+$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.txt");
+
+$fso = new COM("Scripting.FileSystemObject");
+$fh = $fso->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--
+<?php
+
+$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.txt");
+
+if (file_exists($fpath)) {
+ unlink($fpath);
+}
+?>
+--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 0000000000..d97011c2bb
--- /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--
+<?php
+if (!extension_loaded("com_dotnet")){ echo "skip COM/.Net support not present"; }
+
+try {
+ new COM("word.application", NULL, CP_UTF8);
+} catch (Exception $e) {
+ die('skip ' . $e->getMessage();
+}
+
+?>
+--FILE--
+<?php
+
+$text= "Xin chào cộng đồng PHP";
+$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.docx");
+
+com_load_typelib('Word.Application');
+
+$Wrd = new COM("word.application", NULL, CP_UTF8);
+$Wrd->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--
+<?php
+
+$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.docx");
+
+if (file_exists($fpath)) {
+ unlink($fpath);
+}
+?>
+--EXPECT--
+bool(true)
+===DONE===