From bc26832ad7644d5a17e1438b1fc9dbb58cf6432a Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Wed, 15 Dec 2021 23:12:09 -0500 Subject: [PATCH] Support parsing candidates with missing Foundation Not RFC 8445 compliant but are currently emitted by Google. Resolves #390 --- candidate_base.go | 15 ++++++++++++--- candidate_test.go | 23 +++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/candidate_base.go b/candidate_base.go index e66c91d..230bde8 100644 --- a/candidate_base.go +++ b/candidate_base.go @@ -393,8 +393,13 @@ func (c *candidateBase) copy() (Candidate, error) { // Marshal returns the string representation of the ICECandidate func (c *candidateBase) Marshal() string { - val := fmt.Sprintf("%s %d %s %d %s %d typ %s", - c.Foundation(), + val := c.Foundation() + if val == " " { + val = "" + } + + val = fmt.Sprintf("%s %d %s %d %s %d typ %s", + val, c.Component(), c.NetworkType().NetworkShort(), c.Priority(), @@ -419,7 +424,11 @@ func (c *candidateBase) Marshal() string { // UnmarshalCandidate creates a Candidate from its string representation func UnmarshalCandidate(raw string) (Candidate, error) { split := strings.Fields(raw) - if len(split) < 8 { + switch { + // Foundation not specified: not RFC 8445 compliant but seen in the wild + case len(split) == 7 && raw[0] == ' ': + split = append([]string{" "}, split...) + case len(split) < 8: return nil, fmt.Errorf("%w (%d)", errAttributeTooShortICECandidate, len(split)) } diff --git a/candidate_test.go b/candidate_test.go index 5889e9e..1ffebad 100644 --- a/candidate_test.go +++ b/candidate_test.go @@ -294,6 +294,22 @@ func TestCandidateMarshal(t *testing.T) { }, "1380287402 1 udp 2130706431 e2494022-4d9a-4c1e-a750-cc48d4f8d6ee.local 60542 typ host", false, }, + // Missing Foundation + { + &CandidateHost{ + candidateBase{ + networkType: NetworkTypeUDP4, + candidateType: CandidateTypeHost, + address: "127.0.0.1", + port: 80, + priorityOverride: 500, + foundationOverride: " ", + }, + "", + }, + " 1 udp 500 127.0.0.1 80 typ host", + false, + }, // Invalid candidates {nil, "", true}, @@ -321,3 +337,10 @@ func TestCandidateMarshal(t *testing.T) { assert.Equal(t, test.marshaled, actualCandidate.Marshal()) } } + +func TestMissingCandidateFoundation(t *testing.T) { + // " 1 udp 2113939711 2607:f8b0:400e:c0a::7f 19305 typ host generation 0" + // " 1 tcp 2113939710 2607:f8b0:400e:c0a::7f 19305 typ host tcptype passive generation 0" + // " 1 udp 2113932031 172.253.117.127 19305 typ host generation 0" + // " 1 tcp 2113932030 172.253.117.127 19305 typ host tcptype passive generation 0" +}