XmlSerializationTest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /*
  3. * Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. namespace JMS\SerializerBundle\Tests\Serializer;
  18. use Metadata\MetadataFactory;
  19. use Doctrine\Common\Annotations\AnnotationReader;
  20. use JMS\SerializerBundle\Tests\Fixtures\InvalidUsageOfXmlValue;
  21. use JMS\SerializerBundle\Serializer\Construction\UnserializeObjectConstructor;
  22. use JMS\SerializerBundle\Serializer\Naming\CamelCaseNamingStrategy;
  23. use JMS\SerializerBundle\Serializer\Naming\SerializedNameAnnotationStrategy;
  24. use JMS\SerializerBundle\Serializer\XmlDeserializationVisitor;
  25. use JMS\SerializerBundle\Metadata\Driver\AnnotationDriver;
  26. use JMS\SerializerBundle\Serializer\Serializer;
  27. use JMS\SerializerBundle\Exception\InvalidArgumentException;
  28. use JMS\SerializerBundle\Tests\Fixtures\PersonCollection;
  29. use JMS\SerializerBundle\Tests\Fixtures\PersonLocation;
  30. use JMS\SerializerBundle\Tests\Fixtures\Person;
  31. use JMS\SerializerBundle\Tests\Fixtures\ObjectWithVirtualXmlProperties;
  32. use JMS\SerializerBundle\Tests\Fixtures\ObjectWithXmlKeyValuePairs;
  33. class XmlSerializationTest extends BaseSerializationTest
  34. {
  35. /**
  36. * @expectedException \RuntimeException
  37. */
  38. public function testInvalidUsageOfXmlValue()
  39. {
  40. $obj = new InvalidUsageOfXmlValue();
  41. $this->serialize($obj);
  42. }
  43. public function testPropertyIsObjectWithAttributeAndValue()
  44. {
  45. $personCollection = new PersonLocation;
  46. $person = new Person;
  47. $person->name = 'Matthias Noback';
  48. $person->age = 28;
  49. $personCollection->person = $person;
  50. $personCollection->location = 'The Netherlands';
  51. $this->assertEquals($this->getContent('person_location'), $this->serialize($personCollection));
  52. }
  53. public function testPropertyIsCollectionOfObjectsWithAttributeAndValue()
  54. {
  55. $personCollection = new PersonCollection;
  56. $person = new Person;
  57. $person->name = 'Matthias Noback';
  58. $person->age = 28;
  59. $personCollection->persons->add($person);
  60. $personCollection->location = 'The Netherlands';
  61. $this->assertEquals($this->getContent('person_collection'), $this->serialize($personCollection));
  62. }
  63. /**
  64. * @expectedException \InvalidArgumentException
  65. * @expectedExceptionMessage The document type "<!DOCTYPE author [<!ENTITY foo SYSTEM "php://filter/read=convert.base64-encode/resource=XmlSerializationTest.php">]>" is not allowed. If it is safe, you may add it to the whitelist configuration.
  66. */
  67. public function testExternalEntitiesAreDisabledByDefault()
  68. {
  69. $this->deserialize('<?xml version="1.0"?>
  70. <!DOCTYPE author [
  71. <!ENTITY foo SYSTEM "php://filter/read=convert.base64-encode/resource='.basename(__FILE__).'">
  72. ]>
  73. <result>
  74. &foo;
  75. </result>', 'stdClass');
  76. }
  77. /**
  78. * @expectedException \InvalidArgumentException
  79. * @expectedExceptionMessage The document type "<!DOCTYPE foo>" is not allowed. If it is safe, you may add it to the whitelist configuration.
  80. */
  81. public function testDocumentTypesAreNotAllowed()
  82. {
  83. $this->deserialize('<?xml version="1.0"?><!DOCTYPE foo><foo></foo>', 'stdClass');
  84. }
  85. public function testWhitelistedDocumentTypesAreAllowed()
  86. {
  87. $xmlVisitor = new XmlDeserializationVisitor(
  88. new SerializedNameAnnotationStrategy(new CamelCaseNamingStrategy()),
  89. $this->getDeserializationHandlers(),
  90. new UnserializeObjectConstructor()
  91. );
  92. $xmlVisitor->setDoctypeWhitelist(array(
  93. '<!DOCTYPE authorized SYSTEM "http://authorized_url.dtd">',
  94. '<!DOCTYPE author [<!ENTITY foo SYSTEM "php://filter/read=convert.base64-encode/resource='.basename(__FILE__).'">]>'));
  95. $serializer = new Serializer(new MetadataFactory(new AnnotationDriver(new AnnotationReader())), array(), array('xml' => $xmlVisitor));
  96. $serializer->deserialize('<?xml version="1.0"?>
  97. <!DOCTYPE authorized SYSTEM "http://authorized_url.dtd">
  98. <foo></foo>', 'stdClass', 'xml');
  99. $serializer->deserialize('<?xml version="1.0"?>
  100. <!DOCTYPE author [
  101. <!ENTITY foo SYSTEM "php://filter/read=convert.base64-encode/resource='.basename(__FILE__).'">
  102. ]>
  103. <foo></foo>', 'stdClass', 'xml');
  104. }
  105. public function testVirtualAttributes()
  106. {
  107. $serializer = $this->getSerializer();
  108. $serializer->setGroups(array('attributes'));
  109. $this->assertEquals($this->getContent('virtual_attributes'), $serializer->serialize(new ObjectWithVirtualXmlProperties(),'xml'));
  110. }
  111. public function testVirtualValues()
  112. {
  113. $serializer = $this->getSerializer();
  114. $serializer->setGroups(array('values'));
  115. $this->assertEquals($this->getContent('virtual_values'), $serializer->serialize(new ObjectWithVirtualXmlProperties(),'xml'));
  116. }
  117. public function testVirtualXmlList()
  118. {
  119. $serializer = $this->getSerializer();
  120. $serializer->setGroups(array('list'));
  121. $this->assertEquals($this->getContent('virtual_properties_list'), $serializer->serialize(new ObjectWithVirtualXmlProperties(),'xml'));
  122. }
  123. public function testVirtualXmlMap()
  124. {
  125. $serializer = $this->getSerializer();
  126. $serializer->setGroups(array('map'));
  127. $this->assertEquals($this->getContent('virtual_properties_map'), $serializer->serialize(new ObjectWithVirtualXmlProperties(),'xml'));
  128. }
  129. public function testArrayKeyValues()
  130. {
  131. $serializer = $this->getSerializer();
  132. $this->assertEquals($this->getContent('array_key_values'), $serializer->serialize(new ObjectWithXmlKeyValuePairs(), 'xml'));
  133. }
  134. /**
  135. * @param string $key
  136. */
  137. protected function getContent($key)
  138. {
  139. if (!file_exists($file = __DIR__.'/xml/'.$key.'.xml')) {
  140. throw new InvalidArgumentException(sprintf('The key "%s" is not supported.', $key));
  141. }
  142. return file_get_contents($file);
  143. }
  144. protected function getFormat()
  145. {
  146. return 'xml';
  147. }
  148. }