def check_info(info):
    """ Validate info dict.

        Raise ValueError if validation fails.
    """
    if not isinstance(info, dict):
        raise ValueError("bad metainfo - not a dictionary")

    pieces = info.get("pieces")
    if not isinstance(pieces, basestring) or len(pieces) % 20 != 0:
        raise ValueError("bad metainfo - bad pieces key")

    piece_size = info.get("piece length")
    if not isinstance(piece_size, (int, long)) or piece_size <= 0:
        raise ValueError("bad metainfo - illegal piece length")

    name = info.get("name")
    if not isinstance(name, basestring):
        raise ValueError("bad metainfo - bad name (type is %r)" % type(name).__name__)
    if not ALLOWED_ROOT_NAME.match(name):
        raise ValueError("name %s disallowed for security reasons" % name)

    if ("files" in info) == ("length" in info):
        raise ValueError("single/multiple file mix")

    if "length" in info:
        length = info.get("length")
        if not isinstance(length, (int, long)) or length < 0:
            raise ValueError("bad metainfo - bad length")
    else:
        files = info.get("files")
        if not isinstance(files, (list, tuple)):
            raise ValueError("bad metainfo - bad file list")

        for item in files:
            if not isinstance(item, dict):
                raise ValueError("bad metainfo - bad file value")

            length = item.get("length")
            if not isinstance(length, (int, long)) or length < 0:
                raise ValueError("bad metainfo - bad length")

            path = item.get("path")
            if not isinstance(path, (list, tuple)) or not path:
                raise ValueError("bad metainfo - bad path")

            for part in path:
                if not isinstance(part, basestring):
                    raise ValueError("bad metainfo - bad path dir")
                part = fmt.to_unicode(part)
                if part == '..':
                    raise ValueError("relative path in %s disallowed for security reasons" % '/'.join(path))
                if part and not ALLOWED_PATH_NAME.match(part):
                    raise ValueError("path %s disallowed for security reasons" % part)

        file_paths = [os.sep.join(item["path"]) for item in files]
        if len(set(file_paths)) != len(file_paths):
            raise ValueError("bad metainfo - duplicate path")

    return info
def check_info ( info ) : if not isinstance ( info , dict ) : raise ValueError ( "bad metainfo - not a dictionary" ) pieces = info . get ( "pieces" ) if not isinstance ( pieces , basestring ) or len ( pieces ) % 20 != 0 : raise ValueError ( "bad metainfo - bad pieces key" ) piece_size = info . get ( "piece length" ) if not isinstance ( piece_size , ( int , long ) ) or piece_size <= 0 : raise ValueError ( "bad metainfo - illegal piece length" ) name = info . get ( "name" ) if not isinstance ( name , basestring ) : raise ValueError ( "bad metainfo - bad name (type is %r)" % type ( name ) . __name__ ) if not ALLOWED_ROOT_NAME . match ( name ) : raise ValueError ( "name %s disallowed for security reasons" % name ) if ( "files" in info ) == ( "length" in info ) : raise ValueError ( "single/multiple file mix" ) if "length" in info : length = info . get ( "length" ) if not isinstance ( length , ( int , long ) ) or length < 0 : raise ValueError ( "bad metainfo - bad length" ) else : files = info . get ( "files" ) if not isinstance ( files , ( list , tuple ) ) : raise ValueError ( "bad metainfo - bad file list" ) for item in files : if not isinstance ( item , dict ) : raise ValueError ( "bad metainfo - bad file value" ) length = item . get ( "length" ) if not isinstance ( length , ( int , long ) ) or length < 0 : raise ValueError ( "bad metainfo - bad length" ) path = item . get ( "path" ) if not isinstance ( path , ( list , tuple ) ) or not path : raise ValueError ( "bad metainfo - bad path" ) for part in path : if not isinstance ( part , basestring ) : raise ValueError ( "bad metainfo - bad path dir" ) part = fmt . to_unicode ( part ) if part == '..' : raise ValueError ( "relative path in %s disallowed for security reasons" % '/' . join ( path ) ) if part and not ALLOWED_PATH_NAME . match ( part ) : raise ValueError ( "path %s disallowed for security reasons" % part ) file_paths = [ os . sep . join ( item [ "path" ] ) for item in files ] if len ( set ( file_paths ) ) != len ( file_paths ) : raise ValueError ( "bad metainfo - duplicate path" ) return info
Validate info dict.

        Raise ValueError if validation fails.