diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 0000000..572e03b --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1,4 @@ + +target +corpus +artifacts diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock new file mode 100644 index 0000000..fa50f0a --- /dev/null +++ b/fuzz/Cargo.lock @@ -0,0 +1,963 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "arbitrary" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "237430fd6ed3740afe94eefcc278ae21e050285be882804e0d6e8695f0c94691" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "async-stream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7815ea54e4d821e791162e078acbebfd6d8c8939cd559c9335dceb1c8ca7282" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "bitreader" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9178181a7d44239c6c8eaafa8688558a2ab5fa04b8855381f2681e9591fb941b" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "bitvec" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bytes" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" + +[[package]] +name = "cc" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cookie-factory" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396de984970346b0d9e93d1415082923c679e5ae5c3ee3dcbd104f5610af126b" + +[[package]] +name = "cpufeatures" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" +dependencies = [ + "libc", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest_auth" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa30657988b2ced88f68fe490889e739bf98d342916c33ed3100af1d6f1cbc9c" +dependencies = [ + "digest", + "hex", + "md-5", + "rand", + "sha2", +] + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "four-cc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3958af68a31b1d1384d3f39b6aa33eb14b6009065b5ca305ddd9712a4237124f" + +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "futures" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" + +[[package]] +name = "futures-executor" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acc499defb3b348f8d8f3f66415835a9131856ff7714bf10dadfc4ec4bdb29a1" + +[[package]] +name = "futures-macro" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282" + +[[package]] +name = "futures-task" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae" + +[[package]] +name = "futures-util" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" +dependencies = [ + "autocfg", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189" + +[[package]] +name = "h264-reader" +version = "0.4.0" +source = "git+https://github.com/dholroyd/h264-reader#dd2d05d54bec596993be9a0833690b54219f6778" +dependencies = [ + "bitreader", + "memchr", + "rfc6381-codec", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "lexical-core" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" +dependencies = [ + "arrayvec", + "bitflags", + "cfg-if", + "ryu", + "static_assertions", +] + +[[package]] +name = "libc" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a9a84a6e8b55dfefb04235e55edb2b9a2a18488fcae777a6bdaa6f06f1deb3" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + +[[package]] +name = "md-5" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" +dependencies = [ + "block-buffer", + "digest", + "opaque-debug", +] + +[[package]] +name = "memchr" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "mp4ra-rust" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be9daf03b43bf3842962947c62ba40f411e46a58774c60838038f04a67d17626" +dependencies = [ + "four-cc", +] + +[[package]] +name = "mpeg4-audio-const" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a1fe2275b68991faded2c80aa4a33dba398b77d276038b8f50701a22e55918" + +[[package]] +name = "nom" +version = "6.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +dependencies = [ + "bitvec", + "funty", + "lexical-core", + "memchr", + "version_check", +] + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + +[[package]] +name = "object" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bc1d42047cf336f0f939c99e97183cf31551bf0f2865a2ec9c8d91fd4ffb5e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pin-project" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "pretty-hex" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5c99d529f0d30937f6f4b8a86d988047327bb88d04d2c4afc356de74722131" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "retina" +version = "0.0.1" +dependencies = [ + "async-stream", + "base64", + "bitreader", + "bytes", + "digest_auth", + "failure", + "futures", + "h264-reader", + "hex", + "log", + "once_cell", + "pin-project", + "pretty-hex", + "rtcp", + "rtp-rs", + "rtsp-types", + "sdp", + "smallvec", + "time", + "tokio", + "tokio-util", + "url", +] + +[[package]] +name = "retina-fuzz" +version = "0.0.0" +dependencies = [ + "bytes", + "libfuzzer-sys", + "retina", +] + +[[package]] +name = "rfc6381-codec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4395f46a67f0d57c57f6a5361f3a9a0c0183a19cab3998892ecdc003de6d8037" +dependencies = [ + "four-cc", + "mp4ra-rust", + "mpeg4-audio-const", +] + +[[package]] +name = "rtcp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5fb4431b04a948fd91622a75d65a95da3ed2f0be26c902f3d027a23b78fbc96" +dependencies = [ + "bytes", + "thiserror", +] + +[[package]] +name = "rtp-rs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1110d695193d446e901de09921ffbf2d86ae351bbfde9c5b53863ce177e17f5" + +[[package]] +name = "rtsp-types" +version = "0.0.2" +source = "git+https://github.com/sdroege/rtsp-types#53bdf9a74175946572eb3509a6343696724123eb" +dependencies = [ + "cookie-factory", + "nom", + "tinyvec", + "url", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce" + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "sdp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f14aa4ddf1473d50e1664f5c353017981f43f27ede9136a54f60c4bb56d8b152" +dependencies = [ + "rand", + "thiserror", + "url", +] + +[[package]] +name = "sha2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +dependencies = [ + "block-buffer", + "cfg-if", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "slab" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "thiserror" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +dependencies = [ + "libc", + "wasi", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a38d31d7831c6ed7aad00aa4c12d9375fd225a6dd77da1d25b707346319a975" +dependencies = [ + "autocfg", + "libc", + "mio", + "pin-project-lite", + "tokio-macros", +] + +[[package]] +name = "tokio-macros" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-util" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "typenum" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" + +[[package]] +name = "unicode-bidi" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" +dependencies = [ + "matches", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 0000000..d3bf924 --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,27 @@ + +[package] +name = "retina-fuzz" +version = "0.0.0" +authors = ["Automatically generated"] +publish = false +edition = "2018" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +bytes = "1" +libfuzzer-sys = "0.4" + +[dependencies.retina] +path = ".." + +# Prevent this from interfering with workspaces +[workspace] +members = ["."] + +[[bin]] +name = "depacketize_h264" +path = "fuzz_targets/depacketize_h264.rs" +test = false +doc = false diff --git a/fuzz/fuzz_targets/depacketize_h264.rs b/fuzz/fuzz_targets/depacketize_h264.rs new file mode 100644 index 0000000..1c9f8ea --- /dev/null +++ b/fuzz/fuzz_targets/depacketize_h264.rs @@ -0,0 +1,47 @@ +#![no_main] +use bytes::{Buf, Bytes}; +use libfuzzer_sys::fuzz_target; +use std::num::NonZeroU32; + +fuzz_target!(|data: &[u8]| { + let mut data = Bytes::copy_from_slice(data); + let mut depacketizer = retina::codec::Depacketizer::new( + "video", "h264", 90_000, None, Some("packetization-mode=1;profile-level-id=64001E;sprop-parameter-sets=Z2QAHqwsaoLA9puCgIKgAAADACAAAAMD0IAA,aO4xshsA")).unwrap(); + let mut timestamp = retina::Timestamp::new(0, NonZeroU32::new(90_000).unwrap(), 0).unwrap(); + let mut sequence_number: u16 = 0; + let ctx = retina::Context::dummy(); + while data.has_remaining() { + let hdr = data.get_u8(); + let ts_change = (hdr & 0b001) != 0; + let mark = (hdr & 0b010) != 0; + let loss = (hdr & 0b100) != 0; + let len = usize::from(hdr >> 3); + if len > data.remaining() { + return; + } + if loss { + sequence_number = sequence_number.wrapping_add(1); + } + if ts_change { + timestamp = timestamp.try_add(1).unwrap(); + } + let pkt = retina::client::rtp::Packet { + rtsp_ctx: ctx, + stream_id: 0, + timestamp, + sequence_number, + loss: u16::from(loss), + mark, + payload: data.split_off(usize::from(len)), + }; + if depacketizer.push(pkt).is_err() { + return; + } + while let Some(item) = depacketizer.pull().transpose() { + if item.is_err() { + return; + } + } + sequence_number = sequence_number.wrapping_add(1); + } +}); diff --git a/src/codec/h264.rs b/src/codec/h264.rs index 464dbb4..1f69ca8 100644 --- a/src/codec/h264.rs +++ b/src/codec/h264.rs @@ -240,7 +240,7 @@ impl Depacketizer { } } } - 25..=27 | 29 => unimplemented!( + 25..=27 | 29 => bail!( "unimplemented NAL (header 0x{:02x}) at seq {:04x} {:#?}", nal_header, seq, @@ -396,6 +396,9 @@ impl AccessUnit { } fn nal(&mut self, parameters: &mut InternalParameters, nal: Bytes) -> Result<(), Error> { + if !nal.has_remaining() { + bail!("empty NAL"); + } let nal_header = h264_reader::nal::NalHeader::new(nal[0]) .map_err(|e| format_err!("bad NAL header 0x{:x}: {:#?}", nal[0], e))?; let unit_type = nal_header.nal_unit_type(); @@ -578,7 +581,7 @@ impl InternalParameters { frame_rate = vui .timing_info .as_ref() - .map(|t| (2 * t.num_units_in_tick, t.time_scale)); + .and_then(|t| t.num_units_in_tick.checked_mul(2).map(|doubled| (doubled, t.time_scale))); } None => { pixel_aspect_ratio = None; diff --git a/src/codec/mod.rs b/src/codec/mod.rs index 1c42a9c..77810b1 100644 --- a/src/codec/mod.rs +++ b/src/codec/mod.rs @@ -337,9 +337,16 @@ impl bytes::Buf for VideoFrame { } } +/// Turns RTP packets into [CodecItem]s. +/// This interface unstable and for internal use; it's exposed for direct fuzzing. +#[doc(hidden)] +#[derive(Debug)] +pub struct Depacketizer(DepacketizerInner); + + #[derive(Debug)] #[allow(clippy::clippy::large_enum_variant)] -pub(crate) enum Depacketizer { +enum DepacketizerInner { Aac(aac::Depacketizer), SimpleAudio(simple_audio::Depacketizer), G723(g723::Depacketizer), @@ -348,7 +355,7 @@ pub(crate) enum Depacketizer { } impl Depacketizer { - pub(crate) fn new( + pub fn new( media: &str, encoding_name: &str, clock_rate: u32, @@ -359,50 +366,50 @@ impl Depacketizer { // RTP Payload Format Media Types // https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-2 - match (media, encoding_name) { - ("video", "h264") => Ok(Depacketizer::H264(h264::Depacketizer::new( + Ok(Depacketizer(match (media, encoding_name) { + ("video", "h264") => DepacketizerInner::H264(h264::Depacketizer::new( clock_rate, format_specific_params, - )?)), - ("audio", "mpeg4-generic") => Ok(Depacketizer::Aac(aac::Depacketizer::new( + )?), + ("audio", "mpeg4-generic") => DepacketizerInner::Aac(aac::Depacketizer::new( clock_rate, channels, format_specific_params, - )?)), - ("audio", "g726-16") => Ok(Depacketizer::SimpleAudio(simple_audio::Depacketizer::new( + )?), + ("audio", "g726-16") => DepacketizerInner::SimpleAudio(simple_audio::Depacketizer::new( clock_rate, 2, - ))), - ("audio", "g726-24") => Ok(Depacketizer::SimpleAudio(simple_audio::Depacketizer::new( - clock_rate, 3, - ))), - ("audio", "dvi4") | ("audio", "g726-32") => Ok(Depacketizer::SimpleAudio( - simple_audio::Depacketizer::new(clock_rate, 4), )), - ("audio", "g726-40") => Ok(Depacketizer::SimpleAudio(simple_audio::Depacketizer::new( - clock_rate, 5, - ))), - ("audio", "pcma") | ("audio", "pcmu") | ("audio", "u8") | ("audio", "g722") => Ok( - Depacketizer::SimpleAudio(simple_audio::Depacketizer::new(clock_rate, 8)), + ("audio", "g726-24") => DepacketizerInner::SimpleAudio(simple_audio::Depacketizer::new( + clock_rate, 3, + )), + ("audio", "dvi4") | ("audio", "g726-32") => DepacketizerInner::SimpleAudio( + simple_audio::Depacketizer::new(clock_rate, 4), ), - ("audio", "l16") => Ok(Depacketizer::SimpleAudio(simple_audio::Depacketizer::new( + ("audio", "g726-40") => DepacketizerInner::SimpleAudio(simple_audio::Depacketizer::new( + clock_rate, 5, + )), + ("audio", "pcma") | ("audio", "pcmu") | ("audio", "u8") | ("audio", "g722") => ( + DepacketizerInner::SimpleAudio(simple_audio::Depacketizer::new(clock_rate, 8)) + ), + ("audio", "l16") => DepacketizerInner::SimpleAudio(simple_audio::Depacketizer::new( clock_rate, 16, - ))), + )), // Dahua cameras when configured with G723 send packets with a // non-standard encoding-name "G723.1" and length 40, which doesn't // make sense. Don't try to depacketize these. - ("audio", "g723") => Ok(Depacketizer::G723(g723::Depacketizer::new(clock_rate)?)), - ("application", "vnd.onvif.metadata") => Ok(Depacketizer::Onvif( + ("audio", "g723") => DepacketizerInner::G723(g723::Depacketizer::new(clock_rate)?), + ("application", "vnd.onvif.metadata") => DepacketizerInner::Onvif( onvif::Depacketizer::new(CompressionType::Uncompressed), - )), - ("application", "vnd.onvif.metadata.gzip") => Ok(Depacketizer::Onvif( + ), + ("application", "vnd.onvif.metadata.gzip") => DepacketizerInner::Onvif( onvif::Depacketizer::new(CompressionType::GzipCompressed), - )), - ("application", "vnd.onvif.metadata.exi.onvif") => Ok(Depacketizer::Onvif( + ), + ("application", "vnd.onvif.metadata.exi.onvif") => DepacketizerInner::Onvif( onvif::Depacketizer::new(CompressionType::ExiDefault), - )), - ("application", "vnd.onvif.metadata.exi.ext") => Ok(Depacketizer::Onvif( + ), + ("application", "vnd.onvif.metadata.exi.ext") => DepacketizerInner::Onvif( onvif::Depacketizer::new(CompressionType::ExiInBand), - )), + ), (_, _) => { log::info!( "no depacketizer for media/encoding_name {}/{}", @@ -415,36 +422,36 @@ impl Depacketizer { encoding_name ); } + })) + } + + pub fn parameters(&self) -> Option<&Parameters> { + match &self.0 { + DepacketizerInner::Aac(d) => d.parameters(), + DepacketizerInner::G723(d) => d.parameters(), + DepacketizerInner::H264(d) => d.parameters(), + DepacketizerInner::Onvif(d) => d.parameters(), + DepacketizerInner::SimpleAudio(d) => d.parameters(), } } - pub(crate) fn parameters(&self) -> Option<&Parameters> { - match self { - Depacketizer::Aac(d) => d.parameters(), - Depacketizer::G723(d) => d.parameters(), - Depacketizer::H264(d) => d.parameters(), - Depacketizer::Onvif(d) => d.parameters(), - Depacketizer::SimpleAudio(d) => d.parameters(), + pub fn push(&mut self, input: rtp::Packet) -> Result<(), Error> { + match &mut self.0 { + DepacketizerInner::Aac(d) => d.push(input), + DepacketizerInner::G723(d) => d.push(input), + DepacketizerInner::H264(d) => d.push(input), + DepacketizerInner::Onvif(d) => d.push(input), + DepacketizerInner::SimpleAudio(d) => d.push(input), } } - pub(crate) fn push(&mut self, input: rtp::Packet) -> Result<(), Error> { - match self { - Depacketizer::Aac(d) => d.push(input), - Depacketizer::G723(d) => d.push(input), - Depacketizer::H264(d) => d.push(input), - Depacketizer::Onvif(d) => d.push(input), - Depacketizer::SimpleAudio(d) => d.push(input), - } - } - - pub(crate) fn pull(&mut self) -> Result, Error> { - match self { - Depacketizer::Aac(d) => d.pull(), - Depacketizer::G723(d) => d.pull(), - Depacketizer::H264(d) => d.pull(), - Depacketizer::Onvif(d) => d.pull(), - Depacketizer::SimpleAudio(d) => d.pull(), + pub fn pull(&mut self) -> Result, Error> { + match &mut self.0 { + DepacketizerInner::Aac(d) => d.pull(), + DepacketizerInner::G723(d) => d.pull(), + DepacketizerInner::H264(d) => d.pull(), + DepacketizerInner::Onvif(d) => d.pull(), + DepacketizerInner::SimpleAudio(d) => d.pull(), } } } diff --git a/src/lib.rs b/src/lib.rs index ba3c297..c715a7c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,18 @@ pub struct Timestamp { } impl Timestamp { + /// Creates a new timestamp, ensuring `timestamp - start` doesn't underflow. + pub fn new(timestamp: i64, clock_rate: NonZeroU32, start: u32) -> Result { + match timestamp.checked_sub(i64::from(start)) { + None => bail!("timestamp - start must not underflow"), + Some(_) => Ok(Timestamp { + timestamp, + clock_rate, + start, + }) + } + } + /// Returns time since some arbitrary point before the stream started. #[inline] pub fn timestamp(&self) -> i64 { @@ -168,6 +180,21 @@ pub struct Context { } impl Context { + #[doc(hidden)] + pub fn dummy() -> Self { + use std::net::{Ipv4Addr, IpAddr, SocketAddr}; + let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); + Self { + conn_local_addr: addr, + conn_peer_addr: addr, + conn_established_wall: time::get_time(), + conn_established: std::time::Instant::now(), + msg_pos: 0, + msg_received_wall: time::get_time(), + msg_received: std::time::Instant::now(), + } + } + pub fn conn_established(&self) -> std::time::Instant { self.conn_established }