From 71b47b51f72b68a486ff02c5c3f5f9d75794cc5f Mon Sep 17 00:00:00 2001 From: Tristan Colgate Date: Thu, 12 Mar 2020 15:02:23 +0000 Subject: [PATCH 1/2] Add tests for marshaling string fields with "bool" values --- encode_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/encode_test.go b/encode_test.go index 0f01b76f..3f32393d 100644 --- a/encode_test.go +++ b/encode_test.go @@ -176,6 +176,12 @@ var marshalTests = []struct { }, { &struct{ A bool }{true}, "a: true\n", + }, { + &struct{ A string }{"true"}, + "a: \"true\"\n", + }, { + &struct{ A string }{"off"}, + "a: \"off\"\n", }, // Conditional flag From fc2885c7fe595c1fc1fac1e88d447bb591201d5b Mon Sep 17 00:00:00 2001 From: Tristan Colgate Date: Fri, 13 Mar 2020 08:55:14 +0000 Subject: [PATCH 2/2] Marshal YAML 1.2 bool-like strings to quoted strings. We adhere to the YAML 1.3 for input, but only parsing "On", "Off", and friends, as strings rather than bools. When outputting however we will ensure that we quote these cases. Failure to do so forces makes the output ambiguous if it then to be parsed by a YAML 1.2 parser. --- encode.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/encode.go b/encode.go index eee3667e..1f37271c 100644 --- a/encode.go +++ b/encode.go @@ -298,6 +298,21 @@ func isBase60Float(s string) (result bool) { // is bogus. In practice parsers do not enforce the "\.[0-9_]*" suffix. var base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\.[0-9_]*)?$`) +// isOldBool returns whether s is bool notation as defined in YAML 1.1. +// +// We continue to force strings that YAML 1.1 would interpret as booleans to be +// rendered as quotes strings so that the marshalled output valid for YAML 1.1 +// parsing. +func isOldBool(s string) (result bool) { + switch s { + case "y", "Y", "yes", "Yes", "YES", "on", "On", "ON", + "n", "N", "no", "No", "NO", "off", "Off", "OFF": + return true + default: + return false + } +} + func (e *encoder) stringv(tag string, in reflect.Value) { var style yaml_scalar_style_t s := in.String() @@ -319,7 +334,7 @@ func (e *encoder) stringv(tag string, in reflect.Value) { // tag when encoded unquoted. If it doesn't, // there's no need to quote it. rtag, _ := resolve("", s) - canUsePlain = rtag == strTag && !isBase60Float(s) + canUsePlain = rtag == strTag && !(isBase60Float(s) || isOldBool(s)) } // Note: it's possible for user code to emit invalid YAML // if they explicitly specify a tag and a string containing