Beispiel #1
0
PJ_DEF(pj_str_t) pj_str_unescape( pj_pool_t *pool, const pj_str_t *src_str)
{
    char *src = src_str->ptr;
    char *end = src + src_str->slen;
    pj_str_t dst_str;
    char *dst;
    
    if (pj_strchr(src_str, '%')==NULL)
	return *src_str;

    dst = dst_str.ptr = (char*) pj_pool_alloc(pool, src_str->slen);

    while (src != end) {
	if (*src == '%' && src < end-2 && pj_isxdigit(*(src+1)) && 
	    pj_isxdigit(*(src+2))) 
	{
	    *dst = (pj_uint8_t) ((pj_hex_digit_to_val(*(src+1)) << 4) + 
				 pj_hex_digit_to_val(*(src+2)));
	    ++dst;
	    src += 3;
	} else {
	    *dst++ = *src++;
	}
    }
    dst_str.slen = dst - dst_str.ptr;
    return dst_str;
}
Beispiel #2
0
PJ_DEF(void) pj_scan_get_unescape( pj_scanner *scanner,
				   const pj_cis_t *spec, pj_str_t *out)
{
    register char *s = scanner->curptr;
    char *dst = s;

    pj_assert(pj_cis_match(spec,0)==0);

    /* Must not match character '%' */
    pj_assert(pj_cis_match(spec,'%')==0);

    /* EOF is detected implicitly */
    if (!pj_cis_match(spec, *s) && *s != '%') {
	pj_scan_syntax_err(scanner);
	return;
    }

    out->ptr = s;
    do {
	if (*s == '%') {
	    if (s+3 <= scanner->end && pj_isxdigit(*(s+1)) && 
		pj_isxdigit(*(s+2))) 
	    {
		*dst = (pj_uint8_t) ((pj_hex_digit_to_val(*(s+1)) << 4) +
				      pj_hex_digit_to_val(*(s+2)));
		++dst;
		s += 3;
	    } else {
		*dst++ = *s++;
		*dst++ = *s++;
		break;
	    }
	}
	
	if (pj_cis_match(spec, *s)) {
	    char *start = s;
	    do {
		++s;
	    } while (pj_cis_match(spec, *s));

	    if (dst != start) pj_memmove(dst, start, s-start);
	    dst += (s-start);
	} 
	
    } while (*s == '%');

    scanner->curptr = s;
    out->slen = (dst - out->ptr);

    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
	pj_scan_skip_whitespace(scanner);    
    }
}
Beispiel #3
0
PJ_DEF(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr,
				  unsigned base)
{
    unsigned long value;
    unsigned i;

    PJ_CHECK_STACK();

    value = 0;
    if (base <= 10) {
	for (i=0; i<(unsigned)str->slen; ++i) {
	    unsigned c = (str->ptr[i] - '0');
	    if (c >= base)
		break;
	    value = value * base + c;
	}
    } else if (base == 16) {
	for (i=0; i<(unsigned)str->slen; ++i) {
	    if (!pj_isxdigit(str->ptr[i]))
		break;
	    value = value * 16 + pj_hex_digit_to_val(str->ptr[i]);
	}
    } else {
	pj_assert(!"Unsupported base");
	i = 0;
	value = 0xFFFFFFFFUL;
    }

    if (endptr) {
	endptr->ptr = str->ptr + i;
	endptr->slen = str->slen - i;
    }

    return value;
}
Beispiel #4
0
/*
 * This function converts the Internet host address ccp from the standard
 * numbers-and-dots notation into binary data and stores it in the structure
 * that inp points to. 
 */
PJ_DEF(int) pj_inet_aton(const pj_str_t *ccp, struct pj_in_addr *addr)
{
    pj_uint32_t val;
    int base, n;
    char c;
    unsigned parts[4];
    unsigned *pp = parts;
    char cp_copy[18];
    char *cp = cp_copy;
    
    addr->s_addr = PJ_INADDR_NONE;

    if (ccp->slen > 15) return 0;

    pj_memcpy(cp, ccp->ptr, ccp->slen);
    cp[ccp->slen] = '\0';

    c = *cp;
    for (;;) {
	/*
	 * Collect number up to ``.''.
	 * Values are specified as for C:
	 * 0x=hex, 0=octal, isdigit=decimal.
	 */
	if (!pj_isdigit((int)c))
	    return (0);
	val = 0; base = 10;
	if (c == '0') {
	    c = *++cp;
	    if (c == 'x' || c == 'X')
		base = 16, c = *++cp;
	    else
		base = 8;
	}

	for (;;) {
	    if (pj_isascii((int)c) && pj_isdigit((int)c)) {
		val = (val * base) + (c - '0');
		c = *++cp;
	    } else if (base==16 && pj_isascii((int)c) && pj_isxdigit((int)c)) {
		val = (val << 4) |
		      (c + 10 - (pj_islower((int)c) ? 'a' : 'A'));
		c = *++cp;
	    } else
		break;
	}

	if (c == '.') {
	    /*
	     * Internet format:
	     *  a.b.c.d
	     *  a.b.c   (with c treated as 16 bits)
	     *  a.b	(with b treated as 24 bits)
	     */
	    if (pp >= parts + 3)
		return (0);
	    *pp++ = val;
	    c = *++cp;
	} else
	    break;
    }

    /*
     * Check for trailing characters.
     */
    if (c != '\0' && (!pj_isascii((int)c) || !pj_isspace((int)c)))
        return (0);
    /*
     * Concoct the address according to
     * the number of parts specified.
     */
    n = pp - parts + 1;
    switch (n) {
    case 0:
	return (0);	    /* initial nondigit */
    case 1:		/* a -- 32 bits */
	break;
    case 2:		/* a.b -- 8.24 bits */
	if (val > 0xffffff)
	    return (0);
	val |= parts[0] << 24;
	break;
    case 3:		/* a.b.c -- 8.8.16 bits */
	if (val > 0xffff)
	    return (0);
	val |= (parts[0] << 24) | (parts[1] << 16);
	break;
    case 4:		/* a.b.c.d -- 8.8.8.8 bits */
	if (val > 0xff)
	    return (0);
	val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
	break;
    }

    if (addr)
	addr->s_addr = pj_htonl(val);
    return (1);
}
Beispiel #5
0
PJ_DEF(pj_status_t) pj_strtoul3(const pj_str_t *str, unsigned long *value,
				unsigned base)
{
    pj_str_t s;
    unsigned i;

    PJ_CHECK_STACK();

    if (!str || !value) {
        return PJ_EINVAL;
    }

    s = *str;
    pj_strltrim(&s);

    if (s.slen == 0 || s.ptr[0] < '0' ||
	(base <= 10 && (unsigned)s.ptr[0] > ('0' - 1) + base) ||
	(base == 16 && !pj_isxdigit(s.ptr[0])))
    {
        return PJ_EINVAL;
    }

    *value = 0;
    if (base <= 10) {
	for (i=0; i<(unsigned)s.slen; ++i) {
	    unsigned c = s.ptr[i] - '0';
	    if (s.ptr[i] < '0' || (unsigned)s.ptr[i] > ('0' - 1) + base) {
		break;
	    }
	    if (*value > PJ_MAXULONG / base) {
		*value = PJ_MAXULONG;
		return PJ_ETOOBIG;
	    }

	    *value *= base;
	    if ((PJ_MAXULONG - *value) < c) {
		*value = PJ_MAXULONG;
		return PJ_ETOOBIG;
	    }
	    *value += c;
	}
    } else if (base == 16) {
	for (i=0; i<(unsigned)s.slen; ++i) {
	    unsigned c = pj_hex_digit_to_val(s.ptr[i]);
	    if (!pj_isxdigit(s.ptr[i]))
		break;

	    if (*value > PJ_MAXULONG / base) {
		*value = PJ_MAXULONG;
		return PJ_ETOOBIG;
	    }
	    *value *= base;
	    if ((PJ_MAXULONG - *value) < c) {
		*value = PJ_MAXULONG;
		return PJ_ETOOBIG;
	    }
	    *value += c;
	}
    } else {
	pj_assert(!"Unsupported base");
	return PJ_EINVAL;
    }
    return PJ_SUCCESS;
}