Exemple #1
0
/**
 * Decodes a BASE64 encoded data block. Returns True if string has been 
 * successfully decoded, or False if it cannot be decoded (or memory
 * allocation fails). Does not destroy the original contents of the 
 * buffer
 */
STATIC Bool BASE64_InternalDecode(Base64Decode * decode)
{
    /* remember the original length so that we can undo the damage */
    Buffer* out = decode->out;
    size_t origLen = (out ? BUFFER_Size(out) : 0);

    /* read the bulk of the data */
    int n;
    Bool ok = True;
    I8u chunk[4];
    while ((n = BASE64_ReadChunk(decode, chunk)) == 4) {
        if (out) {
            if (!BUFFER_PutByte(out,BASE64_DECODE_1(chunk[0],chunk[1])) ||
                !BUFFER_PutByte(out,BASE64_DECODE_2(chunk[1],chunk[2])) ||
                !BUFFER_PutByte(out,BASE64_DECODE_3(chunk[2],chunk[3]))) {
                /* out of memory */
                ok = False;
                break;
            }
        }
    }

    /* deal with the trailer */
    if (out && ok) {
        switch (n) {
        case 0:
            break;
        case 1:
            /* premature end of BASE64 stream */
            decode->flags |= FLAG_ERROR;
            break;
        case 2:
            if (!BUFFER_PutByte(out,BASE64_DECODE_1(chunk[0],chunk[1]))) {
                /* out of memory */
                ok = False;
            }
            break;
        case 3:
            if (!BUFFER_PutByte(out,BASE64_DECODE_1(chunk[0],chunk[1])) ||
                !BUFFER_PutByte(out,BASE64_DECODE_2(chunk[1],chunk[2]))) {
                /* out of memory */
                ok = False;
            }
            break;
        case 4:
            if (!BUFFER_PutByte(out,BASE64_DECODE_1(chunk[0],chunk[1])) ||
                !BUFFER_PutByte(out,BASE64_DECODE_2(chunk[1],chunk[2])) ||
                !BUFFER_PutByte(out,BASE64_DECODE_3(chunk[2],chunk[3]))) {
                /* out of memory */
                ok = False;
            }
            break;
        }
    }

    /* return True if the input was a valid BASE64 sequence */
    if ((decode->flags & FLAG_ERROR) || !ok) {
        if (out) {
            BUFFER_Unput(out,BUFFER_Size(out)-origLen);
            ASSERT(BUFFER_Size(out) == (int)origLen);
        }
        return False;
    } else {
        return True;
    }
}
Exemple #2
0
/**
 * Decodes a BASE32 encoded data block. Returns True if string has been 
 * successfully decoded, or False if it cannot be decoded (or memory
 * allocation fails). Does not destroy the original contents of the 
 * buffer
 */
STATIC Bool BASE32_InternalDecode(Base32Decode * decode)
{
    /* remember the original length so that we can undo the damage */
    Buffer * out = decode->out;
    int origLen = (out ? BUFFER_Size(out) : 0);

    /* read the bulk of the data */
    int n;
    Bool ok = True;
    I8u b[DECODE_CHUNK_SIZE];
    while ((n = BASE32_ReadChunk(decode, b)) == DECODE_CHUNK_SIZE) {
        if (out) {
            if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_2(b[1],b[2],b[3])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_3(b[3],b[4])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_4(b[4],b[5],b[6])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_5(b[6],b[7]))) {
                /* out of memory */
                ok = False;
                break;
            }
        }
    }

    /*
     *   +--- octet 0 ---+--- octet 1 ---+--- octet 2 ---+
     *   |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
     *   +---------+-----+---+---------+-+-------+-------+
     *   |4 3 2 1 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 0|4 3 2 1
     *   +-0.index-+-1.index-+-2.index-+-3.index-+-4.index
     *   
     *   +--- octet 3 ---+--- octet 4 ---+
     *   |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
     *   +-+---------+---+-----+---------+
     *    0|4 3 2 1 0|4 3 2 1 0|4 3 2 1 0|
     *   --+-5.index-+-6.index-+-7.index-+
     */

    /* deal with the trailer */
    if (out && ok) {
        switch (n) {
        case 0:
            break;
        case 1:
        case 3:
        case 6:
            /* incorrect trailer */
            decode->flags |= FLAG_ERROR;
            break;
        case 2:
            if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1]))) {
                /* out of memory */
                ok = False;
            }
            break;
        case 4:
            if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_2(b[1],b[2],b[3]))) {
                /* out of memory */
                ok = False;
                return False;
            }
            break;
        case 5:
            if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_2(b[1],b[2],b[3])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_3(b[3],b[4]))) {
                /* out of memory */
                ok = False;
                return False;
            }
            break;
        case 7:
            if (!BUFFER_PutByte(out,BASE32_DECODE_1(b[0],b[1])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_2(b[1],b[2],b[3])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_3(b[3],b[4])) ||
                !BUFFER_PutByte(out,BASE32_DECODE_4(b[4],b[5],b[6]))) {
                /* out of memory */
                ok = False;
                return False;
            }
            break;
        }
    }

    /* return True if the input was a valid BASE32 sequence */
    if ((decode->flags & FLAG_ERROR) || !ok) {
        if (out) {
            BUFFER_Unput(out,BUFFER_Size(out)-origLen);
            ASSERT(BUFFER_Size(out) == origLen);
        }
        return False;
    } else {
        return True;
    }
}