paerser icon indicating copy to clipboard operation
paerser copied to clipboard

paerser reads boolean or number YAML values as strings

Open motoki317 opened this issue 6 months ago • 1 comments

Description

paerser v0.2.2 seems to decode boolean values in YAML as strings.

Reproduction

https://github.com/motoki317/traefik-paerser-bool-repro

package main

import (
	"fmt"

	"github.com/google/go-cmp/cmp"
	pfile "github.com/traefik/paerser/file"
	"gopkg.in/yaml.v3"
)

const yamlContents = `
value: true
`

func main() {
	var v1, v2 map[string]any

	err := yaml.Unmarshal([]byte(yamlContents), &v1)
	if err != nil {
		panic(err)
	}

	err = pfile.DecodeContent(yamlContents, ".yaml", &v2)
	if err != nil {
		panic(err)
	}

	fmt.Printf("diff: %v\n", cmp.Diff(v1, v2))
}

output:

diff:   map[string]any{
-       "value": bool(true),
+       "value": string("true"),
  }

Additional Context

I found this when developing WASM plugin in traefik. When piceus discovers and validates plugin, it exited with an error that the "module closed with exit_code(1)".

The issue was that piceus was decoding testData in .traefik.yml with paerser and then encoding it into JSON, and paerser read this line as string (which is commented out for now): https://github.com/motoki317/traefik-headers-wasm/blob/9a61c07def393a285e6a10cf23ec8f4d66e6e93e/.traefik.yml#L13 And then my plugin was exiting with decode error: https://github.com/motoki317/traefik-headers-wasm/blob/9a61c07def393a285e6a10cf23ec8f4d66e6e93e/main.go#L141

It seems piceus is using paerser v0.2.0, but this also happens on the latest paerser v0.2.2, as reproducible in the above code and repo.

motoki317 avatar Jul 28 '25 01:07 motoki317

This also happens with numbers:

package main

import (
	"fmt"

	"github.com/google/go-cmp/cmp"
	pfile "github.com/traefik/paerser/file"
	"gopkg.in/yaml.v3"
)

const yamlContents = `
value: 1
`

func main() {
	var v1, v2 map[string]any

	err := yaml.Unmarshal([]byte(yamlContents), &v1)
	if err != nil {
		panic(err)
	}

	err = pfile.DecodeContent(yamlContents, ".yaml", &v2)
	if err != nil {
		panic(err)
	}

	fmt.Printf("diff: %v\n", cmp.Diff(v1, v2))
}

output:

diff:   map[string]any{
- 	"value": int(1),
+ 	"value": string("1"),
  }

And if I set value: 1.5, output becomes:

diff:   map[string]any{
- 	"value": float64(1.5),
+ 	"value": string("1.500000"),
  }

Interestingly, setting value: null yields this diff:

diff:   map[string]any(
- 	{"value": nil},
+ 	nil,
  )

motoki317 avatar Jul 30 '25 04:07 motoki317