# Buggy code
def parse_magnetlink(url):
    # url must be a magnet link
    dn = None
    xt = None
    trs = []

    logger.debug("parse_magnetlink() %s", url)

    schema, netloc, path, query, fragment = urlsplit(url)
    if schema == "magnet":
        # magnet url's do not conform to regular url syntax (they
        # do not have a netloc.)  This causes path to contain the
        # query part.
        if "?" in path:
            pre, post = path.split("?", 1)
            if query:
                query = "&".join((post, query))
            else:
                query = post

        for key, value in parse_qsl(query):
            if key == "dn":
                # convert to unicode
                dn = value.decode() if not isinstance(value, unicode) else value

            elif key == "xt" and value.startswith("urn:btih:"):
                # vliegendhart: Adding support for base32 in magnet links (BEP 0009)
                encoded_infohash = value[9:49]
                if len(encoded_infohash) == 32:
                    xt = b32decode(encoded_infohash)
                else:
                    xt = binascii.unhexlify(encoded_infohash)

            elif key == "tr":
                trs.append(value)

        logger.debug("parse_magnetlink() NAME: %s", dn)
        logger.debug("parse_magnetlink() HASH: %s", xt)
        logger.debug("parse_magnetlink() TRACS: %s", trs)

    return (dn, xt, trs)


# Traceback (TypeError)
ERROR:RESTRequest:[Failure instance: Traceback: <type 'exceptions.TypeError'>: Non-base32 digit found
/usr/lib/python2.7/dist-packages/twisted/protocols/basic.py:571:dataReceived
/usr/lib/python2.7/dist-packages/twisted/web/http.py:1657:lineReceived
/usr/lib/python2.7/dist-packages/twisted/web/http.py:1736:allContentReceived
/usr/lib/python2.7/dist-packages/twisted/web/http.py:762:requestReceived
--- <exception caught here> ---
/usr/lib/python2.7/dist-packages/twisted/web/server.py:183:process
/usr/lib/python2.7/dist-packages/twisted/web/server.py:234:render
/usr/lib/python2.7/dist-packages/twisted/web/resource.py:250:render
/opt/tribler/Tribler/Core/Modules/restapi/torrentinfo_endpoint.py:102:render_GET
/opt/tribler/Tribler/Core/Utilities/utilities.py:249:parse_magnetlink
/usr/lib/python2.7/base64.py:229:b32decode
]
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/twisted/web/server.py", line 183, in process
self.render(resrc)
File "/usr/lib/python2.7/dist-packages/twisted/web/server.py", line 234, in render
body = resrc.render(self)
File "/usr/lib/python2.7/dist-packages/twisted/web/resource.py", line 250, in render
return m(request)
File "/opt/tribler/Tribler/Core/Modules/restapi/torrentinfo_endpoint.py", line 102, in render_GET
self.infohash = parse_magnetlink(uri)[1]
File "/opt/tribler/Tribler/Core/Utilities/utilities.py", line 249, in parse_magnetlink
xt = b32decode(encoded_infohash)
File "/usr/lib/python2.7/base64.py", line 229, in b32decode
raise TypeError('Non-base32 digit found')
TypeError: Non-base32 digit found

# Fixed code
def parse_magnetlink(url):
    # url must be a magnet link
    dn = None
    xt = None
    trs = []

    logger.debug("parse_magnetlink() %s", url)

    schema, netloc, path, query, fragment = urlsplit(url)
    if schema == "magnet":
        # magnet url's do not conform to regular url syntax (they
        # do not have a netloc.)  This causes path to contain the
        # query part.
        if "?" in path:
            pre, post = path.split("?", 1)
            if query:
                query = "&".join((post, query))
            else:
                query = post

        for key, value in parse_qsl(query):
            if key == "dn":
                # convert to unicode
                dn = value.decode() if not isinstance(value, unicode) else value

            elif key == "xt" and value.startswith("urn:btih:"):
                # vliegendhart: Adding support for base32 in magnet links (BEP 0009)
                encoded_infohash = value[9:49]
                if len(encoded_infohash) == 32:
                    xt = b32decode(encoded_infohash.upper())
                else:
                    xt = binascii.unhexlify(encoded_infohash)

            elif key == "tr":
                trs.append(value)

        logger.debug("parse_magnetlink() NAME: %s", dn)
        logger.debug("parse_magnetlink() HASH: %s", xt)
        logger.debug("parse_magnetlink() TRACS: %s", trs)

    return (dn, xt, trs)