From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS22989 209.51.188.0/24 X-Spam-Status: No, score=-3.9 required=3.0 tests=AWL,BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 1234C1F852 for ; Thu, 20 Jan 2022 22:03:35 +0000 (UTC) Received: from localhost ([::1]:47142 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nAfWo-0005hi-44 for e@80x24.org; Thu, 20 Jan 2022 17:03:34 -0500 Received: from eggs.gnu.org ([209.51.188.92]:49712) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nAcGy-0003Yd-G4 for dtas-all@nongnu.org; Thu, 20 Jan 2022 13:35:06 -0500 Received: from dcvr.yhbt.net ([64.71.152.64]:47490) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nAcGv-0004og-8k for dtas-all@nongnu.org; Thu, 20 Jan 2022 13:34:59 -0500 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 8A9461FA10 for ; Thu, 20 Jan 2022 18:34:20 +0000 (UTC) From: Eric Wong To: dtas-all@nongnu.org Subject: [PATCH 4/4] use YAML.unsafe_load in Psych 4.x (Ruby 3.1+) Date: Thu, 20 Jan 2022 18:34:19 +0000 Message-Id: <20220120183419.2214-5-e@80x24.org> In-Reply-To: <20220120183419.2214-1-e@80x24.org> References: <20220120183419.2214-1-e@80x24.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=64.71.152.64; envelope-from=e@80x24.org; helo=dcvr.yhbt.net X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: dtas-all@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: duct tape audio suite List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dtas-all-bounces+e=80x24.org@nongnu.org Sender: "dtas-all" Psych 4.x defaults to "nanny mode" to handle untrusted data. This causes breakage with since YAML references (aliases) emitted by dtas-player can't be handled by Psych clients under Ruby 3.1. Since dtas is single user and is a shell designed to run arbitrary code, favor the new YAML.unsafe_load API which behaves like the old YAML.load in Ruby <= 3.0. --- bin/dtas-console | 4 ++-- bin/dtas-msinkctl | 4 ++-- bin/dtas-readahead | 8 ++++---- bin/dtas-sinkedit | 4 ++-- bin/dtas-sourceedit | 4 ++-- bin/dtas-splitfx | 6 +++--- bin/dtas-tl | 4 ++-- lib/dtas.rb | 6 ++++++ lib/dtas/source/splitfx.rb | 4 ++-- lib/dtas/state_file.rb | 4 ++-- test/test_encoding.rb | 4 ++-- test/test_format_change.rb | 4 ++-- test/test_player_client_handler.rb | 4 ++-- test/test_player_integration.rb | 12 ++++++------ test/test_rg_integration.rb | 18 +++++++++--------- test/test_sink.rb | 4 ++-- test/test_splitfx.rb | 2 +- test/test_tfx.rb | 4 ++-- 18 files changed, 53 insertions(+), 47 deletions(-) diff --git a/bin/dtas-console b/bin/dtas-console index e02dda4..a519ba9 100755 --- a/bin/dtas-console +++ b/bin/dtas-console @@ -27,7 +27,7 @@ w = DTAS::UNIXClient.new w.req_ok('watch') c = DTAS::UNIXClient.new -cur = YAML.load(c.req('current')) +cur = DTAS.yaml_load(c.req('current')) readable = [ se, w, $stdin ] set_title = (ENV['DISPLAY'] || ENV['WAYLAND_DISPLAY']) ? $stdout : nil @@ -254,7 +254,7 @@ def may_fail(c, req, events) events << "#{Time.now.strftime(tfmt)} #{event}" # something happened, refresh current # we could be more intelligent here, maybe, but too much work. - cur = YAML.load(c.req('current')) + cur = DTAS.yaml_load(c.req('current')) when $stdin # keybindings taken from mplayer / vi case key = Curses.getch diff --git a/bin/dtas-msinkctl b/bin/dtas-msinkctl index 189738f..6fb3863 100755 --- a/bin/dtas-msinkctl +++ b/bin/dtas-msinkctl @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require 'yaml' @@ -29,7 +29,7 @@ def filter(c, player_sinks, key) rv = [] player_sinks.each do |name| buf = c.req("sink cat #{name}") - sink = YAML.load(buf) + sink = DTAS.yaml_load(buf) rv << sink["name"] if sink[key] end rv diff --git a/bin/dtas-readahead b/bin/dtas-readahead index a1971bd..3f46b95 100755 --- a/bin/dtas-readahead +++ b/bin/dtas-readahead @@ -140,7 +140,7 @@ def do_open(path) when "---\n" buf << fp.read(fp.size - 4) Dir.chdir(File.dirname(path)) do - yml = YAML.load(buf) + yml = DTAS.yaml_load(buf) x = yml['infile'] and return File.open(File.expand_path(x).freeze) end end @@ -155,7 +155,7 @@ def do_open(path) @todo_ra = @max_ra t0 = DTAS.now fp = nil - cur = YAML.load(c.req('current')) + cur = DTAS.yaml_load(c.req('current')) while @todo_ra > 0 && fp.nil? if current = cur['current'] track = current['infile'] @@ -177,7 +177,7 @@ def do_open(path) end # queue has priority, work on it, first - queue = YAML.load(c.req('queue cat')) + queue = DTAS.yaml_load(c.req('queue cat')) while @todo_ra > 0 && track = queue.shift next unless track.kind_of?(String) fp = nil @@ -209,7 +209,7 @@ def do_open(path) end end idx or break - cur = YAML.load(c.req('current')) + cur = DTAS.yaml_load(c.req('current')) current = cur['current'] or break end if current diff --git a/bin/dtas-sinkedit b/bin/dtas-sinkedit index 8f96a97..252270f 100755 --- a/bin/dtas-sinkedit +++ b/bin/dtas-sinkedit @@ -36,10 +36,10 @@ buf = c.req(%W(sink cat #{name})) abort(buf) if buf =~ /\AERR/ -orig = YAML.load(buf) +orig = DTAS.yaml_load(buf) commit_update = lambda do |buf| - sink = YAML.load(buf) + sink = DTAS.yaml_load(buf) cmd = %W(sink ed #{name}) update_cmd_env(cmd, orig, sink) diff --git a/bin/dtas-sourceedit b/bin/dtas-sourceedit index e6603bf..1b3f4ee 100755 --- a/bin/dtas-sourceedit +++ b/bin/dtas-sourceedit @@ -36,10 +36,10 @@ buf = c.req(%W(source cat #{name})) abort(buf) if buf =~ /\AERR/ -orig = YAML.load(buf) +orig = DTAS.yaml_load(buf) commit_update = lambda do |buf| - source = YAML.load(buf) + source = DTAS.yaml_load(buf) cmd = %W(source ed #{name}) update_cmd_env(cmd, orig, source) diff --git a/bin/dtas-splitfx b/bin/dtas-splitfx index 18ea0b4..05e71e5 100755 --- a/bin/dtas-splitfx +++ b/bin/dtas-splitfx @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require 'yaml' @@ -48,7 +48,7 @@ when %r{\A(\w+)=(.*)\z} key, val = $1, $2 # only one that makes sense is infile=another_file - overrides[key] = YAML.load(val) + overrides[key] = DTAS.yaml_load(val) when %r{\A(\w+)\.(\w+)=(.*)\z} # comments.ARTIST='blah' top, key, val = $1, $2, $3 @@ -63,5 +63,5 @@ file = args.shift or abort usage target = args.shift || default_target splitfx = DTAS::SplitFX.new -splitfx.import(YAML.load(File.read(file)), overrides) +splitfx.import(DTAS.yaml_load(File.read(file)), overrides) splitfx.run(target, opts) diff --git a/bin/dtas-tl b/bin/dtas-tl index 988e726..c1af933 100755 --- a/bin/dtas-tl +++ b/bin/dtas-tl @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true # encoding: binary @@ -51,7 +51,7 @@ def do_edit(c) # jump to the line of the currently playing track if using vi or vim # Patches for other editors welcome: dtas-all@nongnu.org if ed =~ /vim?\z/ - cur = YAML.load(c.req('current')) + cur = DTAS.yaml_load(c.req('current')) if tl = cur['tracklist'] if pos = tl['pos'] ed += " +#{pos + 1}" diff --git a/lib/dtas.rb b/lib/dtas.rb index 477a176..cb7c33d 100644 --- a/lib/dtas.rb +++ b/lib/dtas.rb @@ -25,6 +25,12 @@ def self.libc Fiddle.dlopen(nil) end end + + # prevent breakage in Psych 4.x; we're a shell and designed to execute code + def self.yaml_load(buf) + require 'yaml' + YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(buf) : YAML.load(buf) + end # :startdoc: end diff --git a/lib/dtas/source/splitfx.rb b/lib/dtas/source/splitfx.rb index 11e4190..afeb6a3 100644 --- a/lib/dtas/source/splitfx.rb +++ b/lib/dtas/source/splitfx.rb @@ -1,4 +1,4 @@ -# Copyright (C) 2014-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require 'yaml' @@ -36,7 +36,7 @@ def try(ymlfile, offset = nil, trim = nil) sfx = DTAS::SplitFX.new Dir.chdir(File.dirname(ymlfile)) do # ugh - @ymlhash = YAML.load(buf) + @ymlhash = DTAS.yaml_load(buf) @ymlhash['tracks'] ||= [ "t 0 default" ] sfx.import(@ymlhash) sfx.infile.replace(File.expand_path(sfx.infile)) diff --git a/lib/dtas/state_file.rb b/lib/dtas/state_file.rb index eac3e2f..f16a866 100644 --- a/lib/dtas/state_file.rb +++ b/lib/dtas/state_file.rb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require 'yaml' @@ -14,7 +14,7 @@ def initialize(path, do_fsync = false) end def tryload - YAML.load(IO.binread(@path)) if File.readable?(@path) + DTAS.yaml_load(IO.binread(@path)) if File.readable?(@path) end def dump(obj, force_fsync = false) diff --git a/test/test_encoding.rb b/test/test_encoding.rb index 9ef6a25..666d185 100644 --- a/test/test_encoding.rb +++ b/test/test_encoding.rb @@ -1,4 +1,4 @@ -# Copyright (C) 2018-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require './test/helper' @@ -13,7 +13,7 @@ def test_encoding ARTIST: !binary |- RW5yaXF1ZSBSb2Ryw61ndWV6 EOD - hash = YAML.load(data) + hash = DTAS.yaml_load(data) artist = DTAS.try_enc(hash['comments']['ARTIST'], Encoding::UTF_8) assert_equal 'Enrique Rodríguez', artist end diff --git a/test/test_format_change.rb b/test/test_format_change.rb index 95bb860..dc94f02 100644 --- a/test/test_format_change.rb +++ b/test/test_format_change.rb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require './test/player_integration' @@ -26,7 +26,7 @@ def test_format_change Timeout.timeout(len) do begin - cur = YAML.load(s.req("current")) + cur = DTAS.yaml_load(s.req("current")) end while cur["sinks"] && sleep(0.01) end diff --git a/test/test_player_client_handler.rb b/test/test_player_client_handler.rb index 7ea8cc0..eee5e49 100644 --- a/test/test_player_client_handler.rb +++ b/test/test_player_client_handler.rb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require './test/helper' @@ -71,7 +71,7 @@ def test_cat @sinks["default"] = sink dpc_sink(@io, %W(cat default)) assert_equal 1, @io.size - hsh = YAML.load(@io[0]) + hsh = DTAS.yaml_load(@io[0]) assert_kind_of Hash, hsh assert_equal "default", hsh["name"] assert_match("dither -s", hsh["command"]) diff --git a/test/test_player_integration.rb b/test/test_player_integration.rb index e933f7b..5059bd2 100644 --- a/test/test_player_integration.rb +++ b/test/test_player_integration.rb @@ -139,7 +139,7 @@ def test_sink_env Timeout.timeout(5) do begin yaml = s.req("current") - cur = YAML.load(yaml) + cur = DTAS.yaml_load(yaml) end while cur["sinks"] && sleep(0.01) end @@ -166,7 +166,7 @@ def test_enq_head Timeout.timeout(len) do begin yaml = s.req("current") - cur = YAML.load(yaml) + cur = DTAS.yaml_load(yaml) end while cur["sinks"] && sleep(0.01) end assert(system("cmp", dump.path, expect.path), @@ -195,13 +195,13 @@ def test_state_file state.close! s = client_socket s.req_ok(%W(state dump #{state_path})) - hash = YAML.load(IO.binread(state_path)) + hash = DTAS.yaml_load(IO.binread(state_path)) assert_equal @sock_path, hash["socket"] assert_equal "default", hash["sinks"][0]["name"] assert_equal "", IO.binread(@state_tmp.path) s.req_ok(%W(state dump)) - orig = YAML.load(IO.binread(@state_tmp.path)) + orig = DTAS.yaml_load(IO.binread(@state_tmp.path)) assert_equal orig, hash ensure File.unlink(state_path) @@ -216,11 +216,11 @@ def test_source_ed assert_equal "sox av ff splitfx", s.req("source ls") s.req_ok("source ed sox command=true") - sox = YAML.load(s.req("source cat sox")) + sox = DTAS.yaml_load(s.req("source cat sox")) assert_equal "true", sox["command"] s.req_ok("source ed sox command=") - sox = YAML.load(s.req("source cat sox")) + sox = DTAS.yaml_load(s.req("source cat sox")) assert_equal DTAS::Source::Sox::SOX_DEFAULTS["command"], sox["command"] end diff --git a/test/test_rg_integration.rb b/test/test_rg_integration.rb index efa0721..f274272 100644 --- a/test/test_rg_integration.rb +++ b/test/test_rg_integration.rb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require './test/player_integration' @@ -39,7 +39,7 @@ def test_rg_changes_added yaml = cur = nil Timeout.timeout(5) do begin - cur = YAML.load(yaml = s.req("current")) + cur = DTAS.yaml_load(yaml = s.req("current")) end while cur["current_offset"] == 0 && sleep(0.01) end @@ -55,7 +55,7 @@ def test_rg_changes_added Timeout.timeout(5) do begin yaml = s.req("current") - cur = YAML.load(yaml) + cur = DTAS.yaml_load(yaml) end while cur["current"]["env"]["RGFX"] !~ expect && sleep(0.01) end assert_match expect, cur["current"]["env"]["RGFX"] @@ -67,27 +67,27 @@ def test_rg_changes_added check_gain.call(%r{gain 2\.5}, "track_peak") s.req_ok("rg preamp+=1") - rg = YAML.load(yaml = s.req("rg")) + rg = DTAS.yaml_load(yaml = s.req("rg")) assert_equal 1, rg["preamp"] s.req_ok("rg preamp-=1") - rg = YAML.load(yaml = s.req("rg")) + rg = DTAS.yaml_load(yaml = s.req("rg")) assert_nil rg["preamp"] s.req_ok("rg preamp=2") - rg = YAML.load(yaml = s.req("rg")) + rg = DTAS.yaml_load(yaml = s.req("rg")) assert_equal 2, rg["preamp"] s.req_ok("rg preamp-=0.3") - rg = YAML.load(yaml = s.req("rg")) + rg = DTAS.yaml_load(yaml = s.req("rg")) assert_equal 1.7, rg["preamp"] s.req_ok("rg preamp-=-0.3") - rg = YAML.load(yaml = s.req("rg")) + rg = DTAS.yaml_load(yaml = s.req("rg")) assert_equal 2.0, rg["preamp"] s.req_ok("rg preamp-=+0.3") - rg = YAML.load(yaml = s.req("rg")) + rg = DTAS.yaml_load(yaml = s.req("rg")) assert_equal 1.7, rg["preamp"] dethrottle_decoder(s) diff --git a/test/test_sink.rb b/test/test_sink.rb index 873fb3a..7214da6 100644 --- a/test/test_sink.rb +++ b/test/test_sink.rb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require './test/helper' @@ -27,6 +27,6 @@ def test_name def test_inactive_load orig = { "active" => false }.freeze tmp = orig.to_yaml - assert_equal orig, YAML.load(tmp) + assert_equal orig, DTAS.yaml_load(tmp) end end diff --git a/test/test_splitfx.rb b/test/test_splitfx.rb index cacda66..e3bd19d 100644 --- a/test/test_splitfx.rb +++ b/test/test_splitfx.rb @@ -39,7 +39,7 @@ def assert_contains_stats(file) end def test_example - hash = YAML.load(File.read("examples/splitfx.sample.yml")) + hash = DTAS.yaml_load(File.read("examples/splitfx.sample.yml")) sfx = DTAS::SplitFX.new Dir.mktmpdir do |dir| Dir.chdir(dir) do diff --git a/test/test_tfx.rb b/test/test_tfx.rb index fa77ca5..51b1900 100644 --- a/test/test_tfx.rb +++ b/test/test_tfx.rb @@ -1,4 +1,4 @@ -# Copyright (C) 2013-2020 all contributors +# Copyright (C) all contributors # License: GPL-3.0+ # frozen_string_literal: true require './test/helper' @@ -12,7 +12,7 @@ def rate end def test_example - ex = YAML.load(File.read("examples/tfx.sample.yml")) + ex = DTAS.yaml_load(File.read("examples/tfx.sample.yml")) effects = [] ex["effects"].each do |line| words = Shellwords.split(line)