]> granicus.if.org Git - php/commitdiff
Fixed bug #66431 Special Character via COM Interface (CP_UTF8)
authorAnatol Belski <ab@php.net>
Tue, 29 Apr 2014 11:40:44 +0000 (13:40 +0200)
committerAnatol Belski <ab@php.net>
Tue, 29 Apr 2014 11:40:44 +0000 (13:40 +0200)
NEWS
ext/com_dotnet/com_olechar.c
ext/com_dotnet/com_variant.c
ext/com_dotnet/tests/bug66431_0.phpt [new file with mode: 0644]
ext/com_dotnet/tests/bug66431_1.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 2212b03a319409dd1d637968a72f0091e898a649..387d070c028eee049787a86a9481ff7b00748024 100644 (file)
--- 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)
index a3e81978bd96dd8655df851189819b49db30282e..bf42b4fffb4cc7c822f3850df8207c04883a6bef 100644 (file)
@@ -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));
index af80f00528b32a0ce97ea65f55228ac9edb2e4b4..b808d0eb6ce692fff5edf5b187e4e0a5736c10ad 100644 (file)
@@ -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 (file)
index 0000000..daac328
--- /dev/null
@@ -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 (file)
index 0000000..d97011c
--- /dev/null
@@ -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===