Skip to content

Commit f2ffa96

Browse files
committed
Don't fail if there is junk byte in origin attribute
1 parent 8d25fe7 commit f2ffa96

4 files changed

Lines changed: 55 additions & 6 deletions

File tree

lib/ex_sdp/origin.ex

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,18 @@ defmodule ExSDP.Origin do
5252
end
5353

5454
@spec parse(binary()) ::
55-
{:ok, t()} | {:error, :invalid_addrtype | :invalid_address}
56-
def parse(origin) do
55+
{:ok, t()}
56+
| {:error, :invalid_addrtype | :invalid_address | :too_few_fields | :too_many_fields}
57+
def parse(origin_binary) do
58+
with {:ok, origin} <- do_parse(origin_binary, 6) do
59+
{:ok, origin}
60+
else
61+
{:error, :too_many_fields} -> do_parse(origin_binary, 7)
62+
error -> error
63+
end
64+
end
65+
66+
defp do_parse(origin, 6) do
5767
with {:ok, [username, sess_id, sess_version, nettype, addrtype, address]} <-
5868
Utils.split(origin, " ", 6),
5969
{:ok, addrtype} <- Address.parse_addrtype(addrtype),
@@ -75,6 +85,29 @@ defmodule ExSDP.Origin do
7585
end
7686
end
7787

88+
# a workaround to support SDP sent by Tapo C320WS camera which puts an additional junk byte in the origin attribute
89+
defp do_parse(origin, 7) do
90+
with {:ok, [username, sess_id, sess_version, _junk, nettype, addrtype, address]} <-
91+
Utils.split(origin, " ", 7),
92+
{:ok, addrtype} <- Address.parse_addrtype(addrtype),
93+
{:ok, address} <- Address.parse_address(address) do
94+
# check whether fqdn
95+
address = if is_binary(address), do: {addrtype, address}, else: address
96+
97+
origin = %__MODULE__{
98+
username: username,
99+
session_id: String.to_integer(sess_id),
100+
session_version: String.to_integer(sess_version),
101+
network_type: nettype,
102+
address: address
103+
}
104+
105+
{:ok, origin}
106+
else
107+
{:error, _reason} = error -> error
108+
end
109+
end
110+
78111
@doc """
79112
Increments `session_version` field.
80113

lib/ex_sdp/utils.ex

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,15 @@ defmodule ExSDP.Utils do
7474
end
7575

7676
@spec split(String.t(), String.t() | [String.t()] | :binary.cp() | Regex.t(), any) ::
77-
{:error, :too_few_fields} | {:ok, [String.t()]}
77+
{:error, :too_few_fields | :too_many_fields} | {:ok, [String.t()]}
7878
def split(origin, delim, expected_len) do
79-
split = String.split(origin, delim, parts: expected_len)
80-
if length(split) == expected_len, do: {:ok, split}, else: {:error, :too_few_fields}
79+
split = String.split(origin, delim)
80+
81+
cond do
82+
length(split) == expected_len -> {:ok, split}
83+
length(split) < expected_len -> {:error, :too_few_fields}
84+
length(split) > expected_len -> {:error, :too_many_fields}
85+
end
8186
end
8287

8388
@spec parse_payload_type(binary) :: {:ok, 0..127} | {:errror, :invalid_pt}

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule ExSDP.MixProject do
22
use Mix.Project
33

4-
@version "1.1.1"
4+
@version "1.1.2"
55
@github_url "https://github.com/membraneframework/ex_sdp"
66

77
def project do

test/ex_sdp/origin_test.exs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ defmodule ExSDP.OriginTest do
4343
username: "jdoe"
4444
}} = Origin.parse("jdoe 2890844526 2890842807 IN IP4 host.origin.name")
4545
end
46+
47+
test "supports improper SDP provided by Tapo C320WS cameras" do
48+
assert {:ok, origin} = Origin.parse("jdoe 2890844526 2890842807 1 IN IP4 10.47.16.5")
49+
50+
assert origin == %Origin{
51+
session_id: 2_890_844_526,
52+
address: {10, 47, 16, 5},
53+
session_version: 2_890_842_807,
54+
username: "jdoe"
55+
}
56+
end
4657
end
4758

4859
describe "Origin serializer" do

0 commit comments

Comments
 (0)