Exemple #1
0
pjsip_hdr* parse_hdr_session_expires(pjsip_parse_ctx* ctx)
{
  pj_pool_t* pool = ctx->pool;
  pj_scanner* scanner = ctx->scanner;
  pjsip_session_expires_hdr* hdr = pjsip_session_expires_hdr_create(pool);
  const pjsip_parser_const_t* pc = pjsip_parser_const();

  // Parse the expiry number
  pj_str_t int_str;
  pj_scan_get(scanner, &pc->pjsip_DIGIT_SPEC, &int_str);
  hdr->expires = pj_strtoul(&int_str);
  pj_scan_skip_whitespace(scanner);

  // Parse the rest of the params, looking for the refresher param
  while (*scanner->curptr == ';')
  {
    // Consume the ';'.
    pj_scan_get_char(scanner);
    pj_scan_skip_whitespace(scanner);

    // Parse the param.
    pj_str_t name;
    pj_str_t value;
    pjsip_parse_param_imp(scanner, pool, &name, &value,
                          PJSIP_PARSE_REMOVE_QUOTE);
    if (!pj_stricmp2(&name, "refresher"))
    {
      if (!pj_stricmp2(&value, "uac"))
      {
        hdr->refresher = SESSION_REFRESHER_UAC;
      }
      else if (!pj_stricmp2(&value, "uas"))
      {
        hdr->refresher = SESSION_REFRESHER_UAS;
      }
      else
      {
        PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); // LCOV_EXCL_LINE
      }
    }
    else
    {
      pjsip_param* param = PJ_POOL_ALLOC_T(pool, pjsip_param);
      param->name = name;
      param->value = value;
      pj_list_insert_before(&hdr->other_param, param);
    }
  }

  // We're done parsing this header.
  pjsip_parse_end_hdr_imp(scanner);

  return (pjsip_hdr*)hdr;
}
Exemple #2
0
PJ_DEF(void) pj_scan_get( pj_scanner *scanner,
			  const pj_cis_t *spec, pj_str_t *out)
{
    register char *s = scanner->curptr;

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

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

    do {
	++s;
    } while (pj_cis_match(spec, *s));
    /* No need to check EOF here (PJ_SCAN_CHECK_EOF(s)) because
     * buffer is NULL terminated and pj_cis_match(spec,0) should be
     * false.
     */

    pj_strset3(out, scanner->curptr, s);

    scanner->curptr = s;

    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
	pj_scan_skip_whitespace(scanner);    
    }
}
Exemple #3
0
pjsip_hdr* parse_hdr_p_charging_function_addresses(pjsip_parse_ctx* ctx)
{
  // The P-Charging-Function-Addresses header has the following ABNF:
  //
  // P-Charging-Addr        = "P-Charging-Function-Addresses" HCOLON
  //                          charge-addr-params
  //                          *(SEMI charge-addr-params)
  // charge-addr-params     = ccf / ecf / generic-param
  // ccf                    = "ccf" EQUAL gen-value
  // ecf                    = "ecf" EQUAL gen-value
  //
  // Where the ccf and ecf elements may be repeated to specify backup CDFs
  // for redundancy.

  pj_pool_t* pool = ctx->pool;
  pj_scanner* scanner = ctx->scanner;
  pjsip_p_c_f_a_hdr* hdr = pjsip_p_c_f_a_hdr_create(pool);
  pj_str_t name;
  pj_str_t value;
  pjsip_param *param;

  for (;;) {
    pjsip_parse_param_imp(scanner, pool, &name, &value,
                          PJSIP_PARSE_REMOVE_QUOTE);
    param = PJ_POOL_ALLOC_T(pool, pjsip_param);
    param->name = name;
    param->value = value;
    if (!pj_stricmp2(&name, "ccf")) {
      pj_list_insert_before(&hdr->ccf, param);
    } else if (!pj_stricmp2(&name, "ecf")) {
      pj_list_insert_before(&hdr->ecf, param);
    } else {
      pj_list_insert_before(&hdr->other_param, param);
    }

    // We might need to swallow the ';'.
    if (!pj_scan_is_eof(scanner) && *scanner->curptr == ';') {
      pj_scan_get_char(scanner);
    }

    // If we're EOF or looking at a newline, we're done.
    pj_scan_skip_whitespace(scanner);
    if (pj_scan_is_eof(scanner) ||
        (*scanner->curptr == '\r') ||
        (*scanner->curptr == '\n')) {
      break;
    }
  }

  // We're done parsing this header.
  pjsip_parse_end_hdr_imp(scanner);

  return (pjsip_hdr*)hdr;
}
Exemple #4
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);    
    }
}
Exemple #5
0
pjsip_hdr* parse_hdr_reject_contact(pjsip_parse_ctx* ctx)
{
  // The Reject-Contact header has the following ABNF:
  //
  // Reject-Contact  =  ("Reject-Contact" / "j") HCOLON rc-value
  //                       *(COMMA rc-value)
  // rc-value        =  "*" *(SEMI rc-params)
  // rc-params       =  feature-param / generic-param
  //
  // But we allow any value for the header (not just *).

  pj_pool_t* pool = ctx->pool;
  pj_scanner* scanner = ctx->scanner;
  const pjsip_parser_const_t* pc = pjsip_parser_const();
  pjsip_reject_contact_hdr* hdr = pjsip_reject_contact_hdr_create(pool);
  pj_str_t name;
  pj_str_t value;
  pjsip_param *param;

  // Read and ignore the value.
  pj_str_t header_value;
  pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &header_value);

  for (;;)
  {
    // We might need to swallow the ';'.
    if (!pj_scan_is_eof(scanner) && *scanner->curptr == ';')
    {
      pj_scan_get_char(scanner);
    }

    pjsip_parse_param_imp(scanner, pool, &name, &value, 0);
    param = PJ_POOL_ALLOC_T(pool, pjsip_param);
    param->name = name;
    param->value = value;
    pj_list_insert_before(&hdr->feature_set, param);

    // If we're EOF or looking at a newline, we're done.
    pj_scan_skip_whitespace(scanner);
    if (pj_scan_is_eof(scanner) ||
        (*scanner->curptr == '\r') ||
        (*scanner->curptr == '\n'))
    {
      break;
    }
  }

  // We're done parsing this header.
  pjsip_parse_end_hdr_imp(scanner);

  return (pjsip_hdr*)hdr;
}
Exemple #6
0
PJ_DEF(void) pj_scan_advance_n( pj_scanner *scanner,
				 unsigned N, pj_bool_t skip_ws)
{
    if (scanner->curptr + N > scanner->end) {
	pj_scan_syntax_err(scanner);
	return;
    }

    scanner->curptr += N;

    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) {
	pj_scan_skip_whitespace(scanner);
    }
}
Exemple #7
0
PJ_DEF(void) pj_scan_init( pj_scanner *scanner, char *bufstart, int buflen, 
			   unsigned options, pj_syn_err_func_ptr callback )
{
    PJ_CHECK_STACK();

    scanner->begin = scanner->curptr = bufstart;
    scanner->end = bufstart + buflen;
    scanner->line = 1;
    scanner->start_line = scanner->begin;
    scanner->callback = callback;
    scanner->skip_ws = options;

    if (scanner->skip_ws) 
	pj_scan_skip_whitespace(scanner);
}
Exemple #8
0
PJ_DEF(int) pj_scan_get_char( pj_scanner *scanner )
{
    int chr = *scanner->curptr;

    if (!chr) {
	pj_scan_syntax_err(scanner);
	return 0;
    }

    ++scanner->curptr;

    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
	pj_scan_skip_whitespace(scanner);
    }
    return chr;
}
Exemple #9
0
PJ_DEF(void) pj_scan_get_n( pj_scanner *scanner,
			    unsigned N, pj_str_t *out)
{
    if (scanner->curptr + N > scanner->end) {
	pj_scan_syntax_err(scanner);
	return;
    }

    pj_strset(out, scanner->curptr, N);
    
    scanner->curptr += N;

    if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
	pj_scan_skip_whitespace(scanner);
    }
}
Exemple #10
0
PJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner, 
				   int until_char, pj_str_t *out)
{
    register char *s = scanner->curptr;

    if (s >= scanner->end) {
	pj_scan_syntax_err(scanner);
	return;
    }

    while (PJ_SCAN_CHECK_EOF(s) && *s != until_char) {
	++s;
    }

    pj_strset3(out, scanner->curptr, s);

    scanner->curptr = s;

    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
	pj_scan_skip_whitespace(scanner);
    }
}
Exemple #11
0
PJ_DEF(void) pj_scan_get_until( pj_scanner *scanner,
				const pj_cis_t *spec, pj_str_t *out)
{
    register char *s = scanner->curptr;

    if (s >= scanner->end) {
	pj_scan_syntax_err(scanner);
	return;
    }

    while (PJ_SCAN_CHECK_EOF(s) && !pj_cis_match(spec, *s)) {
	++s;
    }

    pj_strset3(out, scanner->curptr, s);

    scanner->curptr = s;

    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
	pj_scan_skip_whitespace(scanner);
    }
}
Exemple #12
0
PJ_DEF(void) pj_scan_get_until_chr( pj_scanner *scanner,
				     const char *until_spec, pj_str_t *out)
{
    register char *s = scanner->curptr;
    pj_size_t speclen;

    if (s >= scanner->end) {
	pj_scan_syntax_err(scanner);
	return;
    }

    speclen = strlen(until_spec);
    while (PJ_SCAN_CHECK_EOF(s) && !memchr(until_spec, *s, speclen)) {
	++s;
    }

    pj_strset3(out, scanner->curptr, s);

    scanner->curptr = s;

    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
	pj_scan_skip_whitespace(scanner);
    }
}
Exemple #13
0
pjsip_hdr* parse_hdr_p_charging_vector(pjsip_parse_ctx* ctx)
{
  // The P-Charging-Vector header has the following ABNF:
  //
  // P-Charging-Vector     = "P-Charging-Vector" HCOLON icid-value
  //                         *(SEMI charge-params)
  // charge-params         = icid-gen-addr / orig-ioi /
  //                         term-ioi / generic-param
  // icid-value            = "icid-value" EQUAL gen-value
  // icid-gen-addr         = "icid-generated-at" EQUAL host
  // orig-ioi              = "orig-ioi" EQUAL gen-value
  // term-ioi              = "term-ioi" EQUAL gen-value

  pj_pool_t* pool = ctx->pool;
  pj_scanner* scanner = ctx->scanner;
  pjsip_p_c_v_hdr* hdr = pjsip_p_c_v_hdr_create(pool);
  pj_str_t name;
  pj_str_t value;

  // Parse the required icid-value parameter first.
  pjsip_parse_param_imp(scanner, pool, &name, &value,
                        PJSIP_PARSE_REMOVE_QUOTE);

  if (!pj_stricmp2(&name, "icid-value")) {
    hdr->icid = value;
  } else {
    PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); // LCOV_EXCL_LINE
  }

  for (;;) {
    pj_scan_skip_whitespace(scanner);

    // If we just parsed the last parameter we will have reached the end of the
    // header and have nothing more to do.
    if (pj_scan_is_eof(scanner) ||
        (*scanner->curptr == '\r') ||
        (*scanner->curptr == '\n')) {
      break;
    }

    // There's more content in the header so the next character must be the ";"
    // separator.
    if (*scanner->curptr == ';') {
      pj_scan_get_char(scanner);
    } else {
      PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); // LCOV_EXCL_LINE
    }

    pjsip_parse_param_imp(scanner, pool, &name, &value,
                          PJSIP_PARSE_REMOVE_QUOTE);

    if (!pj_stricmp2(&name, "orig-ioi")) {
      hdr->orig_ioi = value;
    } else if (!pj_stricmp2(&name, "term-ioi")) {
      hdr->term_ioi = value;
    } else if (!pj_stricmp2(&name, "icid-generated-at")) {
      hdr->icid_gen_addr = value;
    } else {
      pjsip_param *param = PJ_POOL_ALLOC_T(pool, pjsip_param);
      param->name = name;
      param->value = value;
      pj_list_insert_before(&hdr->other_param, param);
    }
  }

  // We're done parsing this header.
  pjsip_parse_end_hdr_imp(scanner);

  return (pjsip_hdr*)hdr;
}
Exemple #14
0
PJ_DEF(void) pj_scan_get_quotes(pj_scanner *scanner,
                                const char *begin_quote, const char *end_quote,
                                int qsize, pj_str_t *out)
{
    register char *s = scanner->curptr;
    int qpair = -1;
    int i;

    pj_assert(qsize > 0);

    /* Check and eat the begin_quote. */
    for (i = 0; i < qsize; ++i) {
	if (*s == begin_quote[i]) {
	    qpair = i;
	    break;
	}
    }
    if (qpair == -1) {
	pj_scan_syntax_err(scanner);
	return;
    }
    ++s;

    /* Loop until end_quote is found. 
     */
    do {
	/* loop until end_quote is found. */
	while (PJ_SCAN_CHECK_EOF(s) && *s != '\n' && *s != end_quote[qpair]) {
	    ++s;
	}

	/* check that no backslash character precedes the end_quote. */
	if (*s == end_quote[qpair]) {
	    if (*(s-1) == '\\') {
		char *q = s-2;
		char *r = s-2;

		while (r != scanner->begin && *r == '\\') {
		    --r;
		}
		/* break from main loop if we have odd number of backslashes */
		if (((unsigned)(q-r) & 0x01) == 1) {
		    break;
		}
		++s;
	    } else {
		/* end_quote is not preceeded by backslash. break now. */
		break;
	    }
	} else {
	    /* loop ended by non-end_quote character. break now. */
	    break;
	}
    } while (1);

    /* Check and eat the end quote. */
    if (*s != end_quote[qpair]) {
	pj_scan_syntax_err(scanner);
	return;
    }
    ++s;

    pj_strset3(out, scanner->curptr, s);

    scanner->curptr = s;

    if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
	pj_scan_skip_whitespace(scanner);
    }
}
Exemple #15
0
/* Parse tel: URI 
 * THis actually returns (pjsip_tel_uri *) type.
 */
static void* tel_uri_parse( pj_scanner *scanner, pj_pool_t *pool,
			    pj_bool_t parse_params)
{
    pjsip_tel_uri *uri;
    pj_str_t token;
    int skip_ws = scanner->skip_ws;
    const pjsip_parser_const_t *pc = pjsip_parser_const();

    scanner->skip_ws = 0;

    /* Parse scheme. */
    pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &token);
    if (pj_scan_get_char(scanner) != ':')
	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
    if (pj_stricmp_alnum(&token, &pc->pjsip_TEL_STR) != 0)
	PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);

    /* Create URI */
    uri = pjsip_tel_uri_create(pool);

    /* Get the phone number. */
#if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0
    pj_scan_get_unescape(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number);
#else
    pj_scan_get(scanner, &pjsip_TEL_NUMBER_SPEC, &uri->number);
    uri->number = pj_str_unescape(pool, &uri->number);
#endif

    /* Get all parameters. */
    if (parse_params && *scanner->curptr==';') {
	pj_str_t pname, pvalue;
	const pjsip_parser_const_t *pc = pjsip_parser_const();

	do {
	    /* Eat the ';' separator. */
	    pj_scan_get_char(scanner);

	    /* Get pname. */
	    pj_scan_get(scanner, &pc->pjsip_PARAM_CHAR_SPEC, &pname);

	    if (*scanner->curptr == '=') {
		pj_scan_get_char(scanner);

#		if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0
		    pj_scan_get_unescape(scanner, 
					 &pjsip_TEL_PARSING_PVALUE_SPEC_ESC,
					 &pvalue);
#		else
		    pj_scan_get(scanner, &pjsip_TEL_PARSING_PVALUE_SPEC, 
				&pvalue);
		    pvalue = pj_str_unescape(pool, &pvalue);
#		endif

	    } else {
		pvalue.slen = 0;
		pvalue.ptr = NULL;
	    }

	    /* Save the parameters. */
	    if (pj_stricmp_alnum(&pname, &pjsip_ISUB_STR)==0) {
		uri->isub_param = pvalue;
	    } else if (pj_stricmp_alnum(&pname, &pjsip_EXT_STR)==0) {
		uri->ext_param = pvalue;
	    } else if (pj_stricmp_alnum(&pname, &pjsip_PH_CTX_STR)==0) {
		uri->context = pvalue;
	    } else {
		pjsip_param *param = PJ_POOL_ALLOC_T(pool, pjsip_param);
		param->name = pname;
		param->value = pvalue;
		pj_list_insert_before(&uri->other_param, param);
	    }

	} while (*scanner->curptr==';');
    }

    scanner->skip_ws = skip_ws;
    pj_scan_skip_whitespace(scanner);
    return uri;
}
Exemple #16
0
    void skip_ws()
    {
	pj_scan_skip_whitespace(&scanner_);
    }