test_xml.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from xml.dom import minidom
  2. from django.core import serializers
  3. from django.core.serializers.xml_serializer import DTDForbidden
  4. from django.test import TestCase, TransactionTestCase
  5. from .tests import SerializersTestBase, SerializersTransactionTestBase
  6. class XmlSerializerTestCase(SerializersTestBase, TestCase):
  7. serializer_name = "xml"
  8. pkless_str = """<?xml version="1.0" encoding="utf-8"?>
  9. <django-objects version="1.0">
  10. <object model="serializers.category">
  11. <field type="CharField" name="name">Reference</field>
  12. </object>
  13. <object model="serializers.category">
  14. <field type="CharField" name="name">Non-fiction</field>
  15. </object>
  16. </django-objects>"""
  17. mapping_ordering_str = """<?xml version="1.0" encoding="utf-8"?>
  18. <django-objects version="1.0">
  19. <object model="serializers.article" pk="%(article_pk)s">
  20. <field name="author" rel="ManyToOneRel" to="serializers.author">%(author_pk)s</field>
  21. <field name="headline" type="CharField">Poker has no place on ESPN</field>
  22. <field name="pub_date" type="DateTimeField">2006-06-16T11:00:00</field>
  23. <field name="categories" rel="ManyToManyRel" to="serializers.category"><object pk="%(first_category_pk)s"></object><object pk="%(second_category_pk)s"></object></field>
  24. <field name="meta_data" rel="ManyToManyRel" to="serializers.categorymetadata"></field>
  25. </object>
  26. </django-objects>""" # NOQA
  27. @staticmethod
  28. def _validate_output(serial_str):
  29. try:
  30. minidom.parseString(serial_str)
  31. except Exception:
  32. return False
  33. else:
  34. return True
  35. @staticmethod
  36. def _get_pk_values(serial_str):
  37. ret_list = []
  38. dom = minidom.parseString(serial_str)
  39. fields = dom.getElementsByTagName("object")
  40. for field in fields:
  41. ret_list.append(field.getAttribute("pk"))
  42. return ret_list
  43. @staticmethod
  44. def _get_field_values(serial_str, field_name):
  45. ret_list = []
  46. dom = minidom.parseString(serial_str)
  47. fields = dom.getElementsByTagName("field")
  48. for field in fields:
  49. if field.getAttribute("name") == field_name:
  50. temp = []
  51. for child in field.childNodes:
  52. temp.append(child.nodeValue)
  53. ret_list.append("".join(temp))
  54. return ret_list
  55. def test_control_char_failure(self):
  56. """
  57. Serializing control characters with XML should fail as those characters
  58. are not supported in the XML 1.0 standard (except HT, LF, CR).
  59. """
  60. self.a1.headline = "This contains \u0001 control \u0011 chars"
  61. msg = "Article.headline (pk:%s) contains unserializable characters" % self.a1.pk
  62. with self.assertRaisesMessage(ValueError, msg):
  63. serializers.serialize(self.serializer_name, [self.a1])
  64. self.a1.headline = "HT \u0009, LF \u000A, and CR \u000D are allowed"
  65. self.assertIn(
  66. "HT \t, LF \n, and CR \r are allowed",
  67. serializers.serialize(self.serializer_name, [self.a1])
  68. )
  69. def test_no_dtd(self):
  70. """
  71. The XML deserializer shouldn't allow a DTD.
  72. This is the most straightforward way to prevent all entity definitions
  73. and avoid both external entities and entity-expansion attacks.
  74. """
  75. xml = '<?xml version="1.0" standalone="no"?><!DOCTYPE example SYSTEM "http://example.com/example.dtd">'
  76. with self.assertRaises(DTDForbidden):
  77. next(serializers.deserialize('xml', xml))
  78. class XmlSerializerTransactionTestCase(SerializersTransactionTestBase, TransactionTestCase):
  79. serializer_name = "xml"
  80. fwd_ref_str = """<?xml version="1.0" encoding="utf-8"?>
  81. <django-objects version="1.0">
  82. <object pk="1" model="serializers.article">
  83. <field to="serializers.author" name="author" rel="ManyToOneRel">1</field>
  84. <field type="CharField" name="headline">Forward references pose no problem</field>
  85. <field type="DateTimeField" name="pub_date">2006-06-16T15:00:00</field>
  86. <field to="serializers.category" name="categories" rel="ManyToManyRel">
  87. <object pk="1"></object>
  88. </field>
  89. <field to="serializers.categorymetadata" name="meta_data" rel="ManyToManyRel"></field>
  90. </object>
  91. <object pk="1" model="serializers.author">
  92. <field type="CharField" name="name">Agnes</field>
  93. </object>
  94. <object pk="1" model="serializers.category">
  95. <field type="CharField" name="name">Reference</field></object>
  96. </django-objects>"""