Bug 844929: Accept numeric parameters > UINT_MAX in SDP o-lines

This commit is contained in:
Ethan Hugg 2013-02-25 10:22:10 -08:00
parent 497204dd23
commit 9884e39d79
2 changed files with 81 additions and 4 deletions

View File

@ -11,6 +11,7 @@
#include "prot_configmgr.h"
#include "ccapi.h"
#include "CSFLog.h"
#include "prprf.h"
static const char *logTag = "sdp_token";
@ -59,12 +60,39 @@ sdp_result_e sdp_build_version (sdp_t *sdp_p, u16 level, flex_string *fs)
return (SDP_SUCCESS);
}
static sdp_result_e sdp_verify_unsigned(const char *ptr, PRUint64 max_value)
{
PRUint64 numeric_value;
/* Checking for only numbers since PR_sscanf will ignore trailing
characters */
size_t end = strspn(ptr, "0123456789");
if (ptr[end] != '\0')
return SDP_INVALID_PARAMETER;
if (PR_sscanf(ptr, "%llu", &numeric_value) != 1)
return SDP_INVALID_PARAMETER;
if (numeric_value > max_value)
return SDP_INVALID_PARAMETER;
return SDP_SUCCESS;
}
sdp_result_e sdp_parse_owner (sdp_t *sdp_p, u16 level, const char *ptr)
{
int i;
char *tmpptr;
sdp_result_e result;
char tmp[SDP_MAX_STRING_LEN];
/* The spec says this:
The numeric value of the session id
and version in the o line MUST be representable with a 64 bit signed
integer. The initial value of the version MUST be less than
(2**62)-1, to avoid rollovers.
*/
PRUint64 max_value_sessid_version = ((((PRUint64) 1) << 62) - 2);
if (sdp_p->owner_name[0] != '\0') {
sdp_p->conf_p->num_invalid_token_order++;
@ -91,8 +119,7 @@ sdp_result_e sdp_parse_owner (sdp_t *sdp_p, u16 level, const char *ptr)
/* Make sure the sessid is numeric, even though we store it as
* a string.
*/
(void)sdp_getnextnumtok(sdp_p->owner_sessid,
(const char **)&tmpptr, " \t",&result);
result = sdp_verify_unsigned(sdp_p->owner_sessid, max_value_sessid_version);
}
if (result != SDP_SUCCESS) {
sdp_parse_error(sdp_p->peerconnection,
@ -108,8 +135,7 @@ sdp_result_e sdp_parse_owner (sdp_t *sdp_p, u16 level, const char *ptr)
/* Make sure the version is numeric, even though we store it as
* a string.
*/
(void)sdp_getnextnumtok(sdp_p->owner_version,
(const char **)&tmpptr," \t",&result);
result = sdp_verify_unsigned(sdp_p->owner_version, max_value_sessid_version);
}
if (result != SDP_SUCCESS) {
sdp_parse_error(sdp_p->peerconnection,

View File

@ -1928,6 +1928,57 @@ TEST_F(SignalingTest, ipAddrAnyOffer)
ASSERT_NE(answer.find("a=sendrecv"), std::string::npos);
}
static void CreateSDPForBigOTests(std::string& offer, const char *number) {
offer =
"v=0\r\n"
"o=- ";
offer += number;
offer += " ";
offer += number;
offer += " IN IP4 127.0.0.1\r\n"
"s=-\r\n"
"b=AS:64\r\n"
"t=0 0\r\n"
"a=fingerprint:sha-256 F3:FA:20:C0:CD:48:C4:5F:02:5F:A5:D3:21:D0:2D:48:"
"7B:31:60:5C:5A:D8:0D:CD:78:78:6C:6D:CE:CC:0C:67\r\n"
"m=audio 9000 RTP/AVP 99\r\n"
"c=IN IP4 0.0.0.0\r\n"
"a=rtpmap:99 opus/48000/2\r\n"
"a=ice-ufrag:cYuakxkEKH+RApYE\r\n"
"a=ice-pwd:bwtpzLZD+3jbu8vQHvEa6Xuq\r\n"
"a=sendrecv\r\n";
}
TEST_F(SignalingTest, BigOValues)
{
std::string offer;
CreateSDPForBigOTests(offer, "12345678901234567");
a2_.SetRemote(TestObserver::OFFER, offer);
ASSERT_TRUE(a2_.pObserver->state == TestObserver::stateSuccess);
}
TEST_F(SignalingTest, BigOValuesExtraChars)
{
std::string offer;
CreateSDPForBigOTests(offer, "12345678901234567FOOBAR");
a2_.SetRemote(TestObserver::OFFER, offer, true);
ASSERT_TRUE(a2_.pObserver->state == TestObserver::stateError);
}
TEST_F(SignalingTest, BigOValuesTooBig)
{
std::string offer;
CreateSDPForBigOTests(offer, "18446744073709551615");
a2_.SetRemote(TestObserver::OFFER, offer, true);
ASSERT_TRUE(a2_.pObserver->state == TestObserver::stateError);
}
TEST_F(SignalingAgentTest, CreateUntilFailThenWait) {
int i;