Esempio n. 1
0
ib_status_t ib_util_decode_url_ex(uint8_t *data_in,
                                  size_t dlen_in,
                                  size_t *dlen_out,
                                  ib_flags_t *result)
{
    IB_FTRACE_INIT();

    assert(data_in != NULL);
    assert(dlen_out != NULL);
    assert(result != NULL);

    uint8_t *out = data_in;
    uint8_t *in  = data_in;
    uint8_t *end = data_in + dlen_in;
    bool modified = false;

    while (in < end) {
        if (*in == '%') {
            /* Character is a percent sign. */

            /* Are there enough bytes available? */
            if (in + 2 < end) {
                char c1 = *(in + 1);
                char c2 = *(in + 2);

                if (IS_HEX_CHAR(c1) && IS_HEX_CHAR(c2)) {
                    /* Valid encoding - decode it. */
                    *out++ = x2c(in + 1);
                    in += 3;
                    modified = true;
                }
                else {
                    /* Not a valid encoding, skip this % */
                    if (in == out) {
                        ++out;
                        ++in;
                    }
                    else {
                        *out++ = *in++;
                        modified = true;
                    }
                }
            }
            else {
                /* Not enough bytes available, copy the raw bytes. */
                if (in == out) {
                    ++out;
                    ++in;
                }
                else {
                    *out++ = *in++;
                    modified = true;
                }
            }
        }
        else {
            /* Character is not a percent sign. */
            if (*in == '+') {
                *out++ = ' ';
                modified = true;
            }
            else if (out != in) {
                *out++ = *in;
                modified = true;
            }
            else {
                ++out;
            }
            ++in;
        }
    }
    *dlen_out = (out - data_in);
    *result = ( (modified == true) ?
                (IB_STRFLAG_ALIAS | IB_STRFLAG_MODIFIED) : IB_STRFLAG_ALIAS );

    IB_FTRACE_RET_STATUS(IB_OK);
}
Esempio n. 2
0
char *urldecode(const char *src, const int src_len, char *dest, int *dest_len)
{
#define IS_HEX_CHAR(ch) \
	((ch >= '0' && ch <= '9') || \
	 (ch >= 'a' && ch <= 'f') || \
	 (ch >= 'A' && ch <= 'F'))

#define HEX_VALUE(ch, value) \
	if (ch >= '0' && ch <= '9') \
	{ \
		value = ch - '0'; \
	} \
	else if (ch >= 'a' && ch <= 'f') \
	{ \
		value = ch - 'a' + 10; \
	} \
	else \
	{ \
		value = ch - 'A' + 10; \
	}

    const unsigned char *pSrc;
    const unsigned char *pEnd;
    char *pDest;
    unsigned char cHigh;
    unsigned char cLow;
    int valHigh;
    int valLow;

    pDest = dest;
    pSrc = (unsigned char *)src;
    pEnd = (unsigned char *)src + src_len;
    while (pSrc < pEnd)
    {
        if (*pSrc == '%' && pSrc + 2 < pEnd)
        {
            cHigh = *(pSrc + 1);
            cLow = *(pSrc + 2);

            if (IS_HEX_CHAR(cHigh) && IS_HEX_CHAR(cLow))
            {
                HEX_VALUE(cHigh, valHigh)
                HEX_VALUE(cLow, valLow)
                *pDest++ = (valHigh << 4) | valLow;
                pSrc += 3;
            }
            else
            {
                *pDest++ = *pSrc;
                pSrc++;
            }
        }
        else if (*pSrc == '+')
        {
            *pDest++ = ' ';
            pSrc++;
        }
        else
        {
            *pDest++ = *pSrc;
            pSrc++;
        }
    }

    *pDest = '\0';
    *dest_len = pDest - dest;

    return dest;
}
Esempio n. 3
0
ib_status_t ib_util_decode_url_cow_ex(ib_mpool_t *mp,
                                      const uint8_t *data_in,
                                      size_t dlen_in,
                                      uint8_t **data_out,
                                      size_t *dlen_out,
                                      ib_flags_t *result)
{
    IB_FTRACE_INIT();

    assert(mp != NULL);
    assert(data_in != NULL);
    assert(data_out != NULL);
    assert(dlen_out != NULL);
    assert(result != NULL);

    uint8_t *out = NULL;
    const uint8_t *in  = data_in;
    const uint8_t *end = data_in + dlen_in;
    *data_out = NULL;

    while (in < end) {
        if (*in == '%') {
            /* Character is a percent sign. */

            /* Are there enough bytes available? */
            if (in + 2 < end) {
                char c1 = *(in + 1);
                char c2 = *(in + 2);

                if (IS_HEX_CHAR(c1) && IS_HEX_CHAR(c2)) {
                    /* Valid encoding - decode it. */
                    out = ib_util_copy_on_write(mp, data_in, in, dlen_in,
                                                out, data_out, NULL);
                    if (out == NULL) {
                        IB_FTRACE_RET_STATUS(IB_EALLOC);
                    }
                    *out++ = x2c(in + 1);
                    in += 3;
                }
                else {
                    /* Not a valid encoding, skip this % */
                    if (out == NULL) {
                        ++in;
                    }
                    else {
                        *out++ = *in++;
                    }
                }
            }
            else {
                /* Not enough bytes available, copy the raw bytes. */
                if (out == NULL) {
                    ++in;
                }
                else {
                    *out++ = *in++;
                }
            }
        }
        else {
            /* Character is not a percent sign. */
            if (*in == '+') {
                out = ib_util_copy_on_write(mp, data_in, in, dlen_in,
                                            out, data_out, NULL);
                if (out == NULL) {
                    IB_FTRACE_RET_STATUS(IB_EALLOC);
                }
                *out++ = ' ';
            }
            else if (out != NULL) {
                *out++ = *in;
            }
            ++in;
        }
    }

    if (out == NULL) {
        *result = IB_STRFLAG_ALIAS;
        *data_out = (uint8_t *)data_in;
        *dlen_out = dlen_in;
    }
    else {
        *result = IB_STRFLAG_NEWBUF | IB_STRFLAG_MODIFIED;
        *dlen_out = out - *data_out;
    }

    IB_FTRACE_RET_STATUS(IB_OK);
}