Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot unmarshal struct when key is not English #413

Closed
artemklevtsov opened this issue Nov 30, 2022 · 1 comment · Fixed by #432
Closed

Cannot unmarshal struct when key is not English #413

artemklevtsov opened this issue Nov 30, 2022 · 1 comment · Fixed by #432
Labels
bug Something isn't working

Comments

@artemklevtsov
Copy link

artemklevtsov commented Nov 30, 2022

Seems realted with #234.

package main

import (
	"fmt"

	"encoding/json"

	gjson "github.com/goccy/go-json"
)

type MyType struct {
	Msg string `json:"Сообщение"`
}

func main() {
	b := []byte(`{"Сообщение":"Текст"}`)

	var expected MyType
	json.Unmarshal(b, &expected)
	fmt.Printf("got json object: %+v\n", expected)

	var actual MyType
	gjson.Unmarshal(b, &actual)
	fmt.Printf("got gjson object: %+v\n", actual)
}

Exptected

got json object: {Msg:Текст}
got gjson object: {Msg:Текст}

Actual

got json object: {Msg:Текст}
got gjson object: {Msg:}
go version go1.19.3 linux/amd64
github.com/goccy/go-json v0.10.0
@artemklevtsov artemklevtsov changed the title Cannot unmarshal struct when key is Cannot unmarshal struct when key is not English Nov 30, 2022
@goccy goccy added the bug Something isn't working label Dec 1, 2022
@orisano
Copy link
Contributor

orisano commented Feb 24, 2023

The root cause of this issue is that the tag name is strings.ToLower for case insensitive lookup of field names in the structure, but the decoding process only looks up from the largeToSmallTable and does not consider the locale.

https://go.dev/play/p/xRsK6qvU3XJ

Code:

var (
	largeToSmallTable [256]byte
)

func init() {
	for i := 0; i < 256; i++ {
		c := i
		if 'A' <= c && c <= 'Z' {
			c += 'a' - 'A'
		}
		largeToSmallTable[i] = byte(c)
	}
}

func toLower(s string) string {
	var b []byte
	for _, c := range []byte(s) {
		b = append(b, largeToSmallTable[c])
	}
	return string(b)
}

func main() {
	s := "Сообщение"
	fmt.Println(toLower(s))
	fmt.Println(strings.ToLower(s))
}

Output:

Сообщение
сообщение

@goccy How do we correct the problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants