#!/usr/bin/env python3
# coding: utf-8
from __future__ import print_function, unicode_literals
import re
import unittest
from xml.etree import ElementTree as ET
from copyparty.dxml import BadXML, mkenod, mktnod, parse_xml
ET.register_namespace("D", "DAV:")
def _parse(txt):
try:
parse_xml(txt)
raise Exception("unsafe")
except BadXML:
pass
class TestDXML(unittest.TestCase):
def test_qbe(self):
# allowed by default; verify that we stopped it
txt = r"""
]>
&a;&a;&a;&a;&a;&a;&a;&a;&a;"""
_parse(txt)
ET.fromstring(txt)
def test_ent_file(self):
# NOT allowed by default; should still be blocked
txt = r"""
]>
ⅇ"""
_parse(txt)
try:
ET.fromstring(txt)
raise Exception("unsafe2")
except ET.ParseError:
pass
def test_ent_ext(self):
# NOT allowed by default; should still be blocked
txt = r"""
]>
ⅇ"""
_parse(txt)
def test_dtd(self):
# allowed by default; verify that we stopped it
txt = r"""
a"""
_parse(txt)
ET.fromstring(txt)
##
## end of negative/security tests; the rest is functional
##
def test3(self):
txt = r"""
"""
txt = txt.replace("\n", "\r\n")
ET.fromstring(txt)
el = parse_xml(txt)
self.assertListEqual(
[y.tag for y in el.findall(r"./{DAV:}prop/*")],
[r"{DAV:}name", r"{DAV:}href"],
)
def test4(self):
txt = r"""
Thu, 20 Oct 2022 02:16:33 GMT
Thu, 20 Oct 2022 02:16:35 GMT
Thu, 20 Oct 2022 02:16:33 GMT
00000000
"""
ref = r"""
/d1/foo.txt
HTTP/1.1 403 Forbidden
"""
txt = re.sub("\n +", "\n", txt)
root = mkenod("a")
root.insert(0, parse_xml(txt))
prop = root.find(r"./{DAV:}propertyupdate/{DAV:}set/{DAV:}prop")
assert prop is not None
assert len(prop)
for el in prop:
el.clear()
res = ET.tostring(prop).decode("utf-8")
want = """
"""
self.assertEqual(res, want)
def test5(self):
txt = r"""
DESKTOP-FRS9AO2\ed
"""
ref = r"""
infinity
DESKTOP-FRS9AO2\ed
Second-3600
1666199679
/d1/foo.txt
"""
txt = re.sub("\n +", "\n", txt)
lk = parse_xml(txt)
self.assertEqual(lk.tag, "{DAV:}lockinfo")
if lk.find(r"./{DAV:}depth") is None:
lk.append(mktnod("D:depth", "infinity"))
lk.append(mkenod("D:timeout", mktnod("D:href", "Second-3600")))
lk.append(mkenod("D:locktoken", mktnod("D:href", "56709")))
lk.append(mkenod("D:lockroot", mktnod("D:href", "/foo/bar.txt")))
lk2 = mkenod("D:activelock")
root = mkenod("D:prop", mkenod("D:lockdiscovery", lk2))
for a in lk:
lk2.append(a)
print(ET.tostring(root).decode("utf-8"))