From 3cf932e98d646d8eba3445ccad076e10a2033a14 Mon Sep 17 00:00:00 2001 From: HoneyryderChuck Date: Tue, 29 Oct 2024 14:43:55 +0000 Subject: [PATCH 1/2] config read from file should return frozen data! --- lib/resolv.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/resolv.rb b/lib/resolv.rb index 6cc2756..1653619 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -980,13 +980,13 @@ def Config.parse_resolv_conf(filename) next unless keyword case keyword when 'nameserver' - nameserver.concat(args) + nameserver.concat(args.each(&:freeze)) when 'domain' next if args.empty? - search = [args[0]] + search = [args[0].freeze] when 'search' next if args.empty? - search = args + search = args.each(&:freeze) when 'options' args.each {|arg| case arg @@ -997,22 +997,22 @@ def Config.parse_resolv_conf(filename) end } } - return { :nameserver => nameserver, :search => search, :ndots => ndots } + return { :nameserver => nameserver.freeze, :search => search.freeze, :ndots => ndots.freeze }.freeze end def Config.default_config_hash(filename="/etc/resolv.conf") if File.exist? filename - config_hash = Config.parse_resolv_conf(filename) + Config.parse_resolv_conf(filename) + elsif /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM + require 'win32/resolv' + search, nameserver = Win32::Resolv.get_resolv_info + config_hash = {} + config_hash[:nameserver] = nameserver if nameserver + config_hash[:search] = [search].flatten if search + config_hash else - if /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM - require 'win32/resolv' - search, nameserver = Win32::Resolv.get_resolv_info - config_hash = {} - config_hash[:nameserver] = nameserver if nameserver - config_hash[:search] = [search].flatten if search - end + {} end - config_hash || {} end def lazy_initialize From fc34b8a156513d26ede40b5a6529b1cb6f623aca Mon Sep 17 00:00:00 2001 From: HoneyryderChuck Date: Tue, 29 Oct 2024 17:58:27 +0000 Subject: [PATCH 2/2] refactoring class-hash to be ractor-safe mutable constants can't be shared across ractors; this changes that design to define the required variables as constants on the Resource class, which makes them reachable using ractors; the ClassHash is kept in order not to break integrations relying on its existence, but under the hood it's doing the same thing --- lib/resolv.rb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/resolv.rb b/lib/resolv.rb index 1653619..59ec3dc 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -2107,7 +2107,14 @@ class Resource < Query attr_reader :ttl - ClassHash = {} # :nodoc: + ClassHash = Module.new do + module_function + + def []=(type_class_value, klass) + type_value, class_value = type_class_value + Resource.const_set(:"Type#{type_value}_Class#{class_value}", klass) + end + end def encode_rdata(msg) # :nodoc: raise NotImplementedError.new @@ -2145,7 +2152,9 @@ def hash # :nodoc: end def self.get_class(type_value, class_value) # :nodoc: - return ClassHash[[type_value, class_value]] || + cache = :"Type#{type_value}_Class#{class_value}" + + return (const_defined?(cache) && const_get(cache)) || Generic.create(type_value, class_value) end