Пример #1
0
def rledecode_hqx(space, hexbin):
    "Decode hexbin RLE-coded string."

    # that's a guesstimation of the resulting length
    res = StringBuilder(len(hexbin))

    end = len(hexbin)
    i = 0
    lastpushed = -1
    while i < end:
        c = hexbin[i]
        i += 1
        if c != '\x90':
            res.append(c)
            lastpushed = ord(c)
        else:
            if i == end:
                raise_Incomplete(space, 'String ends with the RLE code \x90')
            count = ord(hexbin[i]) - 1
            i += 1
            if count < 0:
                res.append('\x90')
                lastpushed = 0x90
            else:
                if lastpushed < 0:
                    raise_Error(space, 'String starts with the RLE code \x90')
                res.append_multiple_char(chr(lastpushed), count)
    return space.wrap(res.build())
Пример #2
0
def a2b_hqx(space, ascii):
    """Decode .hqx coding.  Returns (bin, done)."""

    # overestimate the resulting length
    res = StringBuilder(len(ascii))
    done = 0
    pending_value = 0
    pending_bits = 0

    for c in ascii:
        n = ord(table_a2b_hqx[ord(c)])
        if n <= 0x3F:
            pending_value = (pending_value << 6) | n
            pending_bits += 6
            if pending_bits == 24:
                # flush
                res.append(chr(pending_value >> 16))
                res.append(chr((pending_value >> 8) & 0xff))
                res.append(chr(pending_value & 0xff))
                pending_value = 0
                pending_bits = 0
        elif n == FAIL:
            raise_Error(space, 'Illegal character')
        elif n == DONE:
            if pending_bits >= 8:
                res.append(chr(pending_value >> (pending_bits - 8)))
            if pending_bits >= 16:
                res.append(chr((pending_value >> (pending_bits - 16)) & 0xff))
            done = 1
            break
        #elif n == SKIP: pass
    else:
        if pending_bits > 0:
            raise_Incomplete(space, 'String has incomplete number of bytes')
    return space.newtuple([space.wrap(res.build()), space.wrap(done)])
Пример #3
0
def _a2b_write(space, res, length, char):
    if res.getlength() < length:  # common case: we have enough room.
        res.append(chr(char))
    else:
        # overflows.  Only accept zeros from now on.
        if char != 0:
            raise_Error(space, "Trailing garbage")
Пример #4
0
def _a2b_write(space, res, length, char):
    if res.getlength() < length:  # common case: we have enough room.
        res.append(chr(char))
    else:
        # overflows.  Only accept zeros from now on.
        if char != 0:
            raise_Error(space, "Trailing garbage")
Пример #5
0
def _char2value(space, c):
    if c <= '9':
        if c >= '0':
            return ord(c) - ord('0')
    elif c <= 'F':
        if c >= 'A':
            return ord(c) - (ord('A') - 10)
    elif c <= 'f':
        if c >= 'a':
            return ord(c) - (ord('a') - 10)
    raise_Error(space, 'Non-hexadecimal digit found')
Пример #6
0
def unhexlify(space, hexstr):
    '''Binary data of hexadecimal representation.
hexstr must contain an even number of hex digits (upper or lower case).
This function is also available as "unhexlify()".'''
    if len(hexstr) & 1:
        raise_Error(space, 'Odd-length string')
    res = StringBuilder(len(hexstr) >> 1)
    for i in range(0, len(hexstr), 2):
        a = _char2value(space, hexstr[i])
        b = _char2value(space, hexstr[i + 1])
        res.append(chr((a << 4) | b))
    return space.newbytes(res.build())
Пример #7
0
def _a2b_read(space, s, index):
    try:
        c = s[index]
    except IndexError:
        return 0
    # Check the character for legality.  The 64 instead of the expected 63
    # is because there are a few uuencodes out there that use '`' as zero
    # instead of space.
    if c < " " or c > chr(32 + 64):
        if c == "\n" or c == "\r":
            return 0
        raise_Error(space, "Illegal char")
    return (ord(c) - 0x20) & 0x3F
Пример #8
0
def _a2b_read(space, s, index):
    try:
        c = s[index]
    except IndexError:
        return 0
    # Check the character for legality.  The 64 instead of the expected 63
    # is because there are a few uuencodes out there that use '`' as zero
    # instead of space.
    if c < ' ' or c > chr(32 + 64):
        if c == '\n' or c == '\r':
            return 0
        raise_Error(space, "Illegal char")
    return (ord(c) - 0x20) & 0x3f
Пример #9
0
def a2b_base64(space, ascii):
    "Decode a line of base64 data."

    res = StringBuilder((len(ascii) // 4) * 3)  # maximum estimate
    quad_pos = 0
    leftchar = 0
    leftbits = 0
    last_char_was_a_pad = False
    bin_used = 0

    for c in ascii:
        if c == PAD:
            if quad_pos > 2 or (quad_pos == 2 and last_char_was_a_pad):
                break  # stop on 'xxx=' or on 'xx=='
            last_char_was_a_pad = True
        else:
            n = ord(table_a2b_base64[ord(c)])
            if n == 0xff:
                continue  # ignore strange characters
            #
            # Shift it in on the low end, and see if there's
            # a byte ready for output.
            quad_pos = (quad_pos + 1) & 3
            leftchar = (leftchar << 6) | n
            leftbits += 6
            #
            if leftbits >= 8:
                leftbits -= 8
                res.append(chr(leftchar >> leftbits))
                leftchar &= ((1 << leftbits) - 1)
                bin_used += 1
            #
            last_char_was_a_pad = False
    else:
        if leftbits != 0:
            if leftbits == 6:
                # There is exactly one extra valid, non-padding, base64 character.
                # This is an invalid length, as there is no possible input that
                # could encoded into such a base64 string.
                msg = (
                    "Invalid base64-encoded string: number of data "
                    "characters (%d) cannot be 1 more than a multiple of 4" %
                    ((bin_used // 3) * 4 + 1))
                raise_Error(space, msg)
            raise_Error(space, "Incorrect padding")

    return space.newbytes(res.build())
Пример #10
0
def b2a_uu(space, bin):
    "Uuencode a line of data."

    length = len(bin)
    if length > 45:
        raise_Error(space, "At most 45 bytes at once")
    res = StringBuilder(2 + ((length + 2) // 3) * 4)
    res.append(chr(0x20 + length))

    for i in range(0, length, 3):
        A = _b2a_read(bin, i)
        B = _b2a_read(bin, i + 1)
        C = _b2a_read(bin, i + 2)
        #
        res.append(chr(0x20 + (A >> 2)))
        res.append(chr(0x20 + ((A & 0x3) << 4 | B >> 4)))
        res.append(chr(0x20 + ((B & 0xF) << 2 | C >> 6)))
        res.append(chr(0x20 + (C & 0x3F)))

    res.append("\n")
    return space.wrap(res.build())
Пример #11
0
def b2a_uu(space, bin):
    "Uuencode a line of data."

    length = len(bin)
    if length > 45:
        raise_Error(space, 'At most 45 bytes at once')
    res = StringBuilder(2 + ((length + 2) // 3) * 4)
    res.append(chr(0x20 + length))

    for i in range(0, length, 3):
        A = _b2a_read(bin, i)
        B = _b2a_read(bin, i + 1)
        C = _b2a_read(bin, i + 2)
        #
        res.append(chr(0x20 + (A >> 2)))
        res.append(chr(0x20 + ((A & 0x3) << 4 | B >> 4)))
        res.append(chr(0x20 + ((B & 0xF) << 2 | C >> 6)))
        res.append(chr(0x20 + (C & 0x3F)))

    res.append('\n')
    return space.wrap(res.build())
Пример #12
0
def b2a_uu(space, bin, __kwonly__, backtick=False):
    "Uuencode a line of data."

    length = len(bin)
    if length > 45:
        raise_Error(space, 'At most 45 bytes at once')
    res = StringBuilder(2 + ((length + 2) // 3) * 4)
    _b2a_write(res, length, backtick)

    for i in range(0, length, 3):
        A = _b2a_read(bin, i)
        B = _b2a_read(bin, i + 1)
        C = _b2a_read(bin, i + 2)
        #
        _b2a_write(res, A >> 2, backtick)
        _b2a_write(res, (A & 0x3) << 4 | B >> 4, backtick)
        _b2a_write(res, (B & 0xF) << 2 | C >> 6, backtick)
        _b2a_write(res, C & 0x3F, backtick)

    res.append('\n')
    return space.newbytes(res.build())
Пример #13
0
def a2b_uu(space, ascii):
    "Decode a line of uuencoded data."

    if len(ascii) == 0:  # obscure case, for compability with CPython
        length = (-0x20) & 0x3F
    else:
        length = (ord(ascii[0]) - 0x20) & 0x3F
    res = StringBuilder(length)

    for i in range(1, len(ascii), 4):
        A = _a2b_read(space, ascii, i)
        B = _a2b_read(space, ascii, i + 1)
        C = _a2b_read(space, ascii, i + 2)
        D = _a2b_read(space, ascii, i + 3)
        #
        if res.getlength() < length:
            res.append(chr(A << 2 | B >> 4))
        elif A != 0 or B != 0:
            raise_Error(space, "Trailing garbage")
        #
        if res.getlength() < length:
            res.append(chr((B & 0xF) << 4 | C >> 2))
        elif C != 0:
            raise_Error(space, "Trailing garbage")
        #
        if res.getlength() < length:
            res.append(chr((C & 0x3) << 6 | D))
        elif D != 0:
            raise_Error(space, "Trailing garbage")

    remaining = length - res.getlength()
    if remaining > 0:
        res.append_multiple_char("\x00", remaining)
    return space.wrap(res.build())
Пример #14
0
def a2b_uu(space, ascii):
    "Decode a line of uuencoded data."

    if len(ascii) == 0:  # obscure case, for compability with CPython
        length = (-0x20) & 0x3f
    else:
        length = (ord(ascii[0]) - 0x20) & 0x3f
    res = StringBuilder(length)

    for i in range(1, len(ascii), 4):
        A = _a2b_read(space, ascii, i)
        B = _a2b_read(space, ascii, i + 1)
        C = _a2b_read(space, ascii, i + 2)
        D = _a2b_read(space, ascii, i + 3)
        #
        if res.getlength() < length:
            res.append(chr(A << 2 | B >> 4))
        elif A != 0 or B != 0:
            raise_Error(space, "Trailing garbage")
        #
        if res.getlength() < length:
            res.append(chr((B & 0xf) << 4 | C >> 2))
        elif C != 0:
            raise_Error(space, "Trailing garbage")
        #
        if res.getlength() < length:
            res.append(chr((C & 0x3) << 6 | D))
        elif D != 0:
            raise_Error(space, "Trailing garbage")

    remaining = length - res.getlength()
    if remaining > 0:
        res.append_multiple_char('\x00', remaining)
    return space.wrap(res.build())
Пример #15
0
def a2b_base64(space, ascii):
    "Decode a line of base64 data."

    res = StringBuilder((len(ascii) // 4) * 3)  # maximum estimate
    quad_pos = 0
    leftchar = 0
    leftbits = 0
    last_char_was_a_pad = False

    for c in ascii:
        if c == PAD:
            if quad_pos > 2 or (quad_pos == 2 and last_char_was_a_pad):
                break  # stop on 'xxx=' or on 'xx=='
            last_char_was_a_pad = True
        else:
            n = ord(table_a2b_base64[ord(c)])
            if n == 0xff:
                continue  # ignore strange characters
            #
            # Shift it in on the low end, and see if there's
            # a byte ready for output.
            quad_pos = (quad_pos + 1) & 3
            leftchar = (leftchar << 6) | n
            leftbits += 6
            #
            if leftbits >= 8:
                leftbits -= 8
                res.append(chr(leftchar >> leftbits))
                leftchar &= ((1 << leftbits) - 1)
            #
            last_char_was_a_pad = False
    else:
        if leftbits != 0:
            raise_Error(space, "Incorrect padding")

    return space.wrapbytes(res.build())
Пример #16
0
def a2b_base64(space, ascii):
    "Decode a line of base64 data."

    res = StringBuilder((len(ascii) // 4) * 3)   # maximum estimate
    quad_pos = 0
    leftchar = 0
    leftbits = 0
    last_char_was_a_pad = False

    for c in ascii:
        if c == PAD:
            if quad_pos > 2 or (quad_pos == 2 and last_char_was_a_pad):
                break      # stop on 'xxx=' or on 'xx=='
            last_char_was_a_pad = True
        else:
            n = ord(table_a2b_base64[ord(c)])
            if n == 0xff:
                continue    # ignore strange characters
            #
            # Shift it in on the low end, and see if there's
            # a byte ready for output.
            quad_pos = (quad_pos + 1) & 3
            leftchar = (leftchar << 6) | n
            leftbits += 6
            #
            if leftbits >= 8:
                leftbits -= 8
                res.append(chr(leftchar >> leftbits))
                leftchar &= ((1 << leftbits) - 1)
            #
            last_char_was_a_pad = False
    else:
        if leftbits != 0:
            raise_Error(space, "Incorrect padding")

    return space.wrap(res.build())