File: c14n.py

package info (click to toggle)
python-nbxmpp 2.0.2-1%2Bdeb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,120 kB
  • sloc: python: 14,949; makefile: 8
file content (57 lines) | stat: -rw-r--r-- 1,961 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
## c14n.py
##
## Copyright (C) 2007-2008 Brendan Taylor <whateley AT gmail.com>
##
## This file is part of Gajim.
##
## Gajim is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
## by the Free Software Foundation; version 3 only.
##
## Gajim is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##

"""
XML canonicalisation methods (for XEP-0116)
"""

def c14n(node, is_buggy):
    s = "<" + node.name
    if node.namespace:
        if not node.parent or node.parent.namespace != node.namespace:
            s += ' xmlns="%s"' % node.namespace

    sorted_attrs = sorted(node.attrs.keys())
    for key in sorted_attrs:
        if not is_buggy and key == 'xmlns':
            continue
        val = str(node.attrs[key])
        # like XMLescape() but with whitespace and without &gt;
        s += ' %s="%s"' % (key, normalise_attr(val))
    s += ">"
    cnt = 0
    if node.kids:
        for a in node.kids:
            if (len(node.data)-1) >= cnt:
                s = s + normalise_text(node.data[cnt])
            s = s + c14n(a, is_buggy)
            cnt += 1
    if (len(node.data)-1) >= cnt:
        s = s + normalise_text(node.data[cnt])
    if not node.kids and s.endswith('>'):
        s=s[:-1]+' />'
    else:
        s = s + "</" + node.name + ">"
    return s

def normalise_attr(val):
    return val.replace('&', '&amp;').replace('<', '&lt;').replace('"', '&quot;').replace('\t', '&#x9;').replace('\n', '&#xA;').replace('\r', '&#xD;')

def normalise_text(val):
    return val.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('\r', '&#xD;')