#483. Output escaping for HTML.

This commit is contained in:
Roman Syroeshko 2016-06-28 21:37:36 +04:00
parent 508d6194fc
commit 4c7e1399fe
12 changed files with 114 additions and 35 deletions

View File

@ -24,7 +24,7 @@ Read more about PHPWord:
## Features ## Features
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: 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:
- Set document properties, e.g. title, subject, and creator. - Set document properties, e.g. title, subject, and creator.
- Create document sections with different settings, e.g. portrait/landscape, page size, and page numbering - 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
PHPWord requires the following: PHPWord requires the following:
- PHP 5.3+ - PHP 5.3.3+
- [XML Parser extension](http://www.php.net/manual/en/xml.installation.php) - [XML Parser extension](http://www.php.net/manual/en/xml.installation.php)
- [Zend\Escaper component](http://framework.zend.com/manual/current/en/modules/zend.escaper.introduction.html)
- Zend\Stdlib component
- [Zend\Validator component](http://framework.zend.com/manual/current/en/modules/zend.validator.html) - [Zend\Validator component](http://framework.zend.com/manual/current/en/modules/zend.validator.html)
- [Zip extension](http://php.net/manual/en/book.zip.php) (optional, used to write DOCX and ODT) - [Zip extension](http://php.net/manual/en/book.zip.php) (optional, used to write OOXML and ODF)
- [GD extension](http://php.net/manual/en/book.image.php) (optional, used to add images) - [GD extension](http://php.net/manual/en/book.image.php) (optional, used to add images)
- [XMLWriter extension](http://php.net/manual/en/book.xmlwriter.php) (optional, used to write DOCX and ODT) - [XMLWriter extension](http://php.net/manual/en/book.xmlwriter.php) (optional, used to write OOXML and ODF)
- [XSL extension](http://php.net/manual/en/book.xsl.php) (optional, used to apply XSL style sheet to template ) - [XSL extension](http://php.net/manual/en/book.xsl.php) (optional, used to apply XSL style sheet to template )
- [dompdf library](https://github.com/dompdf/dompdf) (optional, used to write PDF) - [dompdf library](https://github.com/dompdf/dompdf) (optional, used to write PDF)
@ -149,7 +151,6 @@ $objWriter->save('helloWorld.html');
/* Note: we skip RTF, because it's not XML-based and requires a different example. */ /* Note: we skip RTF, because it's not XML-based and requires a different example. */
/* Note: we skip PDF, because "HTML-to-PDF" approach is used to create PDF documents. */ /* Note: we skip PDF, because "HTML-to-PDF" approach is used to create PDF documents. */
``` ```
:warning: Escape any string you pass to HTML document, otherwise it may get broken.
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. 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.

View File

@ -1,10 +1,10 @@
{ {
"name": "phpoffice/phpword", "name": "phpoffice/phpword",
"description": "PHPWord - A pure PHP library for reading and writing word processing documents (DOCX, ODT, RTF, HTML, PDF)", "description": "PHPWord - A pure PHP library for reading and writing word processing documents (OOXML, ODF, RTF, HTML, PDF)",
"keywords": [ "keywords": [
"PHP", "PhpOffice", "office", "PhpWord", "word", "template", "template processor", "reader", "writer", "PHP", "PHPOffice", "office", "PHPWord", "word", "template", "template processor", "reader", "writer",
"docx", "OOXML", "OpenXML", "Office Open XML", "ISO IEC 29500", "WordprocessingML", "docx", "OOXML", "OpenXML", "Office Open XML", "ISO IEC 29500", "WordprocessingML",
"RTF", "Rich Text Format", "doc", "odt", "OpenDocument", "PDF", "HTML" "RTF", "Rich Text Format", "doc", "odt", "ODF", "OpenDocument", "PDF", "HTML"
], ],
"homepage": "http://phpoffice.github.io", "homepage": "http://phpoffice.github.io",
"type": "library", "type": "library",
@ -34,8 +34,9 @@
"require": { "require": {
"php": ">=5.3.3", "php": ">=5.3.3",
"ext-xml": "*", "ext-xml": "*",
"zendframework/zend-stdlib": "~2.5", "zendframework/zend-escaper": "2.4.*",
"zendframework/zend-validator": "2.5.*", "zendframework/zend-stdlib": "2.4.*",
"zendframework/zend-validator": "2.4.*",
"phpoffice/common": "0.2.*" "phpoffice/common": "0.2.*"
}, },
"require-dev": { "require-dev": {
@ -46,15 +47,12 @@
"phploc/phploc": "2.*", "phploc/phploc": "2.*",
"dompdf/dompdf":"0.6.*", "dompdf/dompdf":"0.6.*",
"tecnickcom/tcpdf": "6.*", "tecnickcom/tcpdf": "6.*",
"mpdf/mpdf": "5.*", "mpdf/mpdf": "5.*"
"zendframework/zend-stdlib": "~2.5",
"zendframework/zend-validator": "2.5.*",
"phpoffice/common": "0.2.*"
}, },
"suggest": { "suggest": {
"ext-zip": "Allows writing DOCX and ODT", "ext-zip": "Allows writing OOXML and ODF",
"ext-gd2": "Allows adding images", "ext-gd2": "Allows adding images",
"ext-xmlwriter": "Allows writing DOCX and ODT", "ext-xmlwriter": "Allows writing OOXML and ODF",
"ext-xsl": "Allows applying XSL style sheet to main document part of OOXML template", "ext-xsl": "Allows applying XSL style sheet to main document part of OOXML template",
"dompdf/dompdf": "Allows writing PDF" "dompdf/dompdf": "Allows writing PDF"
}, },

View File

@ -8,8 +8,10 @@ Requirements
Mandatory: Mandatory:
- PHP 5.3+ - PHP 5.3.3+
- `XML Parser <http://www.php.net/manual/en/xml.installation.php>`__ extension - `XML Parser <http://www.php.net/manual/en/xml.installation.php>`__ extension
- `Zend\\Escaper <http://framework.zend.com/manual/current/en/modules/zend.escaper.introduction.html>`__ component
- Zend\\Stdlib component
- `Zend\\Validator <http://framework.zend.com/manual/current/en/modules/zend.validator.html>`__ component - `Zend\\Validator <http://framework.zend.com/manual/current/en/modules/zend.validator.html>`__ component
Optional: Optional:

View File

@ -63,7 +63,7 @@ Writers
~~~~~~~ ~~~~~~~
+---------------------------+----------------------+--------+-------+-------+--------+-------+ +---------------------------+----------------------+--------+-------+-------+--------+-------+
| Features | | DOCX | ODT | RTF | HTML | PDF | | Features | | OOXML | ODF | RTF | HTML | PDF |
+===========================+======================+========+=======+=======+========+=======+ +===========================+======================+========+=======+=======+========+=======+
| **Document Properties** | Standard | ✓ | ✓ | ✓ | ✓ | ✓ | | **Document Properties** | Standard | ✓ | ✓ | ✓ | ✓ | ✓ |
+---------------------------+----------------------+--------+-------+-------+--------+-------+ +---------------------------+----------------------+--------+-------+-------+--------+-------+
@ -122,7 +122,7 @@ Readers
~~~~~~~ ~~~~~~~
+---------------------------+----------------------+--------+-------+-------+-------+-------+ +---------------------------+----------------------+--------+-------+-------+-------+-------+
| Features | | DOCX | DOC | ODT | RTF | HTML | | Features | | OOXML | DOC | ODF | RTF | HTML |
+===========================+======================+========+=======+=======+=======+=======+ +===========================+======================+========+=======+=======+=======+=======+
| **Document Properties** | Standard | ✓ | | | | | | **Document Properties** | Standard | ✓ | | | | |
+---------------------------+----------------------+--------+-------+-------+-------+-------+ +---------------------------+----------------------+--------+-------+-------+-------+-------+

View File

@ -19,6 +19,7 @@ namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Element\AbstractElement as Element; use PhpOffice\PhpWord\Element\AbstractElement as Element;
use PhpOffice\PhpWord\Writer\AbstractWriter; use PhpOffice\PhpWord\Writer\AbstractWriter;
use Zend\Escaper\Escaper;
/** /**
* Abstract HTML element writer * Abstract HTML element writer
@ -48,6 +49,11 @@ abstract class AbstractElement
*/ */
protected $withoutP = false; protected $withoutP = false;
/**
* @var \Zend\Escaper\Escaper
*/
protected $escaper;
/** /**
* Write element * Write element
*/ */
@ -65,6 +71,7 @@ abstract class AbstractElement
$this->parentWriter = $parentWriter; $this->parentWriter = $parentWriter;
$this->element = $element; $this->element = $element;
$this->withoutP = $withoutP; $this->withoutP = $withoutP;
$this->escaper = new Escaper();
} }
/** /**

View File

@ -16,6 +16,7 @@
*/ */
namespace PhpOffice\PhpWord\Writer\HTML\Element; namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Settings;
/** /**
* Link element HTML writer * Link element HTML writer
@ -37,7 +38,11 @@ class Link extends Text
$content = ''; $content = '';
$content .= $this->writeOpening(); $content .= $this->writeOpening();
if (Settings::isOutputEscapingEnabled()) {
$content .= "<a href=\"{$this->escaper->escapeHtmlAttr($this->element->getSource())}\">{$this->escaper->escapeHtml($this->element->getText())}</a>";
} else {
$content .= "<a href=\"{$this->element->getSource()}\">{$this->element->getText()}</a>"; $content .= "<a href=\"{$this->element->getSource()}\">{$this->element->getText()}</a>";
}
$content .= $this->writeClosing(); $content .= $this->writeClosing();
return $content; return $content;

View File

@ -16,6 +16,7 @@
*/ */
namespace PhpOffice\PhpWord\Writer\HTML\Element; namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Settings;
/** /**
* ListItem element HTML writer * ListItem element HTML writer
@ -35,8 +36,11 @@ class ListItem extends AbstractElement
return ''; return '';
} }
$text = $this->element->getTextObject()->getText(); if (Settings::isOutputEscapingEnabled()) {
$content = '<p>' . $text . '</p>' . PHP_EOL; $content = '<p>' . $this->escaper->escapeHtml($this->element->getTextObject()->getText()) . '</p>' . PHP_EOL;
} else {
$content = '<p>' . $this->element->getTextObject()->getText() . '</p>' . PHP_EOL;
}
return $content; return $content;
} }

View File

@ -17,6 +17,7 @@
namespace PhpOffice\PhpWord\Writer\HTML\Element; namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Settings;
use PhpOffice\PhpWord\Style\Font; use PhpOffice\PhpWord\Style\Font;
use PhpOffice\PhpWord\Style\Paragraph; use PhpOffice\PhpWord\Style\Paragraph;
use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter; use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter;
@ -72,7 +73,11 @@ class Text extends AbstractElement
$content .= $this->writeOpening(); $content .= $this->writeOpening();
$content .= $this->openingText; $content .= $this->openingText;
$content .= $this->openingTags; $content .= $this->openingTags;
if (Settings::isOutputEscapingEnabled()) {
$content .= $this->escaper->escapeHtml($element->getText());
} else {
$content .= $element->getText(); $content .= $element->getText();
}
$content .= $this->closingTags; $content .= $this->closingTags;
$content .= $this->closingText; $content .= $this->closingText;
$content .= $this->writeClosing(); $content .= $this->writeClosing();
@ -130,7 +135,12 @@ class Text extends AbstractElement
{ {
$content = ''; $content = '';
if (!$this->withoutP) { if (!$this->withoutP) {
if (Settings::isOutputEscapingEnabled()) {
$content .= $this->escaper->escapeHtml($this->closingText);
} else {
$content .= $this->closingText; $content .= $this->closingText;
}
$content .= "</p>" . PHP_EOL; $content .= "</p>" . PHP_EOL;
} }

View File

@ -16,6 +16,7 @@
*/ */
namespace PhpOffice\PhpWord\Writer\HTML\Element; namespace PhpOffice\PhpWord\Writer\HTML\Element;
use PhpOffice\PhpWord\Settings;
/** /**
* TextRun element HTML writer * TextRun element HTML writer
@ -36,7 +37,11 @@ class Title extends AbstractElement
} }
$tag = 'h' . $this->element->getDepth(); $tag = 'h' . $this->element->getDepth();
if (Settings::isOutputEscapingEnabled()) {
$text = $this->escaper->escapeHtml($this->element->getText());
} else {
$text = $this->element->getText(); $text = $this->element->getText();
}
$content = "<{$tag}>{$text}</{$tag}>" . PHP_EOL; $content = "<{$tag}>{$text}</{$tag}>" . PHP_EOL;
return $content; return $content;

View File

@ -19,6 +19,7 @@ namespace PhpOffice\PhpWord\Writer\HTML\Part;
use PhpOffice\PhpWord\Exception\Exception; use PhpOffice\PhpWord\Exception\Exception;
use PhpOffice\PhpWord\Writer\AbstractWriter; use PhpOffice\PhpWord\Writer\AbstractWriter;
use Zend\Escaper\Escaper;
/** /**
* Abstract HTML part writer * Abstract HTML part writer
@ -34,6 +35,16 @@ abstract class AbstractPart
*/ */
private $parentWriter; private $parentWriter;
/**
* @var \Zend\Escaper\Escaper
*/
protected $escaper;
public function __construct()
{
$this->escaper = new Escaper();
}
/** /**
* Write part * Write part
* *

View File

@ -62,8 +62,9 @@ class Head extends AbstractPart
$value = ($value == '') ? $key : $value; $value = ($value == '') ? $key : $value;
$method = "get" . $key; $method = "get" . $key;
if ($docProps->$method() != '') { if ($docProps->$method() != '') {
$content .= '<meta name="' . $value . '" content="' . $content .= '<meta name="' . $value . '"'
$docProps->$method() . '" />' . PHP_EOL; . ' content="' . (Settings::isOutputEscapingEnabled() ? $this->escaper->escapeHtmlAttr($docProps->$method()) : $docProps->$method()) . '"'
.' />' . PHP_EOL;
} }
} }
$content .= $this->writeStyles(); $content .= $this->writeStyles();

View File

@ -17,6 +17,8 @@
namespace PhpOffice\PhpWord\Writer\HTML\Style; namespace PhpOffice\PhpWord\Writer\HTML\Style;
use PhpOffice\PhpWord\SimpleType\Jc;
/** /**
* Paragraph style HTML writer * Paragraph style HTML writer
* *
@ -39,7 +41,40 @@ class Paragraph extends AbstractStyle
// Alignment // Alignment
if ('' !== $style->getAlignment()) { if ('' !== $style->getAlignment()) {
$css['text-align'] = $style->getAlignment(); // todo: convert OpenXml to Html values $textAlign = '';
switch ($style->getAlignment()) {
case Jc::START:
case Jc::NUM_TAB:
case Jc::LEFT:
$textAlign = 'left';
break;
case Jc::CENTER:
$textAlign = 'center';
break;
case Jc::END:
case Jc::MEDIUM_KASHIDA:
case Jc::HIGH_KASHIDA:
case Jc::LOW_KASHIDA:
case Jc::RIGHT:
$textAlign = 'right';
break;
case Jc::BOTH:
case Jc::DISTRIBUTE:
case Jc::THAI_DISTRIBUTE:
case Jc::JUSTIFY:
$textAlign = 'justify';
break;
default:
$textAlign = 'left';
break;
}
$css['text-align'] = $textAlign;
} }
// Spacing // Spacing