Completed
Push — master ( 5a81ff...6ff660 )
by Juan José
12s queued 10s
created

gvm.xml.create_parser()   A

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2018 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: GPL-3.0-or-later
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
import defusedxml.lxml as secET
20
21
from defusedxml import DefusedXmlException
22
from lxml import etree
23
24
from gvm.errors import GvmError
25
26
27
def create_parser():
28
    # recover => try hard to parse through broken XML
29
    # huge_tree => disable security restrictions and support very deep trees and
30
    #              very long text content (for get_reports)
31
    return etree.XMLParser(encoding='utf-8', recover=True, huge_tree=True)
32
33
34
class XmlCommandElement:
35
36
    def __init__(self, element):
37
        self._element = element
38
39
    def add_element(self, name, text=None, *, attrs=None):
40
        node = etree.SubElement(self._element, name, attrib=attrs)
41
        node.text = text
42
        return XmlCommandElement(node)
43
44
    def set_attribute(self, name, value):
45
        self._element.set(name, value)
46
47
    def set_attributes(self, attrs):
48
        """Set several attributes at once.
49
50
        Arguments:
51
            attrs (dict): Attributes to be set on the element
52
        """
53
        for key, value in attrs.items():
54
            self._element.set(key, value)
55
56
    def append_xml_str(self, xml_text):
57
        """Append a xml element in string format."""
58
        node = secET.fromstring(xml_text)
59
        self._element.append(node)
60
61
    def to_string(self):
62
        return etree.tostring(self._element).decode('utf-8')
63
64
    def __str__(self):
65
        return self.to_string()
66
67
68
class XmlCommand(XmlCommandElement):
69
70
    def __init__(self, name):
71
        super().__init__(etree.Element(name))
72
73
74
def pretty_print(xml):
75
    """Prints beautiful XML-Code
76
77
    This function gets a string containing the xml, an object of
78
    list<lxml.etree._Element> or directly a lxml element.
79
80
    Print it with good readable format.
81
82
    Arguments:
83
        xml (str, list or lxml.etree.Element): xml as string,
84
            List<lxml.etree.Element> or directly a lxml element
85
    """
86
    if isinstance(xml, list):
87
        for item in xml:
88
            if etree.iselement(item):
89
                print(etree.tostring(item, pretty_print=True).decode('utf-8'))
90
            else:
91
                print(item)
92
    elif etree.iselement(xml):
93
        print(etree.tostring(xml, pretty_print=True).decode('utf-8'))
94
    elif isinstance(xml, str):
95
        tree = secET.fromstring(xml)
96
        print(etree.tostring(tree, pretty_print=True).decode('utf-8'))
97
98
99
def validate_xml_string(xml_string):
100
    """Checks if the passed string contains valid XML
101
102
    Raises a GvmError if the XML is invalid. Otherwise the function just
103
    returns.
104
105
    Raises:
106
        GvmError: The xml string did contain invalid XML
107
108
    """
109
    try:
110
        secET.fromstring(xml_string)
111
    except (DefusedXmlException, etree.LxmlError) as e:
112
        raise GvmError('Invalid XML', e) from e
113