Skip to content

Commit 4c7e139

Browse files
author
Roman Syroeshko
committed
#483. Output escaping for HTML.
1 parent 508d619 commit 4c7e139

File tree

12 files changed

+114
-35
lines changed

12 files changed

+114
-35
lines changed

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Read more about PHPWord:
2424

2525
## Features
2626

27-
With PHPWord, you can create DOCX, ODT, or RTF documents dynamically using your PHP 5.3+ scripts. Below are some of the things that you can do with PHPWord library:
27+
With PHPWord, you can create OOXML, ODF, or RTF documents dynamically using your PHP 5.3.3+ scripts. Below are some of the things that you can do with PHPWord library:
2828

2929
- Set document properties, e.g. title, subject, and creator.
3030
- Create document sections with different settings, e.g. portrait/landscape, page size, and page numbering
@@ -52,12 +52,14 @@ With PHPWord, you can create DOCX, ODT, or RTF documents dynamically using your
5252

5353
PHPWord requires the following:
5454

55-
- PHP 5.3+
55+
- PHP 5.3.3+
5656
- [XML Parser extension](http://www.php.net/manual/en/xml.installation.php)
57+
- [Zend\Escaper component](http://framework.zend.com/manual/current/en/modules/zend.escaper.introduction.html)
58+
- Zend\Stdlib component
5759
- [Zend\Validator component](http://framework.zend.com/manual/current/en/modules/zend.validator.html)
58-
- [Zip extension](http://php.net/manual/en/book.zip.php) (optional, used to write DOCX and ODT)
60+
- [Zip extension](http://php.net/manual/en/book.zip.php) (optional, used to write OOXML and ODF)
5961
- [GD extension](http://php.net/manual/en/book.image.php) (optional, used to add images)
60-
- [XMLWriter extension](http://php.net/manual/en/book.xmlwriter.php) (optional, used to write DOCX and ODT)
62+
- [XMLWriter extension](http://php.net/manual/en/book.xmlwriter.php) (optional, used to write OOXML and ODF)
6163
- [XSL extension](http://php.net/manual/en/book.xsl.php) (optional, used to apply XSL style sheet to template )
6264
- [dompdf library](https://github.com/dompdf/dompdf) (optional, used to write PDF)
6365

@@ -149,7 +151,6 @@ $objWriter->save('helloWorld.html');
149151
/* Note: we skip RTF, because it's not XML-based and requires a different example. */
150152
/* Note: we skip PDF, because "HTML-to-PDF" approach is used to create PDF documents. */
151153
```
152-
:warning: Escape any string you pass to HTML document, otherwise it may get broken.
153154

154155
More examples are provided in the [samples folder](samples/). You can also read the [Developers' Documentation](http://phpword.readthedocs.org/) and the [API Documentation](http://phpoffice.github.io/PHPWord/docs/master/) for more detail.
155156

composer.json

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"name": "phpoffice/phpword",
3-
"description": "PHPWord - A pure PHP library for reading and writing word processing documents (DOCX, ODT, RTF, HTML, PDF)",
3+
"description": "PHPWord - A pure PHP library for reading and writing word processing documents (OOXML, ODF, RTF, HTML, PDF)",
44
"keywords": [
5-
"PHP", "PhpOffice", "office", "PhpWord", "word", "template", "template processor", "reader", "writer",
5+
"PHP", "PHPOffice", "office", "PHPWord", "word", "template", "template processor", "reader", "writer",
66
"docx", "OOXML", "OpenXML", "Office Open XML", "ISO IEC 29500", "WordprocessingML",
7-
"RTF", "Rich Text Format", "doc", "odt", "OpenDocument", "PDF", "HTML"
7+
"RTF", "Rich Text Format", "doc", "odt", "ODF", "OpenDocument", "PDF", "HTML"
88
],
99
"homepage": "http://phpoffice.github.io",
1010
"type": "library",
@@ -34,8 +34,9 @@
3434
"require": {
3535
"php": ">=5.3.3",
3636
"ext-xml": "*",
37-
"zendframework/zend-stdlib": "~2.5",
38-
"zendframework/zend-validator": "2.5.*",
37+
"zendframework/zend-escaper": "2.4.*",
38+
"zendframework/zend-stdlib": "2.4.*",
39+
"zendframework/zend-validator": "2.4.*",
3940
"phpoffice/common": "0.2.*"
4041
},
4142
"require-dev": {
@@ -46,15 +47,12 @@
4647
"phploc/phploc": "2.*",
4748
"dompdf/dompdf":"0.6.*",
4849
"tecnickcom/tcpdf": "6.*",
49-
"mpdf/mpdf": "5.*",
50-
"zendframework/zend-stdlib": "~2.5",
51-
"zendframework/zend-validator": "2.5.*",
52-
"phpoffice/common": "0.2.*"
50+
"mpdf/mpdf": "5.*"
5351
},
5452
"suggest": {
55-
"ext-zip": "Allows writing DOCX and ODT",
53+
"ext-zip": "Allows writing OOXML and ODF",
5654
"ext-gd2": "Allows adding images",
57-
"ext-xmlwriter": "Allows writing DOCX and ODT",
55+
"ext-xmlwriter": "Allows writing OOXML and ODF",
5856
"ext-xsl": "Allows applying XSL style sheet to main document part of OOXML template",
5957
"dompdf/dompdf": "Allows writing PDF"
6058
},

docs/installing.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ Requirements
88

99
Mandatory:
1010

11-
- PHP 5.3+
11+
- PHP 5.3.3+
1212
- `XML Parser <http://www.php.net/manual/en/xml.installation.php>`__ extension
13+
- `Zend\\Escaper <http://framework.zend.com/manual/current/en/modules/zend.escaper.introduction.html>`__ component
14+
- Zend\\Stdlib component
1315
- `Zend\\Validator <http://framework.zend.com/manual/current/en/modules/zend.validator.html>`__ component
1416

1517
Optional:

docs/intro.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Writers
6363
~~~~~~~
6464

6565
+---------------------------+----------------------+--------+-------+-------+--------+-------+
66-
| Features | | DOCX | ODT | RTF | HTML | PDF |
66+
| Features | | OOXML | ODF | RTF | HTML | PDF |
6767
+===========================+======================+========+=======+=======+========+=======+
6868
| **Document Properties** | Standard ||||||
6969
+---------------------------+----------------------+--------+-------+-------+--------+-------+
@@ -122,7 +122,7 @@ Readers
122122
~~~~~~~
123123

124124
+---------------------------+----------------------+--------+-------+-------+-------+-------+
125-
| Features | | DOCX | DOC | ODT | RTF | HTML |
125+
| Features | | OOXML | DOC | ODF | RTF | HTML |
126126
+===========================+======================+========+=======+=======+=======+=======+
127127
| **Document Properties** | Standard || | | | |
128128
+---------------------------+----------------------+--------+-------+-------+-------+-------+

src/PhpWord/Writer/HTML/Element/AbstractElement.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
use PhpOffice\PhpWord\Element\AbstractElement as Element;
2121
use PhpOffice\PhpWord\Writer\AbstractWriter;
22+
use Zend\Escaper\Escaper;
2223

2324
/**
2425
* Abstract HTML element writer
@@ -48,6 +49,11 @@ abstract class AbstractElement
4849
*/
4950
protected $withoutP = false;
5051

52+
/**
53+
* @var \Zend\Escaper\Escaper
54+
*/
55+
protected $escaper;
56+
5157
/**
5258
* Write element
5359
*/
@@ -65,6 +71,7 @@ public function __construct(AbstractWriter $parentWriter, Element $element, $wit
6571
$this->parentWriter = $parentWriter;
6672
$this->element = $element;
6773
$this->withoutP = $withoutP;
74+
$this->escaper = new Escaper();
6875
}
6976

7077
/**

src/PhpWord/Writer/HTML/Element/Link.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
namespace PhpOffice\PhpWord\Writer\HTML\Element;
19+
use PhpOffice\PhpWord\Settings;
1920

2021
/**
2122
* Link element HTML writer
@@ -37,7 +38,11 @@ public function write()
3738

3839
$content = '';
3940
$content .= $this->writeOpening();
40-
$content .= "<a href=\"{$this->element->getSource()}\">{$this->element->getText()}</a>";
41+
if (Settings::isOutputEscapingEnabled()) {
42+
$content .= "<a href=\"{$this->escaper->escapeHtmlAttr($this->element->getSource())}\">{$this->escaper->escapeHtml($this->element->getText())}</a>";
43+
} else {
44+
$content .= "<a href=\"{$this->element->getSource()}\">{$this->element->getText()}</a>";
45+
}
4146
$content .= $this->writeClosing();
4247

4348
return $content;

src/PhpWord/Writer/HTML/Element/ListItem.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
namespace PhpOffice\PhpWord\Writer\HTML\Element;
19+
use PhpOffice\PhpWord\Settings;
1920

2021
/**
2122
* ListItem element HTML writer
@@ -35,8 +36,11 @@ public function write()
3536
return '';
3637
}
3738

38-
$text = $this->element->getTextObject()->getText();
39-
$content = '<p>' . $text . '</p>' . PHP_EOL;
39+
if (Settings::isOutputEscapingEnabled()) {
40+
$content = '<p>' . $this->escaper->escapeHtml($this->element->getTextObject()->getText()) . '</p>' . PHP_EOL;
41+
} else {
42+
$content = '<p>' . $this->element->getTextObject()->getText() . '</p>' . PHP_EOL;
43+
}
4044

4145
return $content;
4246
}

src/PhpWord/Writer/HTML/Element/Text.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace PhpOffice\PhpWord\Writer\HTML\Element;
1919

20+
use PhpOffice\PhpWord\Settings;
2021
use PhpOffice\PhpWord\Style\Font;
2122
use PhpOffice\PhpWord\Style\Paragraph;
2223
use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter;
@@ -72,7 +73,11 @@ public function write()
7273
$content .= $this->writeOpening();
7374
$content .= $this->openingText;
7475
$content .= $this->openingTags;
75-
$content .= $element->getText();
76+
if (Settings::isOutputEscapingEnabled()) {
77+
$content .= $this->escaper->escapeHtml($element->getText());
78+
} else {
79+
$content .= $element->getText();
80+
}
7681
$content .= $this->closingTags;
7782
$content .= $this->closingText;
7883
$content .= $this->writeClosing();
@@ -130,7 +135,12 @@ protected function writeClosing()
130135
{
131136
$content = '';
132137
if (!$this->withoutP) {
133-
$content .= $this->closingText;
138+
if (Settings::isOutputEscapingEnabled()) {
139+
$content .= $this->escaper->escapeHtml($this->closingText);
140+
} else {
141+
$content .= $this->closingText;
142+
}
143+
134144
$content .= "</p>" . PHP_EOL;
135145
}
136146

src/PhpWord/Writer/HTML/Element/Title.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717

1818
namespace PhpOffice\PhpWord\Writer\HTML\Element;
19+
use PhpOffice\PhpWord\Settings;
1920

2021
/**
2122
* TextRun element HTML writer
@@ -36,7 +37,11 @@ public function write()
3637
}
3738

3839
$tag = 'h' . $this->element->getDepth();
39-
$text = $this->element->getText();
40+
if (Settings::isOutputEscapingEnabled()) {
41+
$text = $this->escaper->escapeHtml($this->element->getText());
42+
} else {
43+
$text = $this->element->getText();
44+
}
4045
$content = "<{$tag}>{$text}</{$tag}>" . PHP_EOL;
4146

4247
return $content;

src/PhpWord/Writer/HTML/Part/AbstractPart.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
use PhpOffice\PhpWord\Exception\Exception;
2121
use PhpOffice\PhpWord\Writer\AbstractWriter;
22+
use Zend\Escaper\Escaper;
2223

2324
/**
2425
* Abstract HTML part writer
@@ -34,6 +35,16 @@ abstract class AbstractPart
3435
*/
3536
private $parentWriter;
3637

38+
/**
39+
* @var \Zend\Escaper\Escaper
40+
*/
41+
protected $escaper;
42+
43+
public function __construct()
44+
{
45+
$this->escaper = new Escaper();
46+
}
47+
3748
/**
3849
* Write part
3950
*

src/PhpWord/Writer/HTML/Part/Head.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ public function write()
4141
{
4242
$docProps = $this->getParentWriter()->getPhpWord()->getDocInfo();
4343
$propertiesMapping = array(
44-
'creator' => 'author',
45-
'title' => '',
44+
'creator' => 'author',
45+
'title' => '',
4646
'description' => '',
47-
'subject' => '',
48-
'keywords' => '',
49-
'category' => '',
50-
'company' => '',
51-
'manager' => ''
47+
'subject' => '',
48+
'keywords' => '',
49+
'category' => '',
50+
'company' => '',
51+
'manager' => ''
5252
);
5353
$title = $docProps->getTitle();
5454
$title = ($title != '') ? $title : 'PHPWord';
@@ -62,8 +62,9 @@ public function write()
6262
$value = ($value == '') ? $key : $value;
6363
$method = "get" . $key;
6464
if ($docProps->$method() != '') {
65-
$content .= '<meta name="' . $value . '" content="' .
66-
$docProps->$method() . '" />' . PHP_EOL;
65+
$content .= '<meta name="' . $value . '"'
66+
. ' content="' . (Settings::isOutputEscapingEnabled() ? $this->escaper->escapeHtmlAttr($docProps->$method()) : $docProps->$method()) . '"'
67+
.' />' . PHP_EOL;
6768
}
6869
}
6970
$content .= $this->writeStyles();

src/PhpWord/Writer/HTML/Style/Paragraph.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
namespace PhpOffice\PhpWord\Writer\HTML\Style;
1919

20+
use PhpOffice\PhpWord\SimpleType\Jc;
21+
2022
/**
2123
* Paragraph style HTML writer
2224
*
@@ -39,7 +41,40 @@ public function write()
3941

4042
// Alignment
4143
if ('' !== $style->getAlignment()) {
42-
$css['text-align'] = $style->getAlignment(); // todo: convert OpenXml to Html values
44+
$textAlign = '';
45+
46+
switch ($style->getAlignment()) {
47+
case Jc::START:
48+
case Jc::NUM_TAB:
49+
case Jc::LEFT:
50+
$textAlign = 'left';
51+
break;
52+
53+
case Jc::CENTER:
54+
$textAlign = 'center';
55+
break;
56+
57+
case Jc::END:
58+
case Jc::MEDIUM_KASHIDA:
59+
case Jc::HIGH_KASHIDA:
60+
case Jc::LOW_KASHIDA:
61+
case Jc::RIGHT:
62+
$textAlign = 'right';
63+
break;
64+
65+
case Jc::BOTH:
66+
case Jc::DISTRIBUTE:
67+
case Jc::THAI_DISTRIBUTE:
68+
case Jc::JUSTIFY:
69+
$textAlign = 'justify';
70+
break;
71+
72+
default:
73+
$textAlign = 'left';
74+
break;
75+
}
76+
77+
$css['text-align'] = $textAlign;
4378
}
4479

4580
// Spacing

0 commit comments

Comments
 (0)