From 4e225df5edb13eeefef2ca4c94e4d26b3a3b22bc Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Wed, 1 Jul 2026 07:00:30 +0900 Subject: [PATCH] [ruby/psych] Resolve booleans per YAML 1.2 on the libfyaml backend Scalar type resolution happens in ScalarScanner, not the C backend, so swapping to libfyaml alone still resolved yes/no/on/off to booleans. Key the boolean set on Psych::BACKEND so the libyaml default keeps the YAML 1.1 set while the experimental libfyaml backend follows 1.2. https://github.com/ruby/psych/commit/b374869c59 Co-Authored-By: Claude Opus 4.8 --- ext/psych/lib/psych/scalar_scanner.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ext/psych/lib/psych/scalar_scanner.rb b/ext/psych/lib/psych/scalar_scanner.rb index d744e61183..68e17ecf5f 100644 --- a/ext/psych/lib/psych/scalar_scanner.rb +++ b/ext/psych/lib/psych/scalar_scanner.rb @@ -24,6 +24,18 @@ module Psych |[-+]?(?:0|[1-9](?:[0-9]|,[0-9]|_[0-9])*) (?# base 10) |[-+]?0x[_,]*[0-9a-fA-F][0-9a-fA-F_,]* (?# base 16))$/x + # YAML 1.1 treats yes/no/on/off as booleans in addition to true/false, + # while YAML 1.2's core schema only recognizes true/false. The default + # libyaml backend keeps the 1.1 set for backward compatibility; the + # experimental libfyaml backend follows 1.2. + if defined?(Psych::BACKEND) && Psych::BACKEND == 'libfyaml' + BOOLEAN_TRUE = /^true$/i + BOOLEAN_FALSE = /^false$/i + else + BOOLEAN_TRUE = /^(yes|true|on)$/i + BOOLEAN_FALSE = /^(no|false|off)$/i + end + attr_reader :class_loader # Create a new scanner @@ -48,9 +60,9 @@ module Psych string elsif string == '~' || string.match?(/^null$/i) nil - elsif string.match?(/^(yes|true|on)$/i) + elsif string.match?(BOOLEAN_TRUE) true - elsif string.match?(/^(no|false|off)$/i) + elsif string.match?(BOOLEAN_FALSE) false else string