Beispiel #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;
    }
}
Beispiel #2
0
/*****************************************************************************
 * FUNCTION
 *  applib_base64_part_decode_append
 * DESCRIPTION
 *  This function accepts next part of source data; 
 *  decode them from BASE64 format
 * PARAMETERS
 *  cntx        [IN]        point to the applib_base64_part_context
 *  src         [IN]        pointer to the input buffer
 *  srcl        [IN]        length of the input buffer
 *  dest        [IN/OUT]    pointer to the output buffer
 *  destl       [IN]        length of the output buffer
 * RETURNS
 *  negative:   Invalid paramter.
 *  ow: the number of bytes written to output buffer.
 *****************************************************************************/
kal_int32 applib_base64_part_decode_append(
            applib_base64_part_context* cntx,
            const kal_char *src,
            kal_int32 *srcl,
            kal_char *dst,
            kal_int32 dstl)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_char  c;
    kal_int32 i_input,i_output;
    
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (cntx == NULL || 
        (cntx->finish_flag && cntx->buf_cnt > 4) ||
        (!cntx->finish_flag && cntx->buf_cnt > 3) ||
        srcl == NULL || 
        (*srcl > 0 && src == NULL))
    {
        BASE64_ASSERT(0);
        return -1;
    }
    
    if (cntx->finish_flag)
    {
        /* the "=" had been reached before */
        if (!cntx->illpad_flag)
        {
            check_illegal_pad(cntx,src,*srcl);
        }
        
        return 0;
    }
    
    /* 
    * begin decode this part content 
    * Skip all NOT BASE64 CHARACTER
    * End the decode if '=' was founded.
    */
    i_input = i_output = 0;
    while(i_input < *srcl)
    {
        /* assert check */
        BASE64_ASSERT(cntx->buf_cnt <= 3);

        c = BASE64_DECODE_TABLE[(kal_uint8)(src[i_input++])];

        if (c == DWSP)
        {
            continue;
        }
        else if (c == DNIL)
        {
            cntx->illchr_flag = 1;
            continue;
        }
        else if (c == DPAD)
        {
            cntx->finish_flag = 1;
            if (cntx->buf_cnt < 2)
            {
                BASE64_WARING();
                cntx->illpad_flag = 1;
                break;
            }

            if (i_output + cntx->buf_cnt - 1 > dstl)
            {
                /* output buffer is NOT enough */
                /* roll back */
                cntx->finish_flag = 0;
                i_input--;
                break;
            }
            
            if (cntx->buf_cnt == 2)
            {
                BASE64_DECODE_2((dst+i_output),cntx->buf);
            }
            else
            {
                BASE64_DECODE_3((dst+i_output),cntx->buf);
            }
            i_output += cntx->buf_cnt - 1;
            cntx->buf[cntx->buf_cnt++] = c;

            check_illegal_pad(cntx,src+i_input,*srcl-i_input);
            i_input = *srcl; /* all data have been processed */
            break;
        }
        else
        {
            /* Decode the bytes upto 4-group */
            cntx->buf[cntx->buf_cnt++] = c;

            /* four bytes readed,DECODE IT */
            if (cntx->buf_cnt < 4)
            {
                continue;
            }           
            
            if (i_output + 3 > dstl)
            {
                /* roll back */
                cntx->buf_cnt--;
                i_input--;
                break;
            }

            BASE64_DECODE_4((dst+i_output),cntx->buf);
            i_output += 3;
            cntx->buf_cnt = 0;
        }
        
        /* assert check */
        BASE64_ASSERT(cntx->buf_cnt <= 3);
    }

    if (*srcl != i_input)
    {
        /* warning */
        BASE64_WARING();
    }
    
    *srcl = i_input;
    return i_output;
}