TEST(chunk, decode_message)
{
	struct mbuf *mb_chunked = mbuf_alloc(1024);
	struct mbuf *mb_data = mbuf_alloc(1024);
	int err = 0;

	ASSERT_TRUE(mb_chunked != NULL);
	ASSERT_TRUE(mb_data != NULL);

	mbuf_write_str(mb_chunked, encoded_data);
	mb_chunked->pos = 0;

	/* decode all chunks */
	for (int i=0; i<16; i++) {
		uint8_t *p;
		size_t n;

		err = chunk_decode(&p, &n, mb_chunked);
		if (err)
			break;

		if (n == 0)
			break;

		err = mbuf_write_mem(mb_data, p, n);
		if (err)
			break;
	}

	ASSERT_EQ(str_len(decoded_data), mb_data->end);
	ASSERT_TRUE(0 == memcmp(decoded_data, mb_data->buf, mb_data->end));

	mem_deref(mb_chunked);
	mem_deref(mb_data);
}
TEST(chunk, decode_invalid_header)
{
	struct mbuf *mb = mbuf_alloc(1024);
	int err = 0;

	mbuf_write_str(mb, "alfred\r\n");
	mb->pos = 0;

	err = chunk_decode(NULL, NULL, mb);
	ASSERT_EQ(EBADMSG, err);

	mem_deref(mb);
}
TEST(chunk, decode_incomplete_header)
{
	struct mbuf *mb = mbuf_alloc(1024);
	int err = 0;

	mbuf_write_str(mb, "c8"); /* the CRLF is missing here */
	mb->pos = 0;

	err = chunk_decode(NULL, NULL, mb);
	ASSERT_EQ(EBADMSG, err);

	mem_deref(mb);
}
TEST(chunk, decode_too_short)
{
	struct mbuf *mb_chunked = mbuf_alloc(1024);
	int err = 0;

	mbuf_write_str(mb_chunked, "3\r\nab");
	mb_chunked->pos = 0;

	err = chunk_decode(NULL, NULL, mb_chunked);
	ASSERT_EQ(EBADMSG, err);

	mem_deref(mb_chunked);
}
Example #5
0
File: b64.c Project: insertion/libu
/**
 *  \brief  Decode Base64 encoded string to binary data
 *
 *  Decode Base64 encoded string \p in to binary data \p out
 *
 *  \param  in      Reference to a Base64 encoded string
 *  \param  in_sz   length of \p in in bytes (excluding the terminating \c NUL)
 *  \param  out     Pre-allocated buffer of size approx as \p in_sz
 *  \param  out_sz  Value-result argument initially containing the total
 *                  size of \p out in bytes.  On successful return it
 *                  holds the decoded buffer size.
 *
 *  \retval  0  on success
 *  \retval ~0  on failure
 */
int u_b64_decode (const char *in, size_t in_sz, uint8_t *out, size_t *out_sz)
{
    char buf[4];
    size_t i, len, pad, tot_sz = *out_sz;
    uint8_t *pout;

    dbg_return_if (in == NULL, ~0);
    dbg_return_if (in_sz == 0, ~0);
    dbg_return_if (out == NULL, ~0);
    dbg_return_if (out_sz == NULL, ~0);

    for (pout = out; in_sz; )
    {
        for (pad = 0, len = 0, i = 0; i < 4; ++i)
        {
            if (in_sz && in_sz-- > 0)   /* Avoid wrapping around in_sz. */
            {
                buf[i] = *in++;

                if (buf[i] == '=')
                    ++pad;
                else if (!is_base64(buf[i]))
                    return ~0;

                ++len;
            }
            else
                buf[i] = '\0';
        }

        if (len)
        {
            size_t nlen = 3 - pad;

            if (tot_sz >= nlen)
            {
                chunk_decode(buf, pout);
                tot_sz -= nlen; /* Take care of subtracting pad bytes. */
                pout += nlen;
            }
            else
                return ~0;  /* Not enough space. */
        }
    }

    *out_sz -= tot_sz;

    return 0;
}
Example #6
0
int wav_header_decode(struct wav_fmt *fmt, size_t *datasize, FILE *f)
{
	struct wav_chunk header, format, chunk;
	uint8_t rifftype[4];        /* "WAVE" */
	int err = 0;

	err = chunk_decode(&header, f);
	if (err)
		return err;

	if (memcmp(header.id, "RIFF", 4)) {
		(void)re_fprintf(stderr, "aufile: expected RIFF (%b)\n",
				 header.id, 4);
		return EBADMSG;
	}

	if (1 != fread(rifftype, sizeof(rifftype), 1, f))
		return ferror(f);

	if (memcmp(rifftype, "WAVE", 4)) {
		(void)re_fprintf(stderr, "aufile: expected WAVE (%b)\n",
				 rifftype, 4);
		return EBADMSG;
	}

	err = chunk_decode(&format, f);
	if (err)
		return err;

	if (memcmp(format.id, "fmt ", 4)) {
		(void)re_fprintf(stderr, "aufile: expected fmt (%b)\n",
				 format.id, 4);
		return EBADMSG;
	}

	if (format.size < WAVE_FMT_SIZE)
		return EBADMSG;

	err  = read_u16(f, &fmt->format);
	err |= read_u16(f, &fmt->channels);
	err |= read_u32(f, &fmt->srate);
	err |= read_u32(f, &fmt->byterate);
	err |= read_u16(f, &fmt->block_align);
	err |= read_u16(f, &fmt->bps);
	if (err)
		return err;

	/* skip any extra bytes */
	if (format.size >= (WAVE_FMT_SIZE + 2)) {

		err = read_u16(f, &fmt->extra);
		if (err)
			return err;

		if (fmt->extra > 0) {
			if (fseek(f, fmt->extra, SEEK_CUR))
				return errno;
		}
	}

	/* fast forward to "data" chunk */
	for (;;) {

		err = chunk_decode(&chunk, f);
		if (err)
			return err;

		if (chunk.size > header.size) {
			(void)re_fprintf(stderr, "chunk size too large"
					 " (%u > %u)\n",
					 chunk.size, header.size);
			return EBADMSG;
		}

		if (0 == memcmp(chunk.id, "data", 4)) {
			*datasize = chunk.size;
			break;
		}

		if (fseek(f, chunk.size, SEEK_CUR) < 0)
			return errno;
	}

	return 0;
}