Bug 1474517: merge rsdparsa from upstream r=johannes.willbold+610943

Updated rsdparsa to 75d5c6df6728fbab502db06940062e0358536f9f from github
upstream

MozReview-Commit-ID: 9hr7DV6KTkK

--HG--
extra : rebase_source : c5b2c003e76489e267390402ebb5947cf3ec48b6
This commit is contained in:
Nils Ohlmeier [:drno] 2018-07-09 23:56:42 -07:00
Родитель 9171c79a67
Коммит cf44315a16
8 изменённых файлов: 241 добавлений и 55 удалений

5
Cargo.lock сгенерированный
Просмотреть файл

@ -1734,6 +1734,11 @@ dependencies = [
[[package]]
name = "rsdparsa"
version = "0.1.0"
dependencies = [
"log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)",
]
[[package]]
name = "rsdparsa_capi"

Просмотреть файл

@ -5,3 +5,14 @@ authors = ["Nils Ohlmeier <github@ohlmeier.org>"]
[features]
default = []
# serializability
serialize = ["serde", "serde_derive"]
[dependencies]
# clippy = {version = "*", optional = true}
log = {version = "*"}
serde = {version = "1.0" , optional = true}
serde_derive = {version = "1.0" , optional = true}
[dev-dependencies]
# serde_json = {version = "1.0"}

Просмотреть файл

@ -773,7 +773,6 @@ fn parse_single_direction(to_parse: &str) -> Result<SdpSingleDirection, SdpParse
}
}
fn parse_sctp_port(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
let port = to_parse.parse()?;
if port > 65535 {
@ -1102,6 +1101,7 @@ fn parse_fmtp(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
parameters: parameters,
}))
}
fn parse_group(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
let mut tokens = to_parse.split_whitespace();
let semantics = match tokens.next() {
@ -1998,7 +1998,30 @@ fn test_parse_attribute_rtcp() {
#[test]
fn test_parse_attribute_rtcp_fb() {
assert!(parse_attribute("rtcp-fb:101 ccm fir").is_ok())
assert!(parse_attribute("rtcp-fb:101 ack rpsi").is_ok());
assert!(parse_attribute("rtcp-fb:101 ack app").is_ok());
assert!(parse_attribute("rtcp-fb:101 ccm").is_ok());
assert!(parse_attribute("rtcp-fb:101 ccm fir").is_ok());
assert!(parse_attribute("rtcp-fb:101 ccm tmmbr").is_ok());
assert!(parse_attribute("rtcp-fb:101 ccm tstr").is_ok());
assert!(parse_attribute("rtcp-fb:101 ccm vbcm").is_ok());
assert!(parse_attribute("rtcp-fb:101 nack").is_ok());
assert!(parse_attribute("rtcp-fb:101 nack sli").is_ok());
assert!(parse_attribute("rtcp-fb:101 nack pli").is_ok());
assert!(parse_attribute("rtcp-fb:101 nack rpsi").is_ok());
assert!(parse_attribute("rtcp-fb:101 nack app").is_ok());
assert!(parse_attribute("rtcp-fb:101 trr-int 1").is_ok());
assert!(parse_attribute("rtcp-fb:101 goog-remb").is_ok());
assert!(parse_attribute("rtcp-fb:101 transport-cc").is_ok());
assert!(parse_attribute("rtcp-fb:101 unknown").is_err());
assert!(parse_attribute("rtcp-fb:101 ack").is_err());
assert!(parse_attribute("rtcp-fb:101 ccm unknwon").is_err());
assert!(parse_attribute("rtcp-fb:101 nack unknown").is_err());
assert!(parse_attribute("rtcp-fb:101 trr-int").is_err());
assert!(parse_attribute("rtcp-fb:101 trr-int a").is_err());
assert!(parse_attribute("rtcp-fb:101 goog-remb unknown").is_err());
assert!(parse_attribute("rtcp-fb:101 transport-cc unknown").is_err());
}
#[test]

Просмотреть файл

@ -1,5 +1,7 @@
#![cfg_attr(feature="clippy", feature(plugin))]
#[macro_use]
extern crate log;
#[cfg(feature="serialize")]
#[macro_use]
extern crate serde_derive;
@ -138,7 +140,7 @@ impl SdpSession {
&self.origin
}
pub fn get_session(&self) -> &String {
pub fn get_session(&self) -> &str {
&self.session
}
@ -170,22 +172,10 @@ impl SdpSession {
self.media.extend(v)
}
pub fn has_timing(&self) -> bool {
self.timing.is_some()
}
pub fn has_attributes(&self) -> bool {
!self.attribute.is_empty()
}
pub fn get_attribute(&self, t: SdpAttributeType) -> Option<&SdpAttribute> {
self.attribute.iter().filter(|a| SdpAttributeType::from(*a) == t).next()
}
pub fn has_media(&self) -> bool {
!self.media.is_empty()
}
pub fn add_media(&mut self, media_type: SdpMediaValue, direction: SdpAttribute, port: u32,
protocol: SdpProtocolValue, addr: String)
-> Result<(),SdpParserInternalError> {
@ -212,7 +202,7 @@ impl SdpSession {
}
fn parse_session(value: &str) -> Result<SdpType, SdpParserInternalError> {
println!("session: {}", value);
trace!("session: {}", value);
Ok(SdpType::Session(String::from(value)))
}
@ -228,7 +218,7 @@ fn parse_version(value: &str) -> Result<SdpType, SdpParserInternalError> {
return Err(SdpParserInternalError::Generic(format!("version type contains unsupported value {}",
ver)));
};
println!("version: {}", ver);
trace!("version: {}", ver);
Ok(SdpType::Version(ver))
}
@ -300,7 +290,7 @@ fn parse_origin(value: &str) -> Result<SdpType, SdpParserInternalError> {
session_version,
unicast_addr,
};
println!("{}", o);
trace!("origin: {}", o);
Ok(SdpType::Origin(o))
}
@ -362,7 +352,7 @@ fn parse_connection(value: &str) -> Result<SdpType, SdpParserInternalError> {
.to_string()));
}
let c = SdpConnection { addr, ttl, amount };
println!("connection: {}", c.addr);
trace!("connection: {}", c.addr);
Ok(SdpType::Connection(c))
}
@ -417,7 +407,7 @@ fn parse_bandwidth(value: &str) -> Result<SdpType, SdpParserInternalError> {
"TIAS" => SdpBandwidth::Tias(bandwidth),
_ => SdpBandwidth::Unknown(String::from(bv[0]), bandwidth),
};
println!("bandwidth: {}, {}", bv[0], bandwidth);
trace!("bandwidth: {}, {}", bv[0], bandwidth);
Ok(SdpType::Bandwidth(bw))
}
@ -448,7 +438,7 @@ fn parse_timing(value: &str) -> Result<SdpType, SdpParserInternalError> {
let start = tv[0].parse::<u64>()?;
let stop = tv[1].parse::<u64>()?;
let t = SdpTiming { start, stop };
println!("timing: {}, {}", t.start, t.stop);
trace!("timing: {}, {}", t.start, t.stop);
Ok(SdpType::Timing(t))
}
@ -626,23 +616,23 @@ fn sanity_check_sdp_session(session: &SdpSession) -> Result<(), SdpParserError>
line_number: 0,
};
if !session.has_timing() {
if !session.timing.is_some() {
return Err(SdpParserError::Sequence {
message: "Missing timing type".to_string(),
line_number: 0,
});
}
if !session.has_media() {
if session.media.is_empty() {
return Err(SdpParserError::Sequence {
message: "Missing media setion".to_string(),
message: "Missing media section".to_string(),
line_number: 0,
});
}
if session.get_connection().is_none() {
for msection in &session.media {
if !msection.has_connection() {
if msection.get_connection().is_none() {
return Err(SdpParserError::Sequence {
message: "Each media section must define a connection
if it is not defined on session level".to_string(),
@ -917,7 +907,7 @@ fn parse_sdp_vector(lines: &[SdpLine]) -> Result<SdpSession, SdpParserError> {
SdpType::Uri(_) |
SdpType::Zone(_) => (),
};
if sdp_session.has_media() {
if !sdp_session.media.is_empty() {
break;
};
}
@ -1006,7 +996,7 @@ pub fn parse_sdp(sdp: &str, fail_on_warning: bool) -> Result<SdpSession, SdpPars
session.warnings = warnings;
for warning in &session.warnings {
println!("Warning: {}", &warning);
warn!("Warning: {}", &warning);
}
Ok(session)

Просмотреть файл

@ -118,10 +118,6 @@ impl SdpMedia {
&self.media.formats
}
pub fn has_bandwidth(&self) -> bool {
!self.bandwidth.is_empty()
}
pub fn get_bandwidth(&self) -> &Vec<SdpBandwidth> {
&self.bandwidth
}
@ -130,10 +126,6 @@ impl SdpMedia {
self.bandwidth.push(bw.clone())
}
pub fn has_attributes(&self) -> bool {
!self.attribute.is_empty()
}
pub fn get_attributes(&self) -> &Vec<SdpAttribute> {
&self.attribute
}
@ -190,10 +182,6 @@ impl SdpMedia {
self.attribute.iter().filter(|a| SdpAttributeType::from(*a) == t).collect()
}
pub fn has_connection(&self) -> bool {
self.connection.is_some()
}
pub fn get_connection(&self) -> &Option<SdpConnection> {
&self.connection
}
@ -372,7 +360,7 @@ pub fn parse_media(value: &str) -> Result<SdpType, SdpParserInternalError> {
proto,
formats,
};
println!("media: {}, {}, {}, {}", m.media, m.port, m.proto, m.formats);
trace!("media: {}, {}, {}, {}", m.media, m.port, m.proto, m.formats);
Ok(SdpType::Media(m))
}
@ -499,4 +487,97 @@ pub fn parse_media_vector(lines: &[SdpLine]) -> Result<Vec<SdpMedia>, SdpParserE
Ok(media_sections)
}
// TODO add unit tests for parse_media_vector
#[test]
fn test_media_vector_first_line_failure() {
let mut sdp_lines: Vec<SdpLine> = Vec::new();
let line = SdpLine {
line_number: 0,
sdp_type: SdpType::Session("hello".to_string())
};
sdp_lines.push(line);
assert!(parse_media_vector(&sdp_lines).is_err());
}
#[test]
fn test_media_vector_multiple_connections() {
let mut sdp_lines: Vec<SdpLine> = Vec::new();
let media_line = SdpMediaLine {
media: SdpMediaValue::Audio,
port: 9,
port_count: 0,
proto: SdpProtocolValue::RtpSavpf,
formats: SdpFormatList::Integers(Vec::new()),
};
let media = SdpLine {
line_number: 0,
sdp_type: SdpType::Media(media_line)
};
sdp_lines.push(media);
use network::{parse_unicast_addr};
let addr = parse_unicast_addr("127.0.0.1").unwrap();
let c = SdpConnection {
addr,
ttl: None,
amount: None };
let c1 = SdpLine {
line_number: 1,
sdp_type: SdpType::Connection(c.clone())
};
sdp_lines.push(c1);
let c2 = SdpLine {
line_number: 2,
sdp_type: SdpType::Connection(c)
};
sdp_lines.push(c2);
assert!(parse_media_vector(&sdp_lines).is_err());
}
#[test]
fn test_media_vector_invalid_types() {
let mut sdp_lines: Vec<SdpLine> = Vec::new();
let media_line = SdpMediaLine {
media: SdpMediaValue::Audio,
port: 9,
port_count: 0,
proto: SdpProtocolValue::RtpSavpf,
formats: SdpFormatList::Integers(Vec::new()),
};
let media = SdpLine {
line_number: 0,
sdp_type: SdpType::Media(media_line)
};
sdp_lines.push(media);
use {SdpTiming};
let t = SdpTiming { start: 0, stop: 0 };
let tline = SdpLine {
line_number: 1,
sdp_type: SdpType::Timing(t)
};
sdp_lines.push(tline);
assert!(parse_media_vector(&sdp_lines).is_err());
}
#[test]
fn test_media_vector_invalid_media_level_attribute() {
let mut sdp_lines: Vec<SdpLine> = Vec::new();
let media_line = SdpMediaLine {
media: SdpMediaValue::Audio,
port: 9,
port_count: 0,
proto: SdpProtocolValue::RtpSavpf,
formats: SdpFormatList::Integers(Vec::new()),
};
let media = SdpLine {
line_number: 0,
sdp_type: SdpType::Media(media_line)
};
sdp_lines.push(media);
let a = SdpAttribute::IceLite;
let aline = SdpLine {
line_number: 1,
sdp_type: SdpType::Attribute(a)
};
sdp_lines.push(aline);
assert!(parse_media_vector(&sdp_lines).is_err());
}

Просмотреть файл

@ -25,9 +25,8 @@ m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n";
assert_eq!(msection.get_port(), 0);
assert_eq!(*msection.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
assert!(!msection.has_attributes());
assert!(!msection.has_bandwidth());
assert!(!msection.has_connection());
assert!(msection.get_attributes().is_empty());
assert!(msection.get_bandwidth().is_empty());
assert!(msection.get_connection().is_none());
}
@ -72,6 +71,40 @@ m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n";
assert!(sdp.get_connection().is_some());
}
#[test]
fn parse_minimal_sdp_with_most_media_types() {
let sdp = "v=0\r\n
o=- 0 0 IN IP4 0.0.0.0\r\n
s=-\r\n
t=0 0\r\n
m=video 0 UDP/TLS/RTP/SAVPF 0\r\n
b=AS:1\r\n
b=CT:123\r\n
b=TIAS:12345\r\n
c=IN IP4 0.0.0.0\r\n
a=sendrecv\r\n";
let sdp_res = rsdparsa::parse_sdp(sdp, false);
assert!(sdp_res.is_ok());
let sdp_opt = sdp_res.ok();
assert!(sdp_opt.is_some());
let sdp = sdp_opt.unwrap();
assert_eq!(sdp.version, 0);
assert_eq!(sdp.session, "-");
assert_eq!(sdp.attribute.len(), 0);
assert_eq!(sdp.media.len(), 1);
let msection = &(sdp.media[0]);
assert_eq!(*msection.get_type(),
rsdparsa::media_type::SdpMediaValue::Video);
assert_eq!(msection.get_port(), 0);
assert_eq!(*msection.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
assert!(!msection.get_bandwidth().is_empty());
assert!(!msection.get_connection().is_none());
assert!(!msection.get_attributes().is_empty());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some());
}
#[test]
fn parse_firefox_audio_offer() {
let sdp = "v=0\r\n
@ -112,10 +145,21 @@ a=ssrc:2655508255 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}\r\n";
assert_eq!(msection.get_port(), 9);
assert_eq!(*msection.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
assert!(msection.has_attributes());
assert!(msection.has_connection());
assert!(msection.get_connection().is_some());
assert!(!msection.has_bandwidth());
assert!(msection.get_bandwidth().is_empty());
assert!(!msection.get_attributes().is_empty());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some());
}
#[test]
@ -169,6 +213,22 @@ a=ssrc:2709871439 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}";
assert_eq!(msection.get_port(), 9);
assert_eq!(*msection.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
assert!(msection.get_connection().is_some());
assert!(msection.get_bandwidth().is_empty());
assert!(!msection.get_attributes().is_empty());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Recvonly).is_some());
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some());
}
#[test]
@ -206,6 +266,22 @@ a=ssrc:3376683177 cname:{62f78ee0-620f-a043-86ca-b69f189f1aea}\r\n";
assert_eq!(msection.get_port(), 49760);
assert_eq!(*msection.get_proto(),
rsdparsa::media_type::SdpProtocolValue::DtlsSctp);
assert!(msection.get_connection().is_some());
assert!(msection.get_bandwidth().is_empty());
assert!(!msection.get_attributes().is_empty());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some());
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::EndOfCandidates).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some());
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some());
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb).is_some());
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some());
assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sctpmap).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some());
assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some());
}
#[test]
@ -311,9 +387,9 @@ a=ssrc:2673335628 label:b6ec5178-c611-403f-bbec-3833ed547c09\r\n";
assert_eq!(msection1.get_port(), 9);
assert_eq!(*msection1.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
assert!(msection1.has_attributes());
assert!(msection1.has_connection());
assert!(!msection1.has_bandwidth());
assert!(!msection1.get_attributes().is_empty());
assert!(msection1.get_connection().is_some());
assert!(msection1.get_bandwidth().is_empty());
let msection2 = &(sdp.media[1]);
assert_eq!(*msection2.get_type(),
@ -321,9 +397,9 @@ a=ssrc:2673335628 label:b6ec5178-c611-403f-bbec-3833ed547c09\r\n";
assert_eq!(msection2.get_port(), 9);
assert_eq!(*msection2.get_proto(),
rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf);
assert!(msection2.has_attributes());
assert!(msection2.has_connection());
assert!(!msection2.has_bandwidth());
assert!(!msection2.get_attributes().is_empty());
assert!(msection2.get_connection().is_some());
assert!(msection2.get_bandwidth().is_empty());
}
#[test]

Просмотреть файл

@ -109,7 +109,7 @@ pub unsafe extern "C" fn sdp_get_origin(session: *const SdpSession) -> RustSdpO
#[no_mangle]
pub unsafe extern "C" fn session_view(session: *const SdpSession) -> StringView {
StringView::from((*session).get_session().as_str())
StringView::from((*session).get_session())
}
#[no_mangle]

Просмотреть файл

@ -134,7 +134,7 @@ pub unsafe extern "C" fn sdp_get_media_bandwidth_vec(sdp_media: *const SdpMedia)
#[no_mangle]
pub unsafe extern "C" fn sdp_media_has_connection(sdp_media: *const SdpMedia) -> bool {
(*sdp_media).has_connection()
(*sdp_media).get_connection().is_some()
}
#[no_mangle]