pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/multimedia/mpv mpv: Add patch-player_lua_ytdl__hook.lu...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/1fa8ea39d8c9
branches:  trunk
changeset: 374816:1fa8ea39d8c9
user:      leot <leot%pkgsrc.org@localhost>
date:      Mon Jan 29 21:54:22 2018 +0000

description:
mpv: Add patch-player_lua_ytdl__hook.lua to address CVE-2018-6360

Sync player/lua/ytdl_hook.lua with upstream commit
2a0f9fc1588d8bda51a6340197c54285f3f62755 minus hunks that need `on_load_fail'
hook introduced after mpv-0.27.

Bump PKGREVISION.

diffstat:

 multimedia/mpv/Makefile                                |    4 +-
 multimedia/mpv/distinfo                                |    3 +-
 multimedia/mpv/patches/patch-player_lua_ytdl__hook.lua |  265 +++++++++++++++++
 3 files changed, 269 insertions(+), 3 deletions(-)

diffs (296 lines):

diff -r 7daf0e8d6cfd -r 1fa8ea39d8c9 multimedia/mpv/Makefile
--- a/multimedia/mpv/Makefile   Mon Jan 29 21:38:20 2018 +0000
+++ b/multimedia/mpv/Makefile   Mon Jan 29 21:54:22 2018 +0000
@@ -1,7 +1,7 @@
-# $NetBSD: Makefile,v 1.62 2018/01/28 20:10:57 wiz Exp $
+# $NetBSD: Makefile,v 1.63 2018/01/29 21:54:22 leot Exp $
 
 DISTNAME=      mpv-0.27.0
-PKGREVISION=   1
+PKGREVISION=   2
 CATEGORIES=    multimedia
 MASTER_SITES=  ${MASTER_SITE_GITHUB:=mpv-player/}
 GITHUB_TAG=    v${PKGVERSION_NOREV}
diff -r 7daf0e8d6cfd -r 1fa8ea39d8c9 multimedia/mpv/distinfo
--- a/multimedia/mpv/distinfo   Mon Jan 29 21:38:20 2018 +0000
+++ b/multimedia/mpv/distinfo   Mon Jan 29 21:54:22 2018 +0000
@@ -1,8 +1,9 @@
-$NetBSD: distinfo,v 1.37 2017/09/13 10:35:58 leot Exp $
+$NetBSD: distinfo,v 1.38 2018/01/29 21:54:22 leot Exp $
 
 SHA1 (mpv-0.27.0.tar.gz) = d4bddb88cf7a112a295a130a091181acbe25605b
 RMD160 (mpv-0.27.0.tar.gz) = d2edbdfdc6fdf3a0c210536ac3966e99113c83ad
 SHA512 (mpv-0.27.0.tar.gz) = 22738f907d84d362095773972f685e3b03ab4c8172a22ddede290fc221a83ab9135b96f8b18191dabe842b2963f68983929cf065097287fc1a054a7d5f1d0ae4
 Size (mpv-0.27.0.tar.gz) = 2956816 bytes
 SHA1 (patch-audio_out_ao__oss.c) = d7f3a75ab43efe396ce536fb54e6207a7ded3510
+SHA1 (patch-player_lua_ytdl__hook.lua) = 450a6f2640c76b5db0c0cd585674ccd689712f78
 SHA1 (patch-player_main.c) = 842432e448526a9d170e7efd2b01276e36072e16
diff -r 7daf0e8d6cfd -r 1fa8ea39d8c9 multimedia/mpv/patches/patch-player_lua_ytdl__hook.lua
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/multimedia/mpv/patches/patch-player_lua_ytdl__hook.lua    Mon Jan 29 21:54:22 2018 +0000
@@ -0,0 +1,265 @@
+$NetBSD: patch-player_lua_ytdl__hook.lua,v 1.1 2018/01/29 21:54:22 leot Exp $
+
+Sync ytdl_hook.lua script with commit 2a0f9fc1588d8bda51a6340197c54285f3f62755
+in order to fix CVE-2018-6360.
+
+Please note that this completely omits hunks that need `on_load_fail' hook that
+was implemented post-0.27.
+
+--- player/lua/ytdl_hook.lua.orig      2018-01-28 10:58:02.151884824 +0000
++++ player/lua/ytdl_hook.lua
+@@ -15,6 +16,18 @@ local ytdl = {
+ 
+ local chapter_list = {}
+ 
++function Set (t)
++    local set = {}
++    for _, v in pairs(t) do set[v] = true end
++    return set
++end
++
++local safe_protos = Set {
++    "http", "https", "ftp", "ftps",
++    "rtmp", "rtmps", "rtmpe", "rtmpt", "rtmpts", "rtmpte",
++    "data"
++}
++
+ local function exec(args)
+     local ret = utils.subprocess({args = args})
+     return ret.status, ret.stdout, ret
+@@ -71,6 +84,15 @@ local function edl_escape(url)
+     return "%" .. string.len(url) .. "%" .. url
+ end
+ 
++local function url_is_safe(url)
++    local proto = type(url) == "string" and url:match("^(.+)://") or nil
++    local safe = proto and safe_protos[proto]
++    if not safe then
++        msg.error(("Ignoring potentially unsafe url: '%s'"):format(url))
++    end
++    return safe
++end
++
+ local function time_to_secs(time_string)
+     local ret
+ 
+@@ -182,6 +204,9 @@ local function edl_track_joined(fragment
+ 
+     for i = offset, #fragments do
+         local fragment = fragments[i]
++        if not url_is_safe(join_url(base, fragment)) then
++            return nil
++        end
+         table.insert(parts, edl_escape(join_url(base, fragment)))
+         if fragment.duration then
+             parts[#parts] =
+@@ -191,16 +216,63 @@ local function edl_track_joined(fragment
+     return edl .. table.concat(parts, ";") .. ";"
+ end
+ 
++local function has_native_dash_demuxer()
++    local demuxers = mp.get_property_native("demuxer-lavf-list")
++    for _,v in ipairs(demuxers) do
++        if v == "dash" then
++            return true
++        end
++    end
++    return false
++end
++
++local function valid_manifest(json)
++    local reqfmt = json["requested_formats"] and json["requested_formats"][1] or {}
++    if not reqfmt["manifest_url"] and not json["manifest_url"] then
++        return false
++    end
++    local proto = reqfmt["protocol"] or json["protocol"] or ""
++    return (has_native_dash_demuxer() and proto == "http_dash_segments") or
++        proto:find("^m3u8")
++end
++
+ local function add_single_video(json)
+     local streamurl = ""
++    local max_bitrate = 0
++    local reqfmts = json["requested_formats"]
++
++    -- prefer manifest_url if present
++    if valid_manifest(json) then
++        local mpd_url = reqfmts and reqfmts[1]["manifest_url"] or
++            json["manifest_url"]
++        if not mpd_url then
++            msg.error("No manifest URL found in JSON data.")
++            return
++        elseif not url_is_safe(mpd_url) then
++            return
++        end
++
++        streamurl = mpd_url
++
++        if reqfmts then
++            for _, track in pairs(reqfmts) do
++                max_bitrate = track.tbr > max_bitrate and
++                    track.tbr or max_bitrate
++            end
++        elseif json.tbr then
++            max_bitrate = json.tbr > max_bitrate and json.tbr or max_bitrate
++        end
+ 
+     -- DASH/split tracks
+-    if not (json["requested_formats"] == nil) then
+-        for _, track in pairs(json.requested_formats) do
++    elseif reqfmts then
++        for _, track in pairs(reqfmts) do
+             local edl_track = nil
+             edl_track = edl_track_joined(track.fragments,
+                 track.protocol, json.is_live,
+                 track.fragment_base_url)
++            if not edl_track and not url_is_safe(track.url) then
++                return
++            end
+             if track.acodec and track.acodec ~= "none" then
+                 -- audio track
+                 mp.commandv("audio-add",
+@@ -217,6 +289,9 @@ local function add_single_video(json)
+         edl_track = edl_track_joined(json.fragments, json.protocol,
+             json.is_live, json.fragment_base_url)
+ 
++        if not edl_track and not url_is_safe(json.url) then
++            return
++        end
+         -- normal video or single track
+         streamurl = edl_track or json.url
+         set_http_headers(json.http_headers)
+@@ -231,6 +306,13 @@ local function add_single_video(json)
+ 
+     mp.set_property("file-local-options/force-media-title", json.title)
+ 
++    -- set hls-bitrate for dash track selection
++    if max_bitrate > 0 and
++        not option_was_set("hls-bitrate") and
++        not option_was_set_locally("hls-bitrate") then
++        mp.set_property_native('file-local-options/hls-bitrate', max_bitrate*1000)
++    end
++
+     -- add subtitles
+     if not (json.requested_subtitles == nil) then
+         for lang, sub_info in pairs(json.requested_subtitles) do
+@@ -309,7 +391,8 @@ mp.add_hook("on_load", 10, function ()
+ 
+         -- check for youtube-dl in mpv's config dir
+         if not (ytdl.searched) then
+-            local ytdl_mcd = mp.find_config_file("youtube-dl")
++            local exesuf = (package.config:sub(1,1) == '\\') and '.exe' or ''
++            local ytdl_mcd = mp.find_config_file("youtube-dl" .. exesuf)
+             if not (ytdl_mcd == nil) then
+                 msg.verbose("found youtube-dl at: " .. ytdl_mcd)
+                 ytdl.path = ytdl_mcd
+@@ -365,9 +448,15 @@ mp.add_hook("on_load", 10, function ()
+         local es, json, result = exec(command)
+ 
+         if (es < 0) or (json == nil) or (json == "") then
+-            if not result.killed_by_us then
+-                msg.warn("youtube-dl failed, trying to play URL directly ...")
++            local err = "youtube-dl failed: "
++            if result.error and result.error == "init" then
++                err = err .. "not found or not enough permissions"
++            elseif not result.killed_by_us then
++                err = err .. "unexpected error ocurred"
++            else
++                err = string.format("%s returned '%d'", err, es)
+             end
++            msg.error(err)
+             return
+         end
+ 
+@@ -396,18 +485,26 @@ mp.add_hook("on_load", 10, function ()
+                 return
+             end
+ 
++            local self_redirecting_url =
++                json.entries[1]["_type"] ~= "url_transparent" and
++                json.entries[1]["webpage_url"] and
++                json.entries[1]["webpage_url"] == json["webpage_url"]
++
+ 
+             -- some funky guessing to detect multi-arc videos
+-            if (not (json.entries[1]["_type"] == "url_transparent")) and
+-                (not (json.entries[1]["webpage_url"] == nil)
+-                and (json.entries[1]["webpage_url"] == json["webpage_url"]))
+-                and not (json.entries[1].url == nil) then
++            if self_redirecting_url and #json.entries > 1
++                and json.entries[1].protocol == "m3u8_native"
++                and json.entries[1].url then
+                 msg.verbose("multi-arc video detected, building EDL")
+ 
+                 local playlist = edl_track_joined(json.entries)
+ 
+                 msg.debug("EDL: " .. playlist)
+ 
++                if not playlist then
++                    return
++                end
++
+                 -- can't change the http headers for each entry, so use the 1st
+                 if json.entries[1] then
+                     set_http_headers(json.entries[1].http_headers)
+@@ -446,39 +543,43 @@ mp.add_hook("on_load", 10, function ()
+                     end
+                 end
+ 
+-            elseif (not (json.entries[1]["_type"] == "url_transparent")) and
+-                (not (json.entries[1]["webpage_url"] == nil)
+-                and (json.entries[1]["webpage_url"] == json["webpage_url"]))
+-                and (#json.entries == 1) then
+-
++            elseif self_redirecting_url and #json.entries == 1 then
+                 msg.verbose("Playlist with single entry detected.")
+                 add_single_video(json.entries[1])
+             else
+-
+-                local playlist = "#EXTM3U\n"
++                local playlist = {"#EXTM3U"}
+                 for i, entry in pairs(json.entries) do
+                     local site = entry.url
+                     local title = entry.title
+ 
+                     if not (title == nil) then
+                         title = string.gsub(title, '%s+', ' ')
+-                        playlist = playlist .. "#EXTINF:0," .. title .. "\n"
++                        table.insert(playlist, "#EXTINF:0," .. title)
+                     end
+ 
+-                    -- some extractors will still return the full info for
+-                    -- all clips in the playlist and the URL will point
+-                    -- directly to the file in that case, which we don't
+-                    -- want so get the webpage URL instead, which is what
+-                    -- we want
+-                    if not (json.entries[1]["_type"] == "url_transparent")
+-                        and not (entry["webpage_url"] == nil) then
++                    --[[ some extractors will still return the full info for
++                         all clips in the playlist and the URL will point
++                         directly to the file in that case, which we don't
++                         want so get the webpage URL instead, which is what
++                         we want, but only if we aren't going to trigger an
++                         infinite loop
++                    --]]
++                    if entry["webpage_url"] and not self_redirecting_url then
+                         site = entry["webpage_url"]
+                     end
+ 
+-                    playlist = playlist .. "ytdl://" .. site .. "\n"
++                    -- links with only youtube id as returned by --flat-playlist
++                    if not site:find("://") then
++                        table.insert(playlist, "ytdl://" .. site)
++                    elseif url_is_safe(site) then
++                        table.insert(playlist, site)
++                    end
++
+                 end
+ 
+-                mp.set_property("stream-open-filename", "memory://" .. playlist)
++                if #playlist > 0 then
++                    mp.set_property("stream-open-filename", "memory://" .. table.concat(playlist, "\n"))
++                end
+             end
+ 
+         else -- probably a video



Home | Main Index | Thread Index | Old Index