Commit b2acabe5 authored by baire's avatar baire
Browse files

added a function to decode and normalise the escaped characters

parent 6dfb5812
Loading
Loading
Loading
Loading
+85 −6
Original line number Diff line number Diff line
@@ -167,7 +167,65 @@ void normalise_quoted_string (Charstring& cs, bool remove_quotes = false) throw
	return;

error_malformed:
	throw DecodeError (&cs, "Malformed quoted string");
	DecodeError e(&cs);
	e.Msg() << "Malformed quoted string: " << cs.GetValue() << endl;
	throw e;
}

void normalise_escaped_string (Charstring& cs) throw (DecodeError)
{
	std::string result;

	const unsigned char* p   = cs.GetValueBin();
	const unsigned char* end = p + (cs.GetLength() / 8);

	for ( ; p!=end ; p++)
	{
		unsigned char c;

		if (*p == '%') {
			// escaped char %xx

			if ((end - p) < 3)
				goto error_malformed;

			char buff[3] = { p[1], p[2], '\0'};
			p += 2;

			char* next;
			c = strtol(buff, &next, 16);

			if (next != &buff[2])
				goto error_malformed;
			//TODO: check that the result is UTF-8 valid ?
		} else {
			c = *p;
		}

		if (c<128)
		{
			// 7-bit character
			result += c;
		} else {
			// 8-bit character
			// -> escape it
			char buff[4];
			sprintf (buff, "%%%02x", c);
			result += buff;
		}
	}

	// replace the string with the quoted string
	{
		Bytestring& bs = cs;
		bs.SetValue (result);
	}
	return;

error_malformed:
	DecodeError e(&cs);
	e.Msg() << "Malformed string: " << cs.GetValue() << endl;
	throw e;
}

//WSP: space, htab, vtab, form feed
@@ -425,6 +483,14 @@ void UserInfo::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}

void UserInfo::PostDecode (Buffer& buffer) throw (DecodeError)
{
	if (IsPresent (id_userOrTelephoneSubscriber))
		normalise_escaped_string (Get_userOrTelephoneSubscriber());
	if (IsPresent (id_password))
		normalise_escaped_string (Get_password());
}

void HostPort::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
{
	static Regex reg_host ("^" SIPREG_HOST);
@@ -594,6 +660,9 @@ void GenericParam::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)

void GenericParam::PostDecode (Buffer& buffer) throw (DecodeError)
{

	normalise_escaped_string (Get_id());

	if (IsPresent (id_paramValue))
	{
		Charstring& value = Get_paramValue();
@@ -601,6 +670,8 @@ void GenericParam::PostDecode (Buffer& buffer) throw (DecodeError)
		if (value.GetLength() &&
		    (*value.GetValueBin() == '"'))
				normalise_quoted_string (value, true);
		else
				normalise_escaped_string (value);
	}
}

@@ -738,6 +809,16 @@ void StatusLine::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)
	}
}

void StatusLine::PostDecode (Buffer& buffer) throw (DecodeError)
{
	static Regex reg_crlf ("^\r\n");

	reg_crlf.AssertMatch(buffer, this);
	reg_crlf.MovePast(buffer);

	normalise_escaped_string (Get_reasonPhrase());
}

class SipHeaderMap {
public:
	struct Entry {
@@ -1895,12 +1976,10 @@ void UndefinedHeader::PreDecodeField (int id, Buffer& buffer) throw (DecodeError
	}
}

void StatusLine::PostDecode (Buffer& buffer) throw (DecodeError)
void UndefinedHeader::PostDecode (Buffer& buffer) throw (DecodeError)
{
	static Regex reg_crlf ("^\r\n");

	reg_crlf.AssertMatch(buffer, this);
	reg_crlf.MovePast(buffer);
	normalise_escaped_string (Get_headerName());
	normalise_escaped_string (Get_headerValue());
}

void CallId::PreDecodeField (int id, Buffer& buffer) throw (DecodeError)