Skip to content

Commit 2d625b5

Browse files
committed
Fixed bug #66431 Special Character via COM Interface (CP_UTF8)
1 parent bb422cb commit 2d625b5

File tree

5 files changed

+116
-1
lines changed

5 files changed

+116
-1
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2014, PHP 5.4.29
44

5+
- COM:
6+
. Fixed bug #66431 (Special Character via COM Interface (CP_UTF8)). (Anatol)
7+
58
- Core:
69
. Fixed bug #65701 (copy() doesn't work when destination filename is created
710
by tempnam()). (Boro Sitnikovski)

ext/com_dotnet/com_olechar.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,13 @@ PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(char *string, uint strin
4646

4747
if (string_len > 0) {
4848
olestring = (OLECHAR*)safe_emalloc(string_len, sizeof(OLECHAR), 0);
49+
/* XXX if that's a real multibyte string, olestring is obviously allocated excessively.
50+
This should be fixed by reallocating the olestring, but as emalloc is used, that doesn't
51+
matter much. */
4952
ok = MultiByteToWideChar(codepage, flags, string, string_len, olestring, string_len);
53+
if (ok > 0 && ok < string_len) {
54+
olestring[ok] = '\0';
55+
}
5056
} else {
5157
ok = FALSE;
5258
olestring = (OLECHAR*)emalloc(sizeof(OLECHAR));

ext/com_dotnet/com_variant.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,11 @@ PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codep
154154
case IS_STRING:
155155
V_VT(v) = VT_BSTR;
156156
olestring = php_com_string_to_olestring(Z_STRVAL_P(z), Z_STRLEN_P(z), codepage TSRMLS_CC);
157-
V_BSTR(v) = SysAllocStringByteLen((char*)olestring, Z_STRLEN_P(z) * sizeof(OLECHAR));
157+
if (CP_UTF8 == codepage) {
158+
V_BSTR(v) = SysAllocStringByteLen((char*)olestring, wcslen(olestring) * sizeof(OLECHAR));
159+
} else {
160+
V_BSTR(v) = SysAllocStringByteLen((char*)olestring, Z_STRLEN_P(z) * sizeof(OLECHAR));
161+
}
158162
efree(olestring);
159163
break;
160164

ext/com_dotnet/tests/bug66431_0.phpt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
Bug #66431 Special Character via COM Interface (CP_UTF8), Scripting.FileSystemObject
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded("com_dotnet")){ echo "skip COM/.Net support not present"; }
6+
?>
7+
--FILE--
8+
<?php
9+
10+
$text= "Xin chào cộng đồng PHP";
11+
$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.txt");
12+
13+
$fso = new COM("Scripting.FileSystemObject");
14+
$fh = $fso->OpenTextFile($fpath, 2, true);
15+
$fh->Write($text);
16+
$fh->Close();
17+
18+
$check_text = file_get_contents($fpath);
19+
20+
$result = ($check_text == $text);
21+
22+
var_dump($result);
23+
24+
if (!$result) {
25+
echo "Expected: '$check_text'\n";
26+
echo "Have: '$text'\n";
27+
}
28+
29+
?>
30+
===DONE===
31+
--CLEAN--
32+
<?php
33+
34+
$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.txt");
35+
36+
if (file_exists($fpath)) {
37+
unlink($fpath);
38+
}
39+
?>
40+
--EXPECT--
41+
bool(true)
42+
===DONE===

ext/com_dotnet/tests/bug66431_1.phpt

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
Bug #66431 Special Character via COM Interface (CP_UTF8), Application.Word
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded("com_dotnet")){ echo "skip COM/.Net support not present"; }
6+
7+
try {
8+
new COM("word.application", NULL, CP_UTF8);
9+
} catch (Exception $e) {
10+
die('skip ' . $e->getMessage();
11+
}
12+
13+
?>
14+
--FILE--
15+
<?php
16+
17+
$text= "Xin chào cộng đồng PHP";
18+
$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.docx");
19+
20+
com_load_typelib('Word.Application');
21+
22+
$Wrd = new COM("word.application", NULL, CP_UTF8);
23+
$Wrd->Documents->Add();
24+
$Wrd->Selection->TypeText($text);
25+
$Wrd->ActiveDocument->SaveAs($fpath);
26+
$Wrd->ActiveDocument->Close(false);
27+
$Wrd->Application->Quit();
28+
unset($Wrd);
29+
30+
$Wrd = new COM("word.application", NULL, CP_UTF8);
31+
$Wrd->Documents->Open($fpath, NULL, false);
32+
$check_text = $Wrd->ActiveDocument->Range($Wrd->ActiveDocument->Sentences(1)->Start, $Wrd->ActiveDocument->Sentences(1)->End)->Text;
33+
$Wrd->ActiveDocument->Close(false);
34+
$Wrd->Application->Quit();
35+
unset($Wrd);
36+
37+
/* trim the returned text as we'll get windows eol from a word doc. */
38+
$result = (trim($check_text) == $text);
39+
40+
var_dump($result);
41+
42+
if (!$result) {
43+
echo "Expected: '$check_text'\n";
44+
echo "Have: '$text'\n";
45+
}
46+
47+
?>
48+
===DONE===
49+
--CLEAN--
50+
<?php
51+
52+
$fpath = str_replace("/", "\\", dirname(__FILE__) . "/bug66431.docx");
53+
54+
if (file_exists($fpath)) {
55+
unlink($fpath);
56+
}
57+
?>
58+
--EXPECT--
59+
bool(true)
60+
===DONE===

0 commit comments

Comments
 (0)