mirror of
https://github.com/goccy/go-yaml.git
synced 2025-11-11 10:41:13 +00:00
Quote YAML 1.1 bools at encoding time for compatibility with other legacy parsers (#354)
This commit is contained in:
parent
11ad39b5c5
commit
f3319d6c80
4 changed files with 56 additions and 6 deletions
|
|
@ -440,7 +440,7 @@ func TestEncoder(t *testing.T) {
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"a:\n y: \"\"\n",
|
"a:\n \"y\": \"\"\n",
|
||||||
struct {
|
struct {
|
||||||
A *struct {
|
A *struct {
|
||||||
X string `yaml:"x,omitempty"`
|
X string `yaml:"x,omitempty"`
|
||||||
|
|
@ -702,7 +702,7 @@ func TestEncodeStructIncludeMap(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%+v", err)
|
t.Fatalf("%+v", err)
|
||||||
}
|
}
|
||||||
expect := "a:\n m:\n x: y\n"
|
expect := "a:\n m:\n x: \"y\"\n"
|
||||||
actual := string(bytes)
|
actual := string(bytes)
|
||||||
if actual != expect {
|
if actual != expect {
|
||||||
t.Fatalf("unexpected output. expect:[%s] actual:[%s]", expect, actual)
|
t.Fatalf("unexpected output. expect:[%s] actual:[%s]", expect, actual)
|
||||||
|
|
@ -720,7 +720,7 @@ func TestEncodeDefinedTypeKeyMap(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("%+v", err)
|
t.Fatalf("%+v", err)
|
||||||
}
|
}
|
||||||
expect := "m:\n x: y\n"
|
expect := "m:\n x: \"y\"\n"
|
||||||
actual := string(bytes)
|
actual := string(bytes)
|
||||||
if actual != expect {
|
if actual != expect {
|
||||||
t.Fatalf("unexpected output. expect:[%s] actual:[%s]", expect, actual)
|
t.Fatalf("unexpected output. expect:[%s] actual:[%s]", expect, actual)
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,28 @@ var (
|
||||||
"False",
|
"False",
|
||||||
"FALSE",
|
"FALSE",
|
||||||
}
|
}
|
||||||
|
// For compatibility with other YAML 1.1 parsers
|
||||||
|
// Note that we use these solely for encoding the bool value with quotes.
|
||||||
|
// go-yaml should not treat these as reserved keywords at parsing time.
|
||||||
|
// as go-yaml is supposed to be compliant only with YAML 1.2.
|
||||||
|
reservedLegacyBoolKeywords = []string{
|
||||||
|
"y",
|
||||||
|
"Y",
|
||||||
|
"yes",
|
||||||
|
"Yes",
|
||||||
|
"YES",
|
||||||
|
"n",
|
||||||
|
"N",
|
||||||
|
"no",
|
||||||
|
"No",
|
||||||
|
"NO",
|
||||||
|
"on",
|
||||||
|
"On",
|
||||||
|
"ON",
|
||||||
|
"off",
|
||||||
|
"Off",
|
||||||
|
"OFF",
|
||||||
|
}
|
||||||
reservedInfKeywords = []string{
|
reservedInfKeywords = []string{
|
||||||
".inf",
|
".inf",
|
||||||
".Inf",
|
".Inf",
|
||||||
|
|
@ -297,6 +319,11 @@ var (
|
||||||
".NAN",
|
".NAN",
|
||||||
}
|
}
|
||||||
reservedKeywordMap = map[string]func(string, string, *Position) *Token{}
|
reservedKeywordMap = map[string]func(string, string, *Position) *Token{}
|
||||||
|
// reservedEncKeywordMap contains is the keyword map used at encoding time.
|
||||||
|
// This is supposed to be a superset of reservedKeywordMap,
|
||||||
|
// and used to quote legacy keywords present in YAML 1.1 or lesser for compatibility reasons,
|
||||||
|
// even though this library is supposed to be YAML 1.2-compliant.
|
||||||
|
reservedEncKeywordMap = map[string]func(string, string, *Position) *Token{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func reservedKeywordToken(typ Type, value, org string, pos *Position) *Token {
|
func reservedKeywordToken(typ Type, value, org string, pos *Position) *Token {
|
||||||
|
|
@ -317,7 +344,14 @@ func init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, keyword := range reservedBoolKeywords {
|
for _, keyword := range reservedBoolKeywords {
|
||||||
reservedKeywordMap[keyword] = func(value, org string, pos *Position) *Token {
|
f := func(value, org string, pos *Position) *Token {
|
||||||
|
return reservedKeywordToken(BoolType, value, org, pos)
|
||||||
|
}
|
||||||
|
reservedKeywordMap[keyword] = f
|
||||||
|
reservedEncKeywordMap[keyword] = f
|
||||||
|
}
|
||||||
|
for _, keyword := range reservedLegacyBoolKeywords {
|
||||||
|
reservedEncKeywordMap[keyword] = func(value, org string, pos *Position) *Token {
|
||||||
return reservedKeywordToken(BoolType, value, org, pos)
|
return reservedKeywordToken(BoolType, value, org, pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -581,7 +615,7 @@ func IsNeedQuoted(value string) bool {
|
||||||
if value == "" {
|
if value == "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if _, exists := reservedKeywordMap[value]; exists {
|
if _, exists := reservedEncKeywordMap[value]; exists {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if stat := getNumberStat(value); stat.isNum {
|
if stat := getNumberStat(value); stat.isNum {
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,22 @@ func TestIsNeedQuoted(t *testing.T) {
|
||||||
`"a b`,
|
`"a b`,
|
||||||
"a:",
|
"a:",
|
||||||
"a: b",
|
"a: b",
|
||||||
|
"y",
|
||||||
|
"Y",
|
||||||
|
"yes",
|
||||||
|
"Yes",
|
||||||
|
"YES",
|
||||||
|
"n",
|
||||||
|
"N",
|
||||||
|
"no",
|
||||||
|
"No",
|
||||||
|
"NO",
|
||||||
|
"on",
|
||||||
|
"On",
|
||||||
|
"ON",
|
||||||
|
"off",
|
||||||
|
"Off",
|
||||||
|
"OFF",
|
||||||
}
|
}
|
||||||
for i, test := range needQuotedTests {
|
for i, test := range needQuotedTests {
|
||||||
if !token.IsNeedQuoted(test) {
|
if !token.IsNeedQuoted(test) {
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ a:
|
||||||
b: hello
|
b: hello
|
||||||
c: true
|
c: true
|
||||||
d:
|
d:
|
||||||
x: y
|
x: "y"
|
||||||
b:
|
b:
|
||||||
a: 2
|
a: 2
|
||||||
b: world
|
b: world
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue