Browse Source

Fixes #10346: Fixed "DOMException: Invalid Character Error" in `yii\web\XmlResponseFormatter::buildXml()`

tags/2.0.12
sasha-ch 8 years ago committed by Alexander Makarov
parent
commit
339c7663eb
No known key found for this signature in database
GPG Key ID: 3617B79C6A325E4A
  1. 1
      framework/CHANGELOG.md
  2. 40
      framework/web/XmlResponseFormatter.php
  3. 10
      tests/framework/web/XmlResponseFormatterTest.php

1
framework/CHANGELOG.md

@ -4,6 +4,7 @@ Yii Framework 2 Change Log
2.0.12 under development
--------------------------
- Bug #10346: Fixed "DOMException: Invalid Character Error" in `yii\web\XmlResponseFormatter::buildXml()` (sasha-ch)
- Bug #13694: `yii\widgets\Pjax` now sends `X-Pjax-Url` header with response to fix redirect (wleona3, Faryshta)
- Bug #14012: `yii\db\pgsql\Schema::findViewNames()` was skipping materialized views (insolita)
- Bug #13362: Fixed return value of `yii\caching\MemCache::setValues()` (masterklavi)

40
framework/web/XmlResponseFormatter.php

@ -10,6 +10,7 @@ namespace yii\web;
use DOMDocument;
use DOMElement;
use DOMText;
use DOMException;
use yii\base\Arrayable;
use yii\base\Component;
use yii\helpers\StringHelper;
@ -94,11 +95,11 @@ class XmlResponseFormatter extends Component implements ResponseFormatterInterfa
if (is_int($name) && is_object($value)) {
$this->buildXml($element, $value);
} elseif (is_array($value) || is_object($value)) {
$child = new DOMElement(is_int($name) ? $this->itemTag : $name);
$child = new DOMElement($this->getValidXmlElementName($name));
$element->appendChild($child);
$this->buildXml($child, $value);
} else {
$child = new DOMElement(is_int($name) ? $this->itemTag : $name);
$child = new DOMElement($this->getValidXmlElementName($name));
$element->appendChild($child);
$child->appendChild(new DOMText($this->formatScalarValue($value)));
}
@ -143,4 +144,39 @@ class XmlResponseFormatter extends Component implements ResponseFormatterInterfa
return (string) $value;
}
/**
* Returns element name ready to be used in DOMElement if
* name is not empty, is not int and is valid.
*
* Falls back to [[itemTag]] otherwise.
*
* @param mixed $name
* @return string
* @since 2.0.12
*/
protected function getValidXmlElementName($name)
{
if (empty($name) || is_int($name) || !$this->isValidXmlName($name)) {
return $this->itemTag;
}
return $name;
}
/**
* Checks if name is valid to be used in XML
*
* @param mixed $name
* @return bool
* @see http://stackoverflow.com/questions/2519845/how-to-check-if-string-is-a-valid-xml-element-name/2519943#2519943
*/
protected function isValidXmlName($name)
{
try {
new DOMElement($name);
return true;
} catch (DOMException $e) {
return false;
}
}
}

10
tests/framework/web/XmlResponseFormatterTest.php

@ -69,6 +69,16 @@ class XmlResponseFormatterTest extends FormatterTest
'c' => [2, '<>'],
false,
], "<response><a>1</a><b>abc</b><c><item>2</item><item>&lt;&gt;</item></c><item>false</item></response>\n"],
// Checks if empty keys and keys not valid in XML are processed.
// See https://github.com/yiisoft/yii2/pull/10346/
[[
'' => 1,
'2015-06-18' => '2015-06-18',
'b:c' => 'b:c',
'a b c' => 'a b c',
'äøñ' => 'äøñ'
], "<response><item>1</item><item>2015-06-18</item><item>b:c</item><item>a b c</item><äøñ>äøñ</äøñ></response>\n"],
]);
}

Loading…
Cancel
Save