Commit 4c91ece9 authored by urbant's avatar urbant
Browse files

correction in header fields that can occur multiple times

parent 8ea1bde2
Loading
Loading
Loading
Loading
+167 −63
Original line number Diff line number Diff line
@@ -149,9 +149,12 @@ bool is_tel_scheme (const char * pszScheme) {
#define SIPREG_EQUAL		SIPREG_SWS "[=]" SIPREG_SWS

// without leading and trailing whitespace
#define SIPREG_QUOTED_STRING	"[\"]((" SIPREG_LWS ")|[]!#-[^-~" SIPCHARS_UTF8_NONASCII"]|([\\x5C][\"\\x5C]))*[\"]"
#define SIPREG_QUOTED_PAIR	"[\\x5C][\\x00-\\x09\\x0B\\x0C\\x0E-\\x7F]"
#define SIPREG_QUOTED_STRING	"[\"]((" SIPREG_LWS ")|[]!#-[^-~" SIPCHARS_UTF8_NONASCII"]|(" SIPREG_QUOTED_PAIR "))*[\"]"
#define SIPREG_DISPLAY_NAME "((" SIPREG_TOKEN "(" SIPREG_LWS SIPREG_TOKEN ")*)|(" SIPREG_QUOTED_STRING "))"

#define SIPREG_COMMENT	"[(]((" SIPREG_LWS ")|[\\x021-\\x5B\\x5D-\\xFD]|(" SIPREG_QUOTED_PAIR "))*[)]"

// IPv4
#define SIPREG_IP4	"([0-9]{1,3}\\.){3}[0-9]{1,3}"

@@ -182,34 +185,13 @@ bool is_tel_scheme (const char * pszScheme) {

#define SIPREG_GPARAM_VALUE "(([" SIPCHARS_ALFANUM ".!%*_+`'~\\-:]+)|(" SIPREG_QUOTED_STRING "))"

bool decode_comma_separated(RecordOfSetOf * pRecordOf, Buffer & buffer) throw (DecodeError)
{
	static Regex reg_separator ("^" SIPREG_COMMA);
	if (!buffer.GetBitsLeft() || pRecordOf->GetSize() == 0)
		return true;
	else if (reg_separator.Match(buffer))
		buffer.SetPosition(buffer.GetPosition() + reg_separator.GetMatchedLength());
	else
		return false;
	return true;
}

int detect_comma(RecordOfSetOf * pRecordOf, Buffer & buffer) throw (DecodeError)
bool detect_comma(Buffer & buffer) throw (DecodeError)
{
	static Regex reg_separator ("^" SIPREG_COMMA);
	static Regex reg_content ("^" SIPREG_ASCII_WITHOUT_COMMA);

	if (!buffer.GetBitsLeft())
		return -1;
	bool bSeparated = reg_separator.Match(buffer);
	if (bSeparated)
		buffer.SetPosition(buffer.GetPosition() + reg_separator.GetMatchedLength());

	if (pRecordOf->GetSize() == 0 || bSeparated) {
		reg_content.AssertMatch(buffer, pRecordOf);
		return reg_content.GetMatchedLength();
	}
	return -1;	
	Regex reg_comma ("^" SIPREG_COMMA);
	bool bRes;
	if (bRes = reg_comma.Match(buffer))
		reg_comma.MovePast(buffer);
	return bRes;
}

void SipUrl::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
@@ -399,9 +381,11 @@ void AmpersandParam_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeE
		SetHypSize(-2);
}

void CommaParam_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
void CommaParam_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (!decode_comma_separated (this, buffer))
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}

@@ -711,6 +695,11 @@ private:
		SIP_HEADER_ADD (MIME-Version,	,	mimeVersion,	MIME_VERSION_E);
		SIP_HEADER_ADD (Min-Expires,	,	minExpires,	MIN_EXPIRES_E);
		SIP_HEADER_ADD (Organization,	,	organization,	ORGANIZATION_E);
		SIP_HEADER_ADD (Priority,	,	priority,	PRIORITY_E);
		SIP_HEADER_ADD (Proxy-Authenticate,		,	proxyAuthenticate,	PROXY_AUTHENTICATE_E);
		SIP_HEADER_ADD (Proxy-Authorization,	,	proxyAuthorization,	PROXY_AUTHORIZATION_E);
		SIP_HEADER_ADD (Reply-To,	,	replyTo,	REPLY_TO_E);
		SIP_HEADER_ADD (Retry-After,	,	retryAfter,	RETRY_AFTER_E);
		{
			mEntries.push_back(Entry("", "", MessageHeader::id_undefinedHeader_List, ""));
			Entry& e = *mEntries.rbegin();
@@ -885,9 +874,11 @@ void ContactBody::PreDecode (Buffer& buffer) throw (DecodeError)
	}
}

void ContactAddress_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
void ContactAddress_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (!decode_comma_separated (this, buffer))
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}

@@ -927,12 +918,24 @@ void To::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}

void ReplyTo::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_semicolon ("^;");
	if (id == id_replyToParams) {
		if(reg_semicolon.Match(buffer)) {
			SetHypFieldIsPresent (id, 1);
		} else {
			SetHypFieldIsPresent (id, 0);
		}
	}
}

void Accept::PreDecodeField (int id, Buffer& buffer) throw (DecodeError){
	static Regex reg_accept_args ("^[^;,\\r\\n]");
	if (id == id_acceptArgs){
		if(reg_accept_args.Match(buffer)) {
			SetHypFieldIsPresent (id, 1);
		} else {
		} else if (Get_acceptArgs().GetSize() == 0){
			SetHypFieldIsPresent (id, 0);
		}
	}
@@ -956,9 +959,20 @@ void AcceptBody::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}

void AcceptBody_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
void AcceptBody_List::PreDecode (Buffer& buffer) throw (DecodeError)
{
	if (!decode_comma_separated (this, buffer))
	// we assume that we are decoding one field at onece 
	// multiple fields are handled by successively decoding
	// the via field several times in MessageHeader
	SetHypSize (GetSize() + 1);
	SetHypAppend (1);
}

void AcceptBody_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}

@@ -975,9 +989,16 @@ void AcceptEncoding::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)

void ContentCoding_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	int nRes = detect_comma(this, buffer);
	if (nRes >= 0)
		SetHypFieldLength(nRes);
	static Regex reg_content ("^" SIPREG_ASCII_WITHOUT_COMMA);
	reg_content.AssertMatch(buffer, this);
	SetHypFieldLength(reg_content.GetMatchedLength());
}


void ContentCoding_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}
@@ -1011,9 +1032,11 @@ void LanguageBody::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}

void LanguageBody_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
void LanguageBody_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (!decode_comma_separated (this, buffer))
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}

@@ -1061,9 +1084,11 @@ void AlertInfoBody::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}

void AlertInfoBody_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
void AlertInfoBody_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (!decode_comma_separated (this, buffer))
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}

@@ -1106,6 +1131,18 @@ void Credentials::PreDecode (Buffer& buffer) throw (DecodeError)
		SetHypChosenId (id_otherResponse);
	}
}

void Challenge::PreDecode (Buffer& buffer) throw (DecodeError)
{
	static Regex reg_digest ("^[Dd][Ii][Gg][Ee][Ss][Tt]" SIPREG_LWS);
	if (reg_digest.Match (buffer)) {
		buffer.SetPosition(buffer.GetPosition() + reg_digest.GetMatchedLength());
		SetHypChosenId (id_digestCln);
	} else {
		SetHypChosenId (id_otherChallenge);
	}
}

void OtherAuth::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_auth_scheme ("^" SIPREG_TOKEN);
@@ -1162,9 +1199,11 @@ void CallInfoBody::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}

void CallInfoBody_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
void CallInfoBody_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (!decode_comma_separated (this, buffer))
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}

@@ -1188,9 +1227,16 @@ void ContentDisposition::PreDecodeField (int id, Buffer& buffer) throw (DecodeEr

void LanguageTag_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	int nRes = detect_comma(this, buffer);
	if (nRes >= 0)
		SetHypFieldLength(nRes);
	static Regex reg_content ("^" SIPREG_ASCII_WITHOUT_COMMA);
	reg_content.AssertMatch(buffer, this);
	SetHypFieldLength(reg_content.GetMatchedLength());
}


void LanguageTag_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}
@@ -1242,9 +1288,11 @@ void ErrorInfoBody::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}

void ErrorInfoBody_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
void ErrorInfoBody_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (!decode_comma_separated (this, buffer))
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}

@@ -1262,9 +1310,16 @@ void Expires::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)

void CallidString_List::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	int nRes = detect_comma(this, buffer);
	if (nRes >= 0)
		SetHypFieldLength(nRes);
	static Regex reg_content ("^" SIPREG_ASCII_WITHOUT_COMMA);
	reg_content.AssertMatch(buffer, this);
	SetHypFieldLength(reg_content.GetMatchedLength());
}


void CallidString_List::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	if (detect_comma (buffer))
		SetHypSize (GetSize() + 1);
	else
		SetHypSize (-2);
}
@@ -1294,7 +1349,6 @@ void MinExpires::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}


void Organization::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_organization ("^(" SIPREG_TEXT_UTF8_TRIM ")*");
@@ -1307,6 +1361,56 @@ void Organization::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}

void Priority::PreDecodeField (int id, Buffer& buffer) throw (DecodeError){
	static Regex reg_priority ("^" SIPREG_TOKEN);
	if (id == id_priorityValue){
		reg_priority.AssertMatch(buffer, this);
		SetHypFieldLength(id, reg_priority.GetMatchedLength());
	}
}

void RetryAfter::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_delta_sec ("^[0-9]+");
	static Regex reg_comment ("^" SIPREG_COMMENT);
	static Regex reg_separator ("^" SIPREG_SEMI);

	switch (id) {
		case id_deltaSec: 
			reg_delta_sec.AssertMatch (buffer, this);
			SetHypFieldLength (id, reg_delta_sec.GetMatchedLength());
			break;
		case id_comment:
			remove_whitespace(buffer);
			if (reg_comment.Match (buffer)) {
				SetHypFieldIsPresent(id, 1);
				SetHypFieldLength (id, reg_comment.GetMatchedLength() - 16);
				buffer.SetPosition(buffer.GetPosition() + 8);
			}
			else
				SetHypFieldIsPresent(id, 0);
			break;
		case id_retryParams:
			if (reg_separator.Match (buffer))
				SetHypFieldIsPresent(id, 1);
			else
				SetHypFieldIsPresent(id, 0);
			break;
	}
}

void RetryAfter::PostDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_parenthesis ("^[)]");
	if (id == id_comment && GetHypFieldIsPresent(id))
	{
		reg_parenthesis.AssertMatch (buffer, this);
		buffer.SetPosition(buffer.GetPosition() + 8);
		remove_whitespace(buffer);
	}
}


void NameAddr::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_display_name ("^" SIPREG_DISPLAY_NAME);