Apply quoting yaml values only the string parameters (#19475)

This commit is contained in:
andig 2025-03-06 12:22:37 +01:00 • committed by GitHub
parent 2ec69a9765
commit 659ce11241
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 39 additions and 36 deletions

View file

@ -30,12 +30,12 @@ func (t *Template) RenderDocumentation(product Product, lang string) ([]byte, er
switch p.Type {
case TypeList:
for _, e := range v.([]string) {
t.Params[index].Values = append(p.Values, yamlQuote(e))
t.Params[index].Values = append(p.Values, p.yamlQuote(e))
}
default:
switch v := v.(type) {
case string:
t.Params[index].Value = yamlQuote(v)
t.Params[index].Value = p.yamlQuote(v)
case int:
t.Params[index].Value = strconv.Itoa(v)
}

View file

@ -229,12 +229,12 @@ func (t *Template) RenderProxyWithValues(values map[string]interface{}, lang str
switch p.Type {
case TypeList:
for _, e := range v.([]string) {
t.Params[index].Values = append(p.Values, yamlQuote(e))
t.Params[index].Values = append(p.Values, p.yamlQuote(e))
}
default:
switch v := v.(type) {
case string:
t.Params[index].Value = yamlQuote(v)
t.Params[index].Value = p.yamlQuote(v)
case int:
t.Params[index].Value = strconv.Itoa(v)
}
@ -297,7 +297,8 @@ func (t *Template) RenderResult(renderMode int, other map[string]any) ([]byte, m
for key, val := range values {
out := strings.ToLower(key)
if i, p := t.ParamByName(key); i == -1 {
i, p := t.ParamByName(key)
if i == -1 {
if !slices.Contains(predefinedTemplateProperties, out) {
return nil, values, fmt.Errorf("invalid key: %s", key)
}
@ -313,7 +314,7 @@ func (t *Template) RenderResult(renderMode int, other map[string]any) ([]byte, m
case []interface{}:
var list []string
for _, v := range typed {
list = append(list, yamlQuote(fmt.Sprintf("%v", v)))
list = append(list, p.yamlQuote(fmt.Sprintf("%v", v)))
}
if res[out] == nil || len(res[out].([]interface{})) == 0 {
res[out] = list
@ -322,7 +323,7 @@ func (t *Template) RenderResult(renderMode int, other map[string]any) ([]byte, m
case []string:
var list []string
for _, v := range typed {
list = append(list, yamlQuote(v))
list = append(list, p.yamlQuote(v))
}
if res[out] == nil || len(res[out].([]string)) == 0 {
res[out] = list
@ -333,7 +334,7 @@ func (t *Template) RenderResult(renderMode int, other map[string]any) ([]byte, m
// prevent rendering nil interfaces as "<nil>" string
var s string
if val != nil {
s = yamlQuote(fmt.Sprintf("%v", val))
s = p.yamlQuote(fmt.Sprintf("%v", val))
}
res[out] = s
}

View file

@ -8,6 +8,7 @@ import (
"strings"
"dario.cat/mergo"
"gopkg.in/yaml.v3"
)
const (
@ -243,6 +244,30 @@ func (p *Param) IsAllInOne() bool {
return p.AllInOne != nil && *p.AllInOne
}
// yamlQuote quotes strings for yaml if they would otherwise by modified by the unmarshaler
func (p *Param) yamlQuote(value string) string {
if p.Type != TypeString {
return value
}
input := fmt.Sprintf("key: %s", value)
var res struct {
Value string `yaml:"key"`
}
if err := yaml.Unmarshal([]byte(input), &res); err != nil || value != res.Value {
return quote(value)
}
// fix 0815, but not 0
if strings.HasPrefix(value, "0") && len(value) > 1 {
return quote(value)
}
return value
}
// Product contains naming information about a product a template supports
type Product struct {
Brand string // product brand
@ -257,7 +282,7 @@ type CountryCode string
func (c CountryCode) IsValid() bool {
// ensure ISO 3166-1 alpha-2 format
var validCode = regexp.MustCompile(`^[A-Z]{2}$`)
validCode := regexp.MustCompile(`^[A-Z]{2}$`)
return validCode.MatchString(string(c))
}

View file

@ -8,7 +8,6 @@ import (
"text/template"
"github.com/Masterminds/sprig/v3"
"gopkg.in/yaml.v3"
)
func quote(value string) string {
@ -16,26 +15,6 @@ func quote(value string) string {
return fmt.Sprintf("'%s'", quoted)
}
// yamlQuote quotes strings for yaml if they would otherwise by modified by the unmarshaler
func yamlQuote(value string) string {
input := fmt.Sprintf("key: %s", value)
var res struct {
Value string `yaml:"key"`
}
if err := yaml.Unmarshal([]byte(input), &res); err != nil || value != res.Value {
return quote(value)
}
// fix 0815, but not 0; allow float values containing .
if strings.HasPrefix(value, "0") && len(value) > 1 && !strings.Contains(value, ".") {
return quote(value)
}
return value
}
func trimLines(s string) string {
lines := strings.Split(s, "\n")
for i, line := range lines {

View file

@ -10,9 +10,10 @@ import (
)
func TestYamlDecode(t *testing.T) {
p := Param{Type: TypeString}
for _, value := range []string{`value`, `!value`, `@value`, `"value"`, `"va"lue"`, `va'lue`, `@va'lue`, `0815`, `"0815"`, `4711`, `#pwd`, ``} {
t.Run(value, func(t *testing.T) {
quoted := yamlQuote(value)
quoted := p.yamlQuote(value)
input := fmt.Sprintf("key: %s", quoted)
var res struct {
@ -27,9 +28,6 @@ func TestYamlDecode(t *testing.T) {
}
func TestYamlDecodeLeadingZero(t *testing.T) {
exp := "'0815'"
if res := yamlQuote("0815"); res != exp {
t.Fatalf("expected %s, got %s", exp, res)
}
p := Param{Type: TypeString}
assert.Equal(t, "'0815'", p.yamlQuote("0815"))
}