Skip to content

Commit a5dd310

Browse files
committed
Rasamassen PR's 2819 and part of 2821
I made RTF usable some time ago. @rasamassen has recently done a lot of useful work to cover many missing areas. Since who knows when those changes will be merged, I intend to incorporate much of that work. I will do this with several pushes, each based on one or more of those changes. This one is based on PR PHPOffice#2819 (fixes issue PHPOffice#321), and the Escaper portion of PR PHPOffice#2821.
1 parent b577547 commit a5dd310

File tree

20 files changed

+634
-298
lines changed

20 files changed

+634
-298
lines changed

phpstan-baseline.neon

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -915,41 +915,6 @@ parameters:
915915
count: 1
916916
path: src/PhpWord/Writer/PDF/DomPDF.php
917917

918-
-
919-
message: "#^Binary operation \"\\+\" between int\\|string and 1 results in an error\\.$#"
920-
count: 1
921-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
922-
923-
-
924-
message: "#^Parameter \\#1 \\$value of method PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Style\\\\Font\\:\\:setNameIndex\\(\\) expects int, int\\|string given\\.$#"
925-
count: 1
926-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
927-
928-
-
929-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$fontStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Font\\) does not accept PhpOffice\\\\PhpWord\\\\Style\\\\AbstractStyle\\|null\\.$#"
930-
count: 1
931-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
932-
933-
-
934-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$fontStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Font\\) does not accept PhpOffice\\\\PhpWord\\\\Style\\\\Font\\|string\\.$#"
935-
count: 1
936-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
937-
938-
-
939-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$paragraphStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Paragraph\\) does not accept PhpOffice\\\\PhpWord\\\\Style\\\\AbstractStyle\\|null\\.$#"
940-
count: 1
941-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
942-
943-
-
944-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$paragraphStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Paragraph\\) does not accept PhpOffice\\\\PhpWord\\\\Style\\\\Paragraph\\|string\\.$#"
945-
count: 1
946-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
947-
948-
-
949-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$paragraphStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Paragraph\\) does not accept null\\.$#"
950-
count: 2
951-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
952-
953918
-
954919
message: "#^Method PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\Field\\:\\:write\\(\\) should return string but empty return statement found\\.$#"
955920
count: 1
@@ -1365,26 +1330,6 @@ parameters:
13651330
count: 1
13661331
path: tests/PhpWordTests/Writer/ODText/Style/FontTest.php
13671332

1368-
-
1369-
message: "#^Method PhpOffice\\\\PhpWordTests\\\\Writer\\\\RTF\\\\ElementTest\\:\\:removeCr\\(\\) has no return type specified\\.$#"
1370-
count: 1
1371-
path: tests/PhpWordTests/Writer/RTF/ElementTest.php
1372-
1373-
-
1374-
message: "#^Method PhpOffice\\\\PhpWordTests\\\\Writer\\\\RTF\\\\ElementTest\\:\\:removeCr\\(\\) has parameter \\$field with no type specified\\.$#"
1375-
count: 1
1376-
path: tests/PhpWordTests/Writer/RTF/ElementTest.php
1377-
1378-
-
1379-
message: "#^Method PhpOffice\\\\PhpWordTests\\\\Writer\\\\RTF\\\\StyleTest\\:\\:removeCr\\(\\) has no return type specified\\.$#"
1380-
count: 1
1381-
path: tests/PhpWordTests/Writer/RTF/StyleTest.php
1382-
1383-
-
1384-
message: "#^Method PhpOffice\\\\PhpWordTests\\\\Writer\\\\RTF\\\\StyleTest\\:\\:removeCr\\(\\) has parameter \\$field with no type specified\\.$#"
1385-
count: 1
1386-
path: tests/PhpWordTests/Writer/RTF/StyleTest.php
1387-
13881333
-
13891334
message: "#^Property PhpOffice\\\\PhpWordTests\\\\Writer\\\\Word2007\\\\Element\\\\ChartTest\\:\\:\\$outputEscapingEnabled has no type specified\\.$#"
13901335
count: 1

phpstan-baseline.php73.neon

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -905,41 +905,6 @@ parameters:
905905
count: 1
906906
path: src/PhpWord/Writer/PDF/DomPDF.php
907907

908-
-
909-
message: "#^Binary operation \"\\+\" between int\\|string and 1 results in an error\\.$#"
910-
count: 1
911-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
912-
913-
-
914-
message: "#^Parameter \\#1 \\$value of method PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Style\\\\Font\\:\\:setNameIndex\\(\\) expects int, int\\|string given\\.$#"
915-
count: 1
916-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
917-
918-
-
919-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$fontStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Font\\) does not accept PhpOffice\\\\PhpWord\\\\Style\\\\AbstractStyle\\|null\\.$#"
920-
count: 1
921-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
922-
923-
-
924-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$fontStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Font\\) does not accept PhpOffice\\\\PhpWord\\\\Style\\\\Font\\|string\\.$#"
925-
count: 1
926-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
927-
928-
-
929-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$paragraphStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Paragraph\\) does not accept PhpOffice\\\\PhpWord\\\\Style\\\\AbstractStyle\\|null\\.$#"
930-
count: 1
931-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
932-
933-
-
934-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$paragraphStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Paragraph\\) does not accept PhpOffice\\\\PhpWord\\\\Style\\\\Paragraph\\|string\\.$#"
935-
count: 1
936-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
937-
938-
-
939-
message: "#^Property PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\AbstractElement\\:\\:\\$paragraphStyle \\(PhpOffice\\\\PhpWord\\\\Style\\\\Paragraph\\) does not accept null\\.$#"
940-
count: 2
941-
path: src/PhpWord/Writer/RTF/Element/AbstractElement.php
942-
943908
-
944909
message: "#^Method PhpOffice\\\\PhpWord\\\\Writer\\\\RTF\\\\Element\\\\Field\\:\\:write\\(\\) should return string but empty return statement found\\.$#"
945910
count: 1
@@ -1350,26 +1315,6 @@ parameters:
13501315
count: 1
13511316
path: tests/PhpWordTests/Writer/ODText/Style/FontTest.php
13521317

1353-
-
1354-
message: "#^Method PhpOffice\\\\PhpWordTests\\\\Writer\\\\RTF\\\\ElementTest\\:\\:removeCr\\(\\) has no return type specified\\.$#"
1355-
count: 1
1356-
path: tests/PhpWordTests/Writer/RTF/ElementTest.php
1357-
1358-
-
1359-
message: "#^Method PhpOffice\\\\PhpWordTests\\\\Writer\\\\RTF\\\\ElementTest\\:\\:removeCr\\(\\) has parameter \\$field with no type specified\\.$#"
1360-
count: 1
1361-
path: tests/PhpWordTests/Writer/RTF/ElementTest.php
1362-
1363-
-
1364-
message: "#^Method PhpOffice\\\\PhpWordTests\\\\Writer\\\\RTF\\\\StyleTest\\:\\:removeCr\\(\\) has no return type specified\\.$#"
1365-
count: 1
1366-
path: tests/PhpWordTests/Writer/RTF/StyleTest.php
1367-
1368-
-
1369-
message: "#^Method PhpOffice\\\\PhpWordTests\\\\Writer\\\\RTF\\\\StyleTest\\:\\:removeCr\\(\\) has parameter \\$field with no type specified\\.$#"
1370-
count: 1
1371-
path: tests/PhpWordTests/Writer/RTF/StyleTest.php
1372-
13731318
-
13741319
message: "#^Property PhpOffice\\\\PhpWordTests\\\\Writer\\\\Word2007\\\\Element\\\\ChartTest\\:\\:\\$outputEscapingEnabled has no type specified\\.$#"
13751320
count: 1

src/PhpWord/Escaper/Rtf.php

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -43,55 +43,27 @@ protected function escapeAsciiCharacter($code)
4343

4444
protected function escapeMultibyteCharacter($code)
4545
{
46-
return '\\uc0{\\u' . $code . '}';
46+
if ($code > 32767) {
47+
return '\\uc0\\u' . ((int) $code - 65536) . ' ';
48+
}
49+
50+
return '\\uc0\\u' . $code . ' ';
4751
}
4852

4953
/**
50-
* @see http://www.randomchaos.com/documents/?source=php_and_unicode
51-
*
5254
* @param ?string $input
5355
*/
5456
protected function escapeSingleValue($input)
5557
{
5658
$escapedValue = '';
57-
58-
$numberOfBytes = 1;
59-
$bytes = [];
60-
for ($i = 0; $i < strlen($input); ++$i) {
61-
$character = $input[$i];
62-
$asciiCode = ord($character);
63-
64-
if ($asciiCode < 128) {
65-
$escapedValue .= $this->escapeAsciiCharacter($asciiCode);
59+
$utf16 = mb_convert_encoding($input, 'UTF-16BE', 'UTF-8');
60+
$utf16len = strlen($utf16);
61+
for ($i = 0; $i < $utf16len; $i += 2) {
62+
$code = (ord($utf16[$i]) << 8) | ord($utf16[$i + 1]);
63+
if ($code <= 0x7f) {
64+
$escapedValue .= $this->escapeAsciiCharacter($code);
6665
} else {
67-
if (0 == count($bytes)) {
68-
if ($asciiCode < 224) {
69-
$numberOfBytes = 2;
70-
} elseif ($asciiCode < 240) {
71-
$numberOfBytes = 3;
72-
} elseif ($asciiCode < 248) {
73-
$numberOfBytes = 4;
74-
}
75-
}
76-
77-
$bytes[] = $asciiCode;
78-
79-
if ($numberOfBytes == count($bytes)) {
80-
if (4 == $numberOfBytes) {
81-
$multibyteCode = ($bytes[0] % 8) * 262144 + ($bytes[1] % 64) * 4096 + ($bytes[2] % 64) * 64 + ($bytes[3] % 64);
82-
} elseif (3 == $numberOfBytes) {
83-
$multibyteCode = ($bytes[0] % 16) * 4096 + ($bytes[1] % 64) * 64 + ($bytes[2] % 64);
84-
} else {
85-
$multibyteCode = ($bytes[0] % 32) * 64 + ($bytes[1] % 64);
86-
}
87-
88-
if (65279 != $multibyteCode) {
89-
$escapedValue .= $multibyteCode < 128 ? $this->escapeAsciiCharacter($multibyteCode) : $this->escapeMultibyteCharacter($multibyteCode);
90-
}
91-
92-
$numberOfBytes = 1;
93-
$bytes = [];
94-
}
66+
$escapedValue .= $this->escapeMultibyteCharacter($code);
9567
}
9668
}
9769

0 commit comments

Comments
 (0)