Skip to content

JSON Unmarshal of some Unicode escape sequence results in error #1576

Open
@denis-zyk

Description

@denis-zyk

What version of protobuf and what language are you using?

protoc --version
libprotoc 23.4

protoc-gen-go --version
protoc-gen-go v1.31.0

Golang lib:

google.golang.org/protobuf v1.30.0

What did you do?
Steps to reproduce the behavior:

  1. Have a JSON string containing the following Unicode escape sequence \udca0, e.g. {"name":"'unsafe-eval'; object?src\udca0'none'"}.
  2. Unmarshal byte slice of JSON string in question to protobuf message using google.golang.org/protobuf/encoding/protojson package.
  3. Got error proto: syntax error (line 1:9): invalid escape code "'none'" in string.

Code snippet for reproducing issue:

package main

import (
	"encoding/json"
	"fmt"
	"google.golang.org/protobuf/encoding/protojson"
	
	"pkg.my.package/microservices/models"
)

func main() {
	j1 := []byte(`{"name":"'unsafe-eval'; object?src\uc2a0'none'"}`)	# unmarshal is OK
	j2 := []byte(`{"name":"'unsafe-eval'; object?src\udca0'none'"}`)	# unmarshal error in protojson

	// protojson lib

	// models.Client is a golang struct compiled using `protoc` binary, from Client protobuf message.
	// Protobuf message for the sake of reproducing has 1 string field:
	//   Name       string       `protobuf:"bytes,1,opt,name=name,proto3" json:"name"`
	outProto1 := &models.Client{}
	outProto2 := &models.Client{}

	unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true}

	err1 := unmarshaler.Unmarshal(j1, outProto1)
	err2 := unmarshaler.Unmarshal(j2, outProto2)

	fmt.Println("protojson lib")
	fmt.Println(string(j1), err1, outProto1)
	fmt.Println(string(j2), err2, outProto2)

	// core lib
	outCore1 := make(map[string]interface{})
	outCore2 := make(map[string]interface{})

	err1 = json.Unmarshal(j1, &outCore1)
	err2 = json.Unmarshal(j2, &outCore2)

	fmt.Println("core lib")
	fmt.Println(string(j1), err1, outCore1)
	fmt.Println(string(j2), err2, outCore2)
}

The example code snippet above produces the following output:

protojson lib
{"name":"'unsafe-eval'; object?src\uc2a0'none'"} <nil> name:"'unsafe-eval'; object?src슠'none'"
{"name":"'unsafe-eval'; object?src\udca0'none'"} proto: syntax error (line 1:9): invalid escape code "'none'" in string 
core lib
{"name":"'unsafe-eval'; object?src\uc2a0'none'"} <nil> map[name:'unsafe-eval'; object?src슠'none']
{"name":"'unsafe-eval'; object?src\udca0'none'"} <nil> map[name:'unsafe-eval'; object?src�'none']

What did you expect to see?
Unmarshalled value name:"'unsafe-eval'; object?src�'none'". I.e. same unmarshalled string value as in Golang core JSON lib.

What did you see instead?
Unpopulated message and an error proto: syntax error (line 1:9): invalid escape code "'none'" in string.

Anything else we should know about your project / environment?
Reproduced & confirmed using the followed golang versions and environments:

Linux: go version go1.20.11 linux/amd64
macOS: go version go1.21.4 darwin/arm64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions