knadh / koanf

Simple, extremely lightweight, extensible, configuration management library for Go. Support for JSON, TOML, YAML, env, command line, file, S3 etc. Alternative to viper.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Bug] Parsing a string from the YAML file with XML/HTML tags

koddr opened this issue · comments

Describe the bug

When parsing a string from the YAML file with XML/HTML tags, there is no reverse decoding when placed in a structure.

To Reproduce

  1. I have this wrapper (nothing special):
func ParseYAMLToStruct[T any](model *T) (*T, error) {
	// Create a new koanf instance and parse the given path to a struct.
	k, err := newKoanfByPath(filepath.Clean(constants.YAMLConfigFileName))
	if err != nil {
		return nil, err
	}

	// Unmarshal structured data to the given struct.
	if err = k.Unmarshal("", &model); err != nil {
		return nil, errors.New(constants.ErrorUnmarshalConfigFileToStructNotComplete)
	}

	return model, nil
}

func newKoanfByPath(path string) (*koanf.Koanf, error) {
	// Create a new koanf provider variable.
	var provider koanf.Provider

	// Create a new koanf instance.
	k := koanf.New(".")

	// Check, if config file ('.gowebly.yml') is existing.
	if IsExistInFolder(path, false) {
		// If exists, set provider to the file.Provider with the given path.
		provider = file.Provider(path)
	} else {
		// Else, read the default config file from the embed.FS.
		defaultConfig, err := attachments.ConfigsFiles.ReadFile("configs/default.yml")
		if err != nil {
			return nil, errors.New(constants.ErrorDefaultYAMLConfigFileNotFound)
		}

		// Set provider to the rawbytes.Provider with a default config file.
		provider = rawbytes.Provider(defaultConfig)
	}

	// Load structured file from the given provider with the koanf's yaml.Parser.
	if err := k.Load(provider, yaml.Parser()); err != nil {
		return nil, errors.New(constants.ErrorYAMLConfigFileNotValid)
	}

	return k, nil
}
  1. YAML config:
icons:
      -
        src: favicons/manifest-touch-icon.svg
        type: 'image/svg+xml'
        sizes: any
  1. Go struct:
type Icon struct {
	Src   string `koanf:"src"`
	Type  string `koanf:"type"`
	Sizes string `koanf:"sizes"`
}
  1. Print Type from struct in your code and see bug.

Expected behavior

When the type value is parsed into the structure via koanf, it becomes image/svg+xml. That is, the + sign changes to the HTML code +.

Please provide the following information):

  • OS: Darwin 22.6.0 Darwin Kernel Version 22.6.0: Fri Sep 15 13:41:30 PDT 2023; root:xnu-8796.141.3.700.8~1/RELEASE_ARM64_T8103 arm64
  • Koanf Version: v2.0.1

Additional context

No.

Hi @koddr
I was trying to reproduce the bug but wasn't able to do so, can you please help me here.

package main

import (
	"fmt"
	"github.com/knadh/koanf/parsers/yaml"
	"github.com/knadh/koanf/providers/file"
	"github.com/knadh/koanf/v2"
	"log"
	"path/filepath"
)

type Icon struct {
	Src   string `koanf:"src"`
	Type  string `koanf:"type"`
	Sizes string `koanf:"sizes"`
}

func main() {
	var k = koanf.New(".")
	if err := k.Load(file.Provider(filepath.Clean("config.yaml")), yaml.Parser()); err != nil {
		log.Fatalf("error loading config: %v", err)
	}
	var model []Icon
	_ = k.Unmarshal("icons", &model)
	fmt.Println("type, src, sizes: ", model[0].Type, model[0].Src, model[0].Sizes)
}

Output of the above code:

% go run main.go 
type, src, sizes:  image/svg+xml favicons/manifest-touch-icon.svg any

The config file is same that you provided and koanf version is also 2.0.1
My go version:

% go version
go version go1.20.2 darwin/arm64